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

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

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

Ответ 1

Кроме того, если вы попытаетесь использовать $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 позволяет вам что-то делать (возможно, по историческим причинам - например, совместимость со старыми версиями), это не значит, что вы должны это сделать!

Ответ 2

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

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

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

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

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

Ответ 3

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

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

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

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

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();

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

Ответ 4

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

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


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

Ответ 5

Да, критическая разница заключается в том, что объявленные методы 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 все равно вызовет фатальную ошибку и выйдет из программы.

Ответ 6

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

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