class t {
public function tt()
{
echo 1;
}
}
t::tt();
См.? Нестатическая функция также может быть вызвана на уровне класса. Так что, если я добавляю ключевое слово static
до public
?
class t {
public function tt()
{
echo 1;
}
}
t::tt();
См.? Нестатическая функция также может быть вызвана на уровне класса. Так что, если я добавляю ключевое слово static
до public
?
Кроме того, если вы попытаетесь использовать $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
то есть. ваш пример слишком прост и не соответствует реальному случаю; -)
Также обратите внимание, что ваш пример должен получить строгое предупреждение (quoting):
Вызов статических статических методов генерирует предупреждение уровня
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 недоступна внутри метода, объявленного как 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.