【PHP】ファイル名や絶対パスの取得方法!パスは汎用性の高いコードを記述しよう

この記事からわかること
- phpのコードでファイル名を取得する方法
- ホスト名や絶対パス(URL)、ディレクトリなども合わせて解説
- 「マジック定数__FILE__」と「$_SERVER['PHP_SELF']」の違い
index
[open]
\ アプリをリリースしました /
phpでheader関数やinclude、画像のパスなど絶対パスやファイル名、ホスト名などを取得したいときに汎用性が高く使いまわせるコードを解説していきます。
ファイル名を取得する
実行しているファイル名を取得できるのは「basename関数」の役割です。
basename関数は指定されたパスの最後の名称部分を返します。
basename(string $path, string $suffix = "")
$path = ファイルのパス(定数__FILE__や"/article/dir/file.php"のようにパスベタがきでもOK)
$suffix = カットしたい文字(末尾にある場合のみ)⇨拡張子が消せる
basename関数の使い方
使い方は引数にパスを入れ込むだけです。第2引数に拡張子を設定することで末尾が指定した文字列の場合自動で削除してくれます。
// パスが"/article/dir/file.php"の場合...
echo basename(__FILE__); // 結果:file.php
echo basename(__FILE__,".php"); // 結果:file
echo basename("/article/dir/file.php"); // 結果:file.php
echo basename("/article/dir/file.php",".php"); // 結果:file
echo basename("/article/dir/"); // 結果:dir
パスは「"/article/dir/file.php"」のように直接入力しても良いですが、マジック定数の「__FILE__」やスーパーグローバル変数の$_SERVER['PHP_SELF']などを使えば汎用性が高まります。
状況にもよりますがパス名は変わることがあるのでコードで取得できるものはコードで記述しておく方が無難です。
dirname関数の使い方
dirname関数も使い方はbasename関数と変わりません。違いとしては取得できるのがパス名ではなくディレクトリ名になっていることです。
dirname(string $path, int $levels = 1)
$path = ファイルのパス(定数__FILE__や"/article/dir/file.php"のようにパスベタがきでもOK)
$levels = さかのぼって表示したいディレクトリの数を整数で指定
ローカル環境(MAMP)で使用するとこのような感じになります。
echo dirname(__FILE__); // 結果:/Applications/MAMP/htdocs/article/dir
echo dirname(__FILE__,3); // 結果:/Applications/MAMP/htdocs
echo dirname("/article/dir/file.php"); // 結果:/article/dir
echo dirname("/article/dir/file.php",2); // 結果:/article
echo dirname("/article/dir/"); // 結果:/article
「マジック定数__FILE__」と「$_SERVER['PHP_SELF']」の違い
ここで「マジック定数__FILE__」と「$_SERVER['PHP_SELF']」の違いをみておきましょう。
マジック定数とは「使われる場所によって結果が異なる定数のこと」です。
$_SERVERはスーパーグローバル変数の1つでサーバーに関する情報を取得することができます。
例えばローカル環境(MAMP)で両者を記述してみたときはどうなるでしょうか。
echo __FILE__;
// 結果:/Applications/MAMP/htdocs/article/dir/file.php
echo $_SERVER['PHP_SELF'];
// 結果:/article/dir/file.php
このような結果になります。両者ともファイル名までのパスを取得することができますが取得する範囲が異なります。
「定数__FILE__」:実行されているファイルのフルパス
「$_SERVER['PHP_SELF']」:ホスト名以下の実行中のスクリプトのパス
ホスト名とはこのサイトでいう「tech.amefure.com」の部分です。
一見似たような値を返す2つのコードですが取得するパスは微妙に違うので気をつけましょう。
よくある間違い
例えばURLを動的に構築したいとします。これを両者でコードにあらわそうとすると以下のようになります。
// https://ホスト名(.ディレクトリ名).ファイル名
echo 'https://'.$_SERVER['HTTP_HOST'].'/'.basename(dirname(__FILE__)).'/'.basename(__FILE__);
echo 'https://'.$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF'];
マジック定数「__FILE__」にはURLには不要なディレクトリの情報が入っているため自力で最適化しないと動的にURLを生成できません。ディレクトリの階層が変わればダメになってしまうこともありますし注意が必要です。
一方スーパーグローバル変数の$_SERVERは正しくURLを自動生成するのに向いています。
httpまたはhttps部分は自分で記述するとしてホスト名は$_SERVER['HTTP_HOST']、ホスト名より下のディレクトリとファイル名は$_SERVER['PHP_SELF']で取得することができます。
URLを動的に取得できる汎用的なコード
echo 'https://'.$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF'];
// 自分自身のURLを取得する場合
echo 'https://'.$_SERVER['HTTP_HOST'].dirname($_SERVER['PHP_SELF']).ファイル名;
// 自分自身と同階層のファイルのURLを取得する場合
この両者を覚えておけば色々な場面で使うことができます。
私も実際にこのサイトのheader部分を「header.php」としてincludeで使い回せるように作るときに、OGP設定のURLや画像のパスを取得する際に使用しました。デベロッパーツールではphpのコードはみることができませんが、正しいURLが記事ごとに取得できているのを確認してみてください。
// meta属性のOGP設定のURL部分
<meta property="og:url" content="<?php
if(dirname($_SERVER['PHP_SELF'])){
// ページごとにディレクトリがあればディレクトリも取得し表示
echo 'https://'.$_SERVER['HTTP_HOST'].dirname($_SERVER['PHP_SELF']).basename($_SERVER['PHP_SELF'],".php");
}else{
// ページごとにディレクトリがなければそのまま表示
echo 'https://'.$_SERVER['HTTP_HOST'].basename($_SERVER['PHP_SELF'],".php");
}
// meta属性のOGP設定の画像パス部分 変数$imgPathに各記事のサムネ画像名を格納
echo '<meta property="og:image" content="https://'.$_SERVER['HTTP_HOST'].dirname($_SERVER['PHP_SELF']).$imgPath.'"/>'
?>"/>
他にもあるパスを取得できる関数
pathinfo関数
pathinfo関数は便利な関数で先ほどのbasename関数やdirname関数を一度に使えるような関数です。
特徴としてはファイルのパス情報を連想配列で返すことです。連想配列で格納し取得したいパス名をキー値として指定することで値が返ってきます。挙動をみてみましょう。
$path = pathinfo('/article/dir/file.php');
echo $path['dirname']; //結果:/article/dir
echo $path['basename']; //結果:file.php
echo $path['extension']; //結果:php
echo $path['filename']; //結果:file
上から「ディレクトリ名,ファイル名,拡張子,ファイル名のみ」を取得することができます。
キー値は「dirname、basename、extension、filename」です。
もちろんこの両者でも取得することができます。
pathinfo($_SERVER['PHP_SELF']);
pathinfo(__FILE__);
まとめ
ファイル名を取得する方法は色々な方法がありました。最後にファイル名、ホスト名、ディレクトリ名、絶対パス(URL)を取得する方法をまとめておきます。
// 自分のファイル名 結果:file.php
echo basename($_SERVER['PHP_SELF']);
// ホスト名 結果:www.○○○.com
echo $_SERVER['HTTP_HOST'];
// 自分のホスト以下のディレクトリ名 結果:/article/dir
echo dirname($_SERVER['PHP_SELF']);
// 絶対パス(URL) 結果:https://www.○○○.com/article/dir/file.php
echo 'https://'.$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF'];
まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。
ご覧いただきありがとうございました。