PHPのdirname関数の使い方について

採用はこちら

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()は、requireincludeと組み合わせて別の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関数の使い方についてでした。

最後までお読みいただき、ありがとうございました。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次