Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In PHP, how do you get the called aliased class when using class_alias?

Tags:

php

php-5.3

I have a class that sets up a class alias for other class names. When a function is called inside of this class via the aliased class, I need to know which alias was used. Is there a way to do this in PHP?

I have tried the following code:

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

class_alias('foo', 'bar');

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

Which outputs:

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

But I want bar::test(); to output string 'bar' (length=3) instead. Grasping at straws, __CLASS__ and get_class() all produce the same result. I can't seem to find anything else in the PHP documentation that would help me with this problem, but hopefully I am overlooking something.

How do you get the called aliased class when using class_alias?

like image 770
Joe Lencioni Avatar asked Feb 10 '12 14:02

Joe Lencioni


1 Answers

You can't do this easily as of PHP 5.3-5.5.

There are only a handful of ways to determine what the "current" class is when a call is made. All of them return the unaliased class.

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.

This is because class_alias doesn't create a new class with the new name, it creates another entry in the list of classes that points at the same class as the original. When you ask PHP to look up what class is being used, it finds the original class, not the alias.

If you need to create a new class is nothing more the original class with a different name, you'll need to do so via inheritance. You can do this dynamically using eval. I can't believe I'm going to recommend eval for something. Eww.

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.

This might not work well for all cases. In PHP, private members can not be seen by descendant classes, so this might break your code horribly.

like image 195
Charles Avatar answered Sep 24 '22 16:09

Charles