2009-03-23 35 views
25

Tôi đang cố gắng truy cập biến tĩnh trong lớp bằng cách sử dụng tên lớp biến. Tôi biết rằng để truy cập vào một chức năng trong lớp, bạn sử dụng call_user_func():

class foo { 
    function bar() { echo 'hi'; } 
} 
$class = 'foo'; 
call_user_func(array($class, 'bar')); // prints hi 

Tuy nhiên, điều này không làm việc khi cố gắng truy cập vào một tĩnh biến trong lớp:

class foo { 
    public static $bar = 'hi'; 
} 
$class = "foo"; 
call_user_func(array($class, 'bar')); // nothing 
echo $foo::$bar; // invalid 

Làm cách nào để nhận được biến này? Thậm chí có thể không? Tôi có một cảm giác xấu này chỉ có sẵn trong PHP 5.3 đi về phía trước và tôi đang chạy PHP 5.2.6.

+0

@Rrinkle, xin vui lòng không có thói quen thêm chữ đậm vào văn bản - nó không giúp ích nhiều như nhiều người. Cảm ơn! – sarnold

Trả lời

24

Bạn có thể sử dụng reflection để làm điều này. Tạo một đối tượng ReflectionClass cho tên lớp, và sau đó sử dụng phương thức getStaticPropertyValue để lấy giá trị biến tĩnh.

class Demo 
{ 
    public static $foo = 42; 
} 

$class = new ReflectionClass('Demo'); 
$value=$class->getStaticPropertyValue('foo'); 
var_dump($value); 
+0

Tôi đã nhận thấy rằng getStaticPropertyValue ($ prop) không xuất hiện để hoạt động nếu $ prop là bất cứ điều gì nhưng "tĩnh công cộng". Nó sẽ bork nếu $ prop được tuyên bố là "private static" hoặc "static static" trong lớp. Tôi không chắc chắn lý do tại sao, mặc dù. – brianjcohen

+10

Điều này có ý nghĩa, vì nếu nó KHÔNG công khai, bạn không nên truy cập nó từ bên ngoài lớp học. – adudley

21

Đối với các thành viên tĩnh gọi bạn có thể sử dụng một mã như thế này:

call_user_func("MyClass::my_static_method"); 
// or 
call_user_func(array("MyClass", "my_static_method")); 

Thật không may là cách duy nhất để có được các thành viên tĩnh từ một đối tượng có vẻ là get_class_vars():

$vars = get_class_vars("MyClass"); 
$vars['my_static_attribute']; 
24

Tôi nghĩ rằng có cách nào tốt hơn (thanh lịch hơn) sau đó tạo cá thể ReflectionClass. Tôi cũng đã chỉnh sửa mã này (và câu trả lời của tôi) sau vài bình luận. Tôi đã thêm ví dụ cho các biến được bảo vệ (bạn không thể truy cập chúng từ bên ngoài lớp, vì vậy tôi đã tạo ra getter tĩnh và gọi nó bằng cách sử dụng mẫu biến). Bạn có thể sử dụng nó trong vài cách khác nhau:

class Demo 
{ 
    public static $foo = 42; 
    protected static $boo = 43; 
    public static function getProtected($name) { 
     return self::$$name; 
    } 
} 

$var1 = 'foo'; 
$var2 = 'boo'; 
$class = 'Demo'; 
$func = 'getProtected'; 
var_dump(Demo::$$var1); 
var_dump($class::$foo); 
var_dump($class::$$var1); 
//var_dump(Demo::$$var2); // Fatal error: Cannot access protected property Demo::$boo 
var_dump(Demo::getProtected($var2)); 
var_dump($class::getProtected($var2)); 
var_dump($class::$func($var2)); 

Tài liệu là ở đây:

http://php.net/manual/en/language.variables.variable.php

+1

Tôi không nghĩ rằng điều này sẽ làm việc nếu 'Demo' là một biến ... nhưng nó có:' $ class :: $$ field' – mpen

+0

yeah, it does. Tôi quên viết nó - cảm ơn! – Karol

+1

'$ class :: $$ field' chỉ hoạt động nếu bạn đang sử dụng PHP 5.3 hoặc cao hơn, có vẻ như. – jamietelin

2

Bạn đã thử loại này?

class foo { 
    static public $bar = "Hi"; 

    static public function bar() { 
     echo "Hi"; 
    } 
} 

echo foo::$bar; // Output: Hi 
foo::bar(); // Output: Hi 

$class = "foo"; 
echo $class::$bar; // Output: Hi 
$class::bar(); // Output: Hi 
call_user_func($class, 'bar'); // Output: Hi 
+2

Câu hỏi là 4 tuổi và đề cập rõ ràng đến một phiên bản PHP cũ, nơi '$ class: : $ bar' là không thể được nêu ra. –

Các vấn đề liên quan