取得方法
下記のような変換を行います。
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
といった静的解析ができるように記述したかったです。
サンプル
<?php
Class Class_A {
public function sample_method() {
}
}
<?php
namespace Somenamespace;
class Named_class_B {
public function sample_method() {
}
}
<?php
namespace Somenamespace;
Interface I_named_class_C {
public function sample_method();
}
<?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()が参照渡しなので一旦変数に取っています。うーん良い方法無いかな。