PHPのdirname()関数は、ファイルやディレクトリのパスから親ディレクトリのパスを取得するための関数です。
たとえば、次のようなファイルパスがあるとします。
/var/www/html/index.php
このパスにdirname()を使用すると、以下のように親ディレクトリを取得できます。
/var/www/html
ファイルの保存場所を基準に別のファイルを読み込んだり、プロジェクトの上位ディレクトリを参照したりするときに便利です。
dirname関数の基本的な書き方
dirname関数の構文
dirname()の基本構文は次のとおりです。
dirname(string $path, int $levels = 1): string
第1引数の$pathには、対象となるパスを指定します。
第2引数の$levelsには、何階層上のディレクトリを取得するかを指定します。
$levelsを省略した場合は1となり、1階層上のディレクトリが返されます。
なお、$levelsには1以上の整数を指定します。
親ディレクトリを取得する基本例
次のコードでは、ファイルパスから1階層上のディレクトリを取得しています。
$path = '/var/www/html/index.php';
echo dirname($path);
実行結果は次のとおりです。
/var/www/html
index.phpに相当する最後の部分が取り除かれ、親ディレクトリのパスが返されます。
dirname関数で複数階層上のディレクトリを取得する
第2引数に階層数を指定する
dirname()では、第2引数を指定することで複数階層上のディレクトリを取得できます。
たとえば、次のコードを見てみましょう。
$path = '/var/www/html/app/index.php';
echo dirname($path, 2);
実行結果は次のようになります。
/var/www/html
元のパスは次のとおりです。
/var/www/html/app/index.php
1階層上は以下です。
/var/www/html/app
さらに1階層上は以下になります。
/var/www/html
そのため、dirname($path, 2)では2階層上のディレクトリが取得できます。
dirnameを入れ子にする方法との違い
複数階層上のディレクトリを取得する場合、次のようにdirname()を入れ子にすることもできます。
dirname(dirname($path));
ただし、現在は次のように書くほうが簡潔です。
dirname($path, 2);
何階層上を取得しているのかがひと目で分かるため、可読性の面でも後者のほうが扱いやすいでしょう。
dirnameと__FILE__を組み合わせる方法
現在のPHPファイルのディレクトリを取得する
PHPには、現在のファイルのフルパスを表すマジック定数__FILE__があります。
たとえば、現在のPHPファイルが次の場所にあるとします。
/var/www/html/app/index.php
このファイル内で、
echo __FILE__;
とすると、現在のファイルのフルパスを取得できます。
これをdirname()と組み合わせると、現在のPHPファイルが存在するディレクトリを取得できます。
echo dirname(__FILE__);
実行結果は次のようになります。
/var/www/html/app
dirnameと__DIR__の違い
現在のディレクトリだけなら__DIR__が便利
PHPでは、現在のファイルが存在するディレクトリを表す__DIR__というマジック定数も利用できます。
基本的に、
dirname(__FILE__)
と、
__DIR__
は同じ目的で使えます。
そのため、現在のファイルと同じディレクトリを参照するだけなら、次のように__DIR__を使うほうが簡潔です。
require __DIR__ . '/config.php';
dirname(__FILE__)より短く、何を意味しているのかも分かりやすくなります。
上位ディレクトリを取得する場合はdirnameが便利
__DIR__からさらに上位のディレクトリを取得したい場合は、dirname()が便利です。
たとえば、
$rootDir = dirname(__DIR__, 2);
とすると、現在のディレクトリから2階層上のパスを取得できます。
プロジェクトルートを取得したい場合などによく使われます。
dirnameを使ってファイルを読み込む方法
requireと組み合わせる
dirname()は、requireやincludeと組み合わせて別のPHPファイルを読み込むときにも利用できます。
次のようなディレクトリ構成があるとします。
project/
├── config.php
└── public/
└── index.php
public/index.phpからconfig.phpを読み込む場合は、次のように記述できます。
require dirname(__DIR__) . '/config.php';
__DIR__はproject/publicを表します。
そこからdirname(__DIR__)を実行すると、1階層上のprojectディレクトリを取得できます。
その結果、project/config.phpを指定できます。
dirnameとbasenameの違い
dirnameはディレクトリ部分を取得する
dirname()は、パスから親ディレクトリ部分を取得します。
$path = '/var/www/html/index.php';
echo dirname($path);
結果は次のとおりです。
/var/www/html
basenameは最後の要素を取得する
一方、basename()はパスの最後の要素を取得する関数です。
$path = '/var/www/html/index.php';
echo basename($path);
実行結果は次のようになります。
index.php
つまり、役割は次のように分けられます。
dirname()
→ 親ディレクトリ部分を取得
basename()
→ 最後のファイル名やディレクトリ名を取得
ファイルパスを分解するときは、dirname()とbasename()をセットで覚えておくと便利です。
dirname関数を使うときの注意点
ファイルやディレクトリの存在は確認しない
dirname()は、指定されたファイルやディレクトリが実際に存在するかどうかを確認する関数ではありません。
たとえば、実際には存在しないパスでも、
$path = '/dummy/example/test.php';
echo dirname($path);
とすると、次の文字列を取得できます。
/dummy/example
ファイルやディレクトリの存在を確認したい場合は、用途に応じてfile_exists()やis_dir()などを使用します。
if (file_exists($path)) {
echo '存在します';
}
..を実際のパスとして解決する関数ではない
dirname()は、..を含むパスを実際のファイルシステムに基づいて正規化するための関数ではありません。
実在するファイルやディレクトリのパスを正規化したい場合は、realpath()を利用できます。
$path = realpath(__DIR__ . '/../config');
ただし、realpath()は対象のパスが実在しない場合にfalseを返す点に注意が必要です。
URLの解析には別の関数を使う
dirname()は基本的にファイルシステム上のパスを扱うための関数です。
URLを解析したい場合は、parse_url()などのURL向け関数を利用するほうが適しています。
$url = 'https://example.com/path/page.html';
$parts = parse_url($url);
ファイルパスとURLは目的が異なるため、用途に応じて関数を使い分けましょう。
Windows環境でdirnameを使う方法
Windowsのパスでも利用できる
dirname()はWindows環境でも使用できます。
たとえば、次のようなコードです。
$path = 'C:\Users\example\Documents\sample.txt';
echo dirname($path);
Windows環境では、親ディレクトリに相当するパスを取得できます。
Windows形式のパスをPHPの文字列として記述するときは、シングルクォートを使うとバックスラッシュの扱いが分かりやすくなります。
DIRECTORY_SEPARATORは必須ではない
OSごとのディレクトリ区切り文字を使用したい場合は、DIRECTORY_SEPARATORを利用できます。
$path = __DIR__
. DIRECTORY_SEPARATOR
. 'config'
. DIRECTORY_SEPARATOR
. 'database.php';
ただし、PHPではWindows環境でも多くの場合/をパス区切りとして使用できます。
そのため、一般的なPHPアプリケーションでは次のような書き方も広く使われています。
$path = __DIR__ . '/config/database.php';
DIRECTORY_SEPARATORを必ず使用しなければならないわけではありません。
dirname関数の実用例
プロジェクトルートを取得する
次のようなディレクトリ構成があるとします。
project/
├── config/
│ └── database.php
├── src/
│ └── Controller/
│ └── UserController.php
└── public/
UserController.phpの場所が、
/project/src/Controller/UserController.php
である場合、__DIR__は次の場所を示します。
/project/src/Controller
ここで、
$projectRoot = dirname(__DIR__, 2);
とすると、2階層上の、
/project
を取得できます。
その後、
$configFile = $projectRoot . '/config/database.php';
とすれば、プロジェクトルートを基準に設定ファイルのパスを作成できます。
dirname関数について覚えておきたいポイント
PHPのdirname()関数は、パスから親ディレクトリを取得するときに便利な関数です。
基本的な使い方は次のとおりです。
dirname($path);
複数階層上を取得したい場合は、第2引数を指定します。
dirname($path, 2);
また、現在のPHPファイルと同じディレクトリを取得するだけなら、dirname(__FILE__)よりも__DIR__を使うと簡潔に記述できます。
一方、__DIR__からさらに上位の階層を取得する場合は、dirname()との組み合わせが便利です。
dirname()はパスの存在確認や正規化を行う関数ではないため、必要に応じてfile_exists()、is_dir()、realpath()などと使い分けることも重要です。
ファイル読み込みやプロジェクトルートの取得など、PHPでは利用する機会が多い関数なので、__DIR__やbasename()との違いもあわせて覚えておくとよいでしょう。
以上、PHPのdirname関数の使い方についてでした。
最後までお読みいただき、ありがとうございました。










