PHP
BOX
namespace
get_declared_classes

PHP の名前空間の一覧(調べ方)

TL;DR

色々 include しすぎたり auto_load した際に、利用したいクラス名はわかるも、呼び出すと名前空間が違うと怒られる場合は get_declared_classes()関数を使って定義済みクラスの一覧を取得して、該当するクラスの名前空間を確認できます。

TS;DR

Hello Error!

ちょっとしたアプリを作成したので、配布する際に単一の実行可能な PHP ファイルとして配布できるように Phar 形式(PHPアーカイブ)でアーカイブしました。

以下が、Phar化(アーカイブ)される本体 PHP スクリプトです。

index.phpFunctions.phpHelloWorld.phar としてアーカイブされ、$ php HelloWorld.phar を実行すると「Hello World.」と表示するだけのシンプルなものです。

index.php
<?php

namespace KEINOS\Sample;

include('Functions.php');

if (is_phar()) {
    echo 'Hello World.' . PHP_EOL;
} else {
    echo 'Running directly. Not a phar file.' . PHP_EOL;
}
Functions.php
<?php

namespace KEINOS\Sample;

function is_phar()
{
    return strlen(Phar::running()) > 0 ? true : false;
}

実行時にアーカイブ状態であるかの確認、つまりアプリ自身が Pharとして実行されているか確認をするために is_phar ユーザ関数内で、Phar クラスのメソッドを呼び出しています。

しかし、アプリの本体内部で namespace(名前空間)を使っているため、次のエラーが発生しました。

$ php HelloWorld.phar
PHP Fatal error: Uncaught Error: Class 'KEINOS\Sample\Phar' not found in phar:///PATH/TO/YOUR/SAMPLE/PHAR/APP/HelloWorld.phar/src/Functions.php:7

自分のスクリプト内では Phar クラスの定義はしていないため、当然といえば当然のエラーです。

A Class With No Name Space ~ 名前空間のないクラス ~

では、問題の Phar クラスはどこに属しているのか。

私は、Phar アーカイブを行う際に便利なアーカイバー「Box」を利用しているのですが、てっきり Box の名前空間を使うのかと思っていたのですが、手当たり次第思いつく名前空間をつけても NG でした。

そこで、定義済みのクラスを表示させることで確認したところ、そもそも Phar は PHP のコアなクラスであるため名前空間を持っていませんでした。落ち着いて考えれば、そりゃそうです。

名前空間のないクラスの呼び出し方

最終的には、スクリプトを以下のように Phar クラスの前いバックティック(\)を加えてエラーを回避しました

Functions.php
<?php

namespace KEINOS\Sample;

function is_phar()
{
    return strlen(\Phar::running()) > 0 ? true : false;
}

参考文献