2013-10-10 1 views
3
<?php 

class T { 
     public function x(){ 
       return true; 
     }  
} 
var_dump(T::x()); 

class X { 
     public function x(){ 
       return true; 
     } 

}  
var_dump(X::x()); 

Этот код приводит к:понимание обработки PHP статических методов (не статический метод не может быть вызван статически)

bool(true) 
PHP Fatal error: Non-static method X::x() cannot be called statically in test.php on line 16 

Почему T :: х() работает (когда он выйдет из строя) и X :: x() не работает (как должно)?

+1

хорошо, себя, родителей и статические также делают не-статические вызовы. Вы уверены, что '$ x = T :: x();' успешно ?! – bwoebi

+0

Обратите внимание, что в testY() вы создаете объект T, но не объект X. Кажется, это имеет значение. – Oniofchaos

+0

@bwoebi, это именно то, что я нахожу странным во всем этом. Я копирую вложенное ядро, которое я запускаю. не стесняйтесь воспроизводить и видеть, работает ли он иначе. также будет обновляться с помощью моих версий php/phpunit, что может быть полезно. – gcb

ответ

3

X::x() на самом деле является конструктором стиля PHP4, так как он имеет одно и то же имя класса. И называя конструкторы класса статически вызывает фатальную ошибку:

Non-static method X::x() cannot be called statically, assuming $this from incompatible context

Это на самом деле имеет место для всех нестатические магических методов, как вы можете видеть в реализации: http://lxr.php.net/xref/PHP_5_5/Zend/zend_compile.c#1636

Единственный случай где он может быть неявным называется статический (и поднять E_STRICT), когда функция не имеет специальную обработки:

if (some large if/else's for the magic methods) { 
    // flag isn't set… 
} else { 
    CG(active_op_array)->fn_flags |= ZEND_ACC_ALLOW_STATIC; 
} 
+0

Почему T :: x() не trhow та же ошибка. – gcb

+0

@gcb, потому что T :: x() не является конструктором стиля PHP4 (и это не магический метод, который позволяет статическим вызовам из несовместимого контекста)? _Для обратной совместимости, если PHP 5 не может найти функцию __construct() для данного класса и класс не наследует ее от родительского класса, она будет искать ** функцию конструктора старого стиля по имени класса ** ._ из http://php.net/manual/en/language.oop5.decon.php – bwoebi

+0

Я все еще не вижу, как T :: x() отличается от X :: x(). Если я удалю первый тест, который создает «новый T()» из кода, то происходит то же самое. T :: x() не вызывает ошибку. но X: :(). – gcb

Смежные вопросы