В PHP, как вы получаете вызываемый псевдоним класса при использовании псевдонима класса?


У меня есть класс, который устанавливает псевдоним класса для других имен классов. Когда функция вызывается внутри этого класса через класс aliased, мне нужно знать, какой псевдоним был использован. Есть ли способ сделать это в PHP?

Я попробовал следующий код:

class foo
{
  public static function test()
  {
    var_dump(get_called_class());
  }
}

class_alias('foo', 'bar');

foo::test();
bar::test();

Который выводит:

string 'foo' (length=3)
string 'foo' (length=3)

Но я хочу bar::test(); вывести string 'bar' (length=3) вместо этого. Хватаясь за соломинку, __CLASS__ и get_class() дают один и тот же результат. Я не могу найти ничего другого в документации PHP, что помогло бы мне с этой проблемой, но, надеюсь, я что-то упускаю из виду.

Как получить вызываемый классс псевдонимами при использовании class_alias?

1 6

1 ответ:

Вы не можете сделать это легко, как в PHP 5.3-5.5.

Существует всего несколько способов определить, что такое" текущий " класс при выполнении вызова. Все они возвращают невозмущенный класс.
class First {
    public function test1() { echo get_called_class(); }
    public function test2() { print_r(debug_backtrace()); }
    public function test3() { echo get_class($this); }
    public function test4() { echo __CLASS__; }
    public static function test5() { echo get_called_class(); }
}
class_alias('First', 'Second');
$aliased = new Second();
$aliased->test1(); // First
$aliased->test2(); // array( 0 => array( ... [object] => First Object, ... ) )
$aliased->test3(); // First
$aliased->test4(); // First
Second::test5();   // First

3v4l demo .

Это происходит потому, что class_alias не создает Новый класс с новым именем, он создает другую запись в списке классов, которая указывает на тот же класс, что и исходный. Когда вы просите PHP посмотреть, какой класс используется, он находит исходный класс, а не псевдоним.

Если вам нужно создать новый класс-это не более чем исходный класс с другим именем, вам нужно будет сделать это с помощью наследования. Вы можете сделать это динамически, используя eval. Я не могу поверить, что собираюсь рекомендовать eval для чего-то. Фу.

class First {
    public function test1() { echo get_called_class(); }
    public function test2() { print_r(debug_backtrace()); }
    public function test3() { echo get_class($this); }
    public function test4() { echo __CLASS__; }
    public static function test5() { echo get_called_class(); }
}

function class_alias_kinda($original, $alias) {
    eval("class $alias extends $original {}");
}

class_alias_kinda('First', 'Second');
$aliased = new Second();
$aliased->test1(); // Second
$aliased->test2(); // array( 0 => array( ... [object] => Second Object, ... ) )
$aliased->test3(); // Second
$aliased->test4(); // First (this is expected)
Second::test5();   // Second

3v4l demo .

Это может сработать не во всех случаях. В PHP частные члены не могут быть замечены классами-потомками, поэтому это может привести к ужасному нарушению вашего кода.