Имеет ли статический метод в PHP какую-либо разницу с нестатическим методом?
class t {
public function tt()
{
echo 1;
}
}
t::tt();
посмотреть?Нестатическая функция также может вызываться на уровне класса.Итак, что изменилось, если я добавлю static
ключевое слово перед public
?
6 ответов
кроме того, если вы попытаетесь использовать $this
в вашем методе, как это:
class t {
protected $a = 10;
public function tt() {
echo $this->a;
echo 1;
}
}
t::tt();
вы получите фатальную ошибку при вызове нестатического метода статически:
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
итак: не так уж хорошо ; -)
Тем не менее, статически вызов нестатического метода не выглядит как хорошая практика (наверное, поэтому он поднимает строгое предупреждение), поскольку статические методы не имеют того же значения , что и нестатические: статические методы не ссылаются на какой-либо объект, а нестатические методы работают с экземпляром класса, который вызывается.
Еще раз: даже если PHP позволяет вам что-то делать (возможно по историческим причинам-как совместимость со старыми версиями), это не значит, что вы должны сделать это !
Так как статические методы вызываются без создания экземпляра созданного объекта, псевдо-переменная $This не доступна внутри метода, объявленного как static.
статические свойства не могут быть доступны через объект с помощью оператора стрелки ->.
вызов нестатических методов статически генерирует предупреждение уровня 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();
обратите внимание, что статическое свойство счетчик является частным, поэтому он может быть доступен только самим классом и экземплярами этого класса, но не извне.
основное отличие, которое не было упомянуто, относится к полиморфное поведение.
нестатические методы при повторном объявлении в производном классе переопределяют метод базового класса и разрешают полиморфное поведение на основе типа вызываемого экземпляра. это не относится к статическим методам.
PHP 5.3 представил концепцию позднее статическое связывание который можно использовать для ссылки вызываемый класс в контексте статического наследования.
да, критическая разница заключается в том, что методы, объявленные static
не имеют доступа к переменной object-context,$this
.
кроме того, вызов нестатического метода, когда не в контексте объекта вызовет 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.