Стационарный метод в PHP имеет какую-либо разницу с нестационарным методом?

class t { public function tt() { echo 1; } } t::tt(); 

См.? Нестатическая функция также может быть вызвана на уровне класса. Так что же изменится, если я добавлю static ключевое слово перед public ?

Solutions Collecting From Web of "Стационарный метод в PHP имеет какую-либо разницу с нестационарным методом?"

Кроме того, если вы попытаетесь использовать $this в своем методе, например:

 class t { protected $a = 10; public function tt() { echo $this->a; echo 1; } } t::tt(); 

Вы получите Fatal Error при вызове нестатического метода статически:

 Fatal error: Using $this when not in object context in ...\temp.php on line 11 

т. е. ваш пример слишком прост и на самом деле не соответствует реальному случаю 😉

Также обратите внимание, что ваш пример должен содержать строгое предупреждение ( цитирование ):

Вызов нестатических методов статически генерирует предупреждение уровня E_STRICT .

И это на самом деле (по крайней мере, с PHP 5.3) :

 Strict Standards: Non-static method t::tt() should not be called statically in ...\temp.php on line 12 1 

Итак: не так хорошо 😉

Тем не менее статический вызов нестатического метода не похож на какую-либо хорошую практику (вероятно, поэтому он вызывает предупреждение Strict) , поскольку статические методы не имеют того же значения, что и нестатические: статические методы делают не ссылаться на какой-либо объект, в то время как нестатические методы работают над экземпляром вызываемого класса.

Еще раз: даже если PHP позволяет вам что-то сделать (возможно, по историческим причинам – например, совместимость со старыми версиями) , это не значит, что вы должны это сделать!

Статическое ключевое слово

Поскольку статические методы вызываются без экземпляра созданного объекта, псевдопеременная $ this недоступна внутри метода, объявленного как статический.

Статические свойства не могут быть доступны через объект с помощью оператора стрелки ->.

Вызов нестатических методов статически генерирует предупреждение уровня E_STRICT.

Просто потому, что вы можете вызывать нестатические методы статически, это не значит, что вы должны. Это плохая форма.

Обычно статический метод также называется методом класса, а нестатический метод также называется методом объекта или методом экземпляра .

Разница между методом класса и объектным методом заключается в том, что методы класса могут обращаться только к свойствам класса (статические свойства), тогда как объектные методы используются для доступа к свойствам объекта (свойства одного и того же экземпляра класса).

Статические методы и свойства используются для совместного использования общих данных или для всех экземпляров этого конкретного класса.

Например, вы можете использовать статическое свойство для отслеживания количества экземпляров:

 class A { private static $counter = 0; public function __construct() { self::counter = self::counter + 1; } public function __destruct() { self::counter = self::counter - 1; } public static function printCounter() { echo "There are currently ".self::counter." instances of ".__CLASS__; } } $a1 = new A(); $a2 = new A(); A::printCounter(); unset($a2); A::printCounter(); с class A { private static $counter = 0; public function __construct() { self::counter = self::counter + 1; } public function __destruct() { self::counter = self::counter - 1; } public static function printCounter() { echo "There are currently ".self::counter." instances of ".__CLASS__; } } $a1 = new A(); $a2 = new A(); A::printCounter(); unset($a2); A::printCounter(); 

Обратите внимание, что статический счетчик свойств является закрытым, поэтому доступ к нему может получить только сам класс и экземпляры этого класса, но не извне.

Основное отличие, которое не упоминалось, относится к полиморфному поведению .

Нестационарные методы при переопределении в производном классе переопределяют метод базового класса и допускают полиморфное поведение, основанное на типе экземпляра, на который они вызваны. Это не относится к статическим методам .


PHP 5.3 представил концепцию поздней статической привязки, которая может использоваться для ссылки на вызываемый класс в контексте статического наследования.

Да, критическая разница заключается в том, что методы, объявленные static , не имеют доступа к переменной object-context, $this .

Кроме того, вызов нестатического метода, если не в контексте объекта, вызывает E_STRICT ошибки E_STRICT . Когда включено, поведение этого события по умолчанию – выводить сообщение в журнал ошибок (или STDERR), но это позволит программе продолжать работу .

Кроме того, любая попытка ссылаться на $this если не в контексте объекта, вызывает событие E_ERROR . Поведение этого события – выводить сообщение в журнал ошибок (или STDERR) и выходить из программы со статусом 255.

Например:

 <?php error_reporting(-1); //error_reporting(E_ALL); class DualNature { public static function fnStatic() { if ( isset( $this ) ) { // never ever gets here $myValue = $this->_instanceValue; } else { // always gets here $myValue = self::$_staticValue; } return $myValue; } public function fnInstance() { if ( isset( $this ) ) { // gets here on instance (->) reference only $myValue = $this->_instanceValue; } else { // gets here in all other situations $myValue = self::$_staticValue; } return $myValue; } public static function fnStaticDeath() { return $this->_instanceValue; } private static $_staticValue = 'no access to $this'; private $_instanceValue = '$this is available'; } $thing = new DualNature(); echo "==========\n"; printf("DualNature::fnStatic(): \"%s\"\n", DualNature::fnStatic() ); echo "==========\n"; printf("\$thing::fnStatic(): \"%s\"\n", $thing::fnStatic() ); echo "==========\n"; printf("\$thing->fnStatic(): \"%s\"\n", $thing->fnStatic() ); echo "==========\n"; printf("DualNature::fnInstance(): \"%s\"\n", DualNature::fnInstance() ); echo "==========\n"; printf("\$thing::fnInstance(): \"%s\"\n", $thing::fnInstance() ); echo "==========\n"; printf("\$thing->fnInstance(): \"%s\"\n", $thing->fnInstance() ); echo "==========\n"; printf("\$thing->fnStaticDeath(): \"%s\"\n", $thing->fnStaticDeath() ); echo "==========\n"; echo "I'M ALIVE!!!\n"; 

Вышеуказанный результат:

 ========== PHP Strict Standards: Non-static method DualNature::fnInstance() should not be called statically in example.php on line 45 DualNature::fnStatic(): "no access to $this" ========== $thing::fnStatic(): "no access to $this" ========== $thing->fnStatic(): "no access to $this" PHP Strict Standards: Non-static method DualNature::fnInstance() should not be called statically in example.php on line 47 ========== DualNature::fnInstance(): "no access to $this" ========== $thing::fnInstance(): "no access to $this" ========== $thing->fnInstance(): "$this is available" ========== PHP Fatal error: Using $this when not in object context in example.php on line 29 

Изменение уровня сообщений об ошибках на E_ALL приведет к подавлению предупреждающих сообщений по умолчанию E_STRICT (событие все равно будет распространено), но неверная ссылка на $this все равно вызовет фатальную ошибку и выйдет из программы.

Помимо синтаксиса и функциональных различий существует также разница в производительности.

Вы можете обратиться к этому более или менее детальному сравнению статических и нестатических методов в PHP .