PHP: Что делать, если я старую статический метод нестационарно

Я не занимаюсь объектно-ориентированным программированием, и у меня возникает глупый вопрос:

class test { public static function doSomething($arg) { $foo = 'I ate your ' . $arg; return $foo; } } 

Таким образом, правильный способ вызова doSomething() – выполнить test::doSomething('Pizza'); , Я прав?

Теперь, что произойдет, если я назову это так:

 $test = new test; $bar = $test->doSomething('Sandwich'); 

Я протестировал его, и он работает без каких-либо ошибок или уведомлений или т. Д., Но правильно ли это сделать?

Как уже указывал Баба, это приводит к E_STRICT зависимости от вашей конфигурации.

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

Если у вас есть иерархия классов, например

 class A { public static function sayHello() { echo "Hello from A!\n"; } public function sayHelloNonStaticWithSelf() { return self::sayHello(); } public function sayHelloNonStaticWithStatic() { return static::sayHello(); } } class B extends A { public static function sayHello() { echo "Hello from B!\n"; } public function callHelloInMultipleDifferentWays() { A::sayHello(); B::sayHello(); $this->sayHelloNonStaticWithSelf(); $this->sayHelloNonStaticWithStatic(); $this->sayHello(); } } $b = new B(); $b->callHelloInMultipleDifferentWays(); 

Это дает следующий результат:

 Hello from A! // A::sayHello() - obvious Hello from B! // B::sayHello() - obvious Hello from A! // $this->sayHelloNonStaticWithSelf() // self alweays refers to the class it is used in Hello from B! // $this->sayHelloNonStaticWithStatic() // static always refers to the class it is called from at runtime Hello from B! // $this->sayHello() - obvious 

Как вы можете видеть, легко добиться неожиданного поведения при смешивании статических и нестатических вызовов и методов метода.

Поэтому мой совет также заключается в следующем: используйте метод Class :: для явного вызова статического метода, который вы хотите вызвать. Или даже лучше не использовать статические методы вообще, потому что они делают ваш код неустойчивым .

Лучше вы называете это таким образом, чтобы избежать E_STRICT на некоторой версии PHP

 $bar = test::doSomething('Sandwich'); 

ОТ PHP DOC

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

Также

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

Неважно, если ваш метод не использует $this и не имеет доступа к статическим свойствам.

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

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

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