2012-02-10 4 views
6

Tôi có một lớp thiết lập bí danh lớp cho các tên lớp khác. Khi một hàm được gọi bên trong lớp này thông qua lớp aliased, tôi cần biết bí danh nào đã được sử dụng. Có cách nào để làm điều này trong PHP?Trong PHP, làm thế nào để bạn có được lớp được gọi là bí danh khi sử dụng class_alias?

Tôi đã thử đoạn mã sau:

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

class_alias('foo', 'bar'); 

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

Những kết quả đầu ra:

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

Nhưng tôi muốn bar::test(); để đầu ra string 'bar' (length=3) để thay thế. Nắm bắt ở ống hút, __CLASS__get_class() tất cả đều tạo ra cùng một kết quả. Tôi không thể tìm thấy bất cứ điều gì khác trong tài liệu PHP sẽ giúp tôi với vấn đề này, nhưng hy vọng tôi đang nhìn cái gì đó.

Làm cách nào để bạn có được lớp được gọi là bí danh khi sử dụng class_alias?

+5

Cá nhân tôi khuyên bạn không nên chỉ định bí danh lớp học. Nó sẽ kết thúc trong nước mắt. – GordonM

+0

Bạn không thể trừ khi bạn sử dụng phương thức debug_backtrace() horrendous ... bar :: test() không gọi test() trong lớp bar, là một bản sao hoặc bản sao của lớp foo; nó gọi phương thức test() trong chính lớp foo, điều này chỉ xảy ra với một bí danh của thanh, vì vậy get_called_class() tự nhiên trả về "foo". –

+0

Dup http://stackoverflow.com/questions/6245705/get-top-level-class-name-when-inheritance-and-class-alias-is-used – CBusBus

Trả lời

7

Bạn không thể thực hiện điều này dễ dàng như của PHP 5.3-5.5.

Chỉ có một số cách để xác định lớp "hiện tại" là khi thực hiện cuộc gọi. Tất cả họ đều trở lại lớp không thiên vị.

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.

Điều này là do class_alias không tạo ra một lớp mới với tên mới, nó tạo một mục nhập khác trong danh sách các lớp trỏ đến cùng một lớp với lớp gốc. Khi bạn yêu cầu PHP tra cứu lớp nào đang được sử dụng, nó sẽ tìm thấy lớp gốc, không phải là bí danh.

Nếu bạn cần tạo một lớp mới thì không có gì là lớp gốc với tên khác, bạn sẽ cần phải làm như vậy thông qua kế thừa. Bạn có thể thực hiện thao tác này bằng cách sử dụng eval. Tôi không thể tin rằng tôi sẽ giới thiệu eval cho một cái gì đó. 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.

Điều này có thể không hoạt động tốt cho mọi trường hợp. Trong PHP, các thành viên riêng tư có thể xem không phải là bởi các lớp con cháu, vì vậy điều này có thể phá vỡ mã của bạn một cách khủng khiếp.