Я не занимаюсь объектно-ориентированным программированием, и у меня возникает глупый вопрос:
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 вы можете вызвать его на экземпляре.