PHP

PHPでnamespaceを除いたクラス名を取得する


取得方法

下記のような変換を行います。

Somenamespace\named_class_B => named_class_B

explode()end()を利用すると取得できます。

<?php

$class_parts = explode('\\', \Somenamespace\named_class_B::class);
echo end($class_parts) . PHP_EOL; // named_class_B


目的

Laravelでクラス名を列挙して利用したかったです。

その際にクラス名からDBのテーブル名への変換、エンドポイントの設定などを配列を使って行いたかったのですが、クラス名から文字列への変換に手間取りました。

文字列でnamed_class_B使えば良いのですが、それだとIDEの静的解析から漏れてしまうため、Typoなどを検出できませんでした。

そのためできれば Somenamespace\named_class_B::class といった静的解析ができるように記述したかったです。


サンプル


Class_A.php

<?php

Class Class_A {
public function sample_method() {

}
}



Named_class_B.php

<?php

namespace Somenamespace;

class Named_class_B {
public function sample_method() {

}
}



I_named_class_C.php

<?php

namespace Somenamespace;

Interface I_named_class_C {
public function sample_method();
}



main.php

<?php

require 'Class_A.php';
require 'Named_class_B.php';
require 'I_named_class_C.php';

new Class_A();
new \Somenamespace\Named_class_B();

// ネームスペースなし
echo Class_A::class . PHP_EOL; // Class_A

// ネームスペースあり
echo \Somenamespace\Named_class_B::class . PHP_EOL; // Somenamespace\\Somenamespace\Named_class_B
echo basename(\Somenamespace\Named_class_B::class) . PHP_EOL; // Somenamespace\\Somenamespace\Named_class_B
// new すれば取れる
echo get_class(new \Somenamespace\Named_class_B()) . PHP_EOL; // \Somenamespace\Named_class_B

// echo get_class(I_named_class_C::class); // Interfaceの場合にnewできない。

// これが解決方法
// @see https://stackoverflow.com/questions/49358575/get-class-name-minus-namespace-without-using-reflection
$class_parts = explode('\\', \Somenamespace\Named_class_B::class);
echo end($class_parts) . PHP_EOL; // named_class_B

$class_parts = explode('\\', \Somenamespace\I_named_class_C::class);
echo end($class_parts) . PHP_EOL; // I_named_class_C


コードはここからです。

php - Get class name minus namespace without using Reflection - Stack Overflow

get_class()も良かったのですが、インスタンスを作らなければ取れませんでした。

::classのようなものがあれば良いのですが見つかりませんでした。

Interfaceの場合でも動くexplode('\\')ですね。

せめてワンライナーで書きたいのですが、explode->end()が参照渡しなので一旦変数に取っています。うーん良い方法無いかな。