phpでアプリ(ソース)のルートパスを取得する方法をまとめてみた。

$_SERVER変数利用

<?php
$path = $_SERVER['DOCUMENT_ROOT'];

この変数は基本的にサーバーで定義されています。(最近のwebアプリだとnginxapacheが多い)

このパスは公開パスの場合が多くて、つまり外から直接アクセスできるパスとなる。例えば./app/public./app/web。実際ソースのルート./appを取得する際は、$_SERVER['DOCUMENT_ROOT']の親ディレクトリを取得しないといけないことが多い:

<?php
$root = dirname($_SERVER['DOCUMENT_ROOT']);

この方法はサーバーの設定に左右されるし、CLI(コマンドライン)からの実行では取得できないので、あまりオススメしない

アプリのhelperに取得メソードを定義する

おすすめの案は、アプリのルートに汎用的なhelper.phpを置いて、そこにルートを取得関数を定義する:

<?php

if (!function_exists('app_root')) {
    function app_root() {
        return rtrim(__DIR__ . '/' . join('/', array_map(function($v) {
            return trim($v, '/');
        }, func_get_args())), '/');
        /* 
            わかりやすいver
            $args = func_get_args(); // 引数を配列として取得
            foreach ($args as $key => $value) {
                $args[$key] = trim($value); // 全ての引数の首尾の'/'を消す
            }
            $path = join('/', $args); // 配列の要素を'/'で繋げる
            $ret = __DIR__ . '/' . $path; // ルートパスと繋ぐ
            return rtrim($ret, '/'); // 最後の'/'消す(標準化するため)
        */
    }
}

使い場所には:

<?php

require 'path/to/helper.php'; // helperを導入

var_dump(app_root());
// "/<root>"

var_dump(app_root('abc', 'd'));
// "<root>/abc/d"

var_dump(app_root('abc', 'd', '///e', '//f//', '/g/'));
// "php/abc/d/e/f/g" <= 変な書き方でも綺麗に直してくれる

var_dump(app_root('path/to', 'file.php'));
// "/<roo>/path/to/file.php"

var_dump($_SERVER['DOCUMENT_ROOT']);
// "" <= だめだ><

この方法だと、webからでもCLIでも使える!

しかもパスの入力はかなりシンプルになった。(綺麗に渡された引数をパスの階層として繋いでくれる)