Просто FYI, ваш первый пример - переменная экземпляра, вызывающая статический метод, который невозможен, потому что статический метод является частью класса и недоступен через переменную экземпляра.
Joejoeson
Вы можете удалить $ this сейчас, пожалуйста, он не работает, только если используются статические методы и не существует экземпляра.
...но почему? $ this-> staticMethod () тоже работает. Можете ли вы объяснить, почему self :: staticMethod () более правильно (если это так)?
Ян Данн
29
@Ian Dunn Проще говоря, $thisсуществует , только если объект был создан, и вы можете использовать только $this->methodиз существующего объекта. Если у вас нет объекта, но вы просто вызываете статический метод, и в этом методе вы хотите вызвать другой статический метод в том же классе, вы должны использовать self::. Поэтому, чтобы избежать потенциальных ошибок (и строгих предупреждений), лучше использовать self.
Йерун
1
Спасибо! В laravel я обнаружил, что случайно вызывал статический метод через расширенный контроллер $this, но проблема не возникала до тех пор, пока код не был передан stage. ошибок не возвращалось, значение было просто 0. будьте осторожны с этим, используйтеself::
Из foo()метода, давайте посмотрим на различные варианты:
$this->staticMethod();
Так что это вызывает staticMethod()как метод экземпляра, верно? Это не. Это потому, что метод объявлен как public staticинтерпретатор, будет вызывать его как статический метод, поэтому он будет работать как положено. Можно утверждать, что это делает из кода менее очевидным, что происходит статический вызов метода.
$this::staticMethod();
Начиная с PHP 5.3 вы можете использовать, $var::method()чтобы означать <class-of-$var>::; это довольно удобно, хотя приведенный выше вариант использования все еще довольно нетрадиционен. Итак, это приводит нас к наиболее распространенному способу вызова статического метода:
self::staticMethod();
Теперь, прежде чем вы начинаете думать , что ::это оператор статического вызова, позвольте мне дать вам еще один пример:
self::bar();
Это напечатает baz = 1, что означает, что $this->bar()и self::bar()делать то же самое; это потому, что ::это просто оператор разрешения области видимости. Это там , чтобы сделать parent::, self::и static::работу , и вы получите доступ к статическим переменным; способ вызова метода зависит от его сигнатуры и способа вызова.
self::bar()кажется вводящим в заблуждение - это теперь осуждается? (используется self::для вызова метода экземпляра, а не статического метода).
ToolmakerSteve
@ToolmakerSteve, как бы вы сказали, что это вводит в заблуждение?
Ja͢ck
Логически говоря, нет selfпри вызове статического метода. По определению: статический метод вызывается из любого места и не получает параметр «self». Тем не менее, я вижу удобство этого phpсинтаксиса, так что вам не нужно писать MyClassName::. Я привык к языкам со статической типизацией, где компилятору должны быть указаны все переменные, доступные в текущей области видимости, поэтому (эквивалент) self::может быть опущен. Так сказал только один self instanceMethod; нет причин говорить self staticMethod.
ToolmakerSteve
15
Это очень поздний ответ, но он добавляет некоторые детали к предыдущим ответам
Когда речь идет о вызове статических методов в PHP из другого статического метода в том же классе, важно различать selfимя класса.
Я нашел это информативным. Небольшая гнида, я бы не сказал, что другие ответы "вводят в заблуждение". Точнее сказать, что они «неполные»; они не решают (не заданный) вопрос о том, что self::происходит в (редком) случае, когда статический метод A вызывает другой статический метод B, а B был переопределен в подклассе. ИМХО, менее запутанно ограничивать переопределение метода методами «экземпляра»; используйте эту способность экономно на статическом уровне. Другими словами, читатели вашего кода ожидают переопределения методов экземпляров (что является сущностью ОО-кодирования), но не статических.
ToolmakerSteve
1
Очень полезно и имеет смысл, что расширение класса не является исходным классом. Следовательно, очевидно, selfчто в этом случае оно не будет использовано. Вы объявили отдельный класс как расширение первого класса. Использование selfв расширенном классе будет ссылаться на расширенный класс. Это не противоречит другим ответам, но, безусловно, помогает продемонстрировать масштаб self.
Айрин
2
В более поздней версии PHP self::staticMethod();также не будет работать. Это бросит строгую стандартную ошибку.
В этом случае мы можем создать объект того же класса и вызвать объект
Вы можете сделать это, хотя, если fun1не используете self, не логично делать это методом экземпляра. Правильный способ сделать это в PHP, чтобы объявить public static function fun1, а затем вызвать, указав класс: Foo::fun1. Я уверен, что это намеченный способ исправить эту строгую стандартную ошибку.
self
против$this
): stackoverflow.com/questions/151969/php-self-vs-thisОтветы:
Подробнее о ключевом слове Static.
источник
$this
существует , только если объект был создан, и вы можете использовать только$this->method
из существующего объекта. Если у вас нет объекта, но вы просто вызываете статический метод, и в этом методе вы хотите вызвать другой статический метод в том же классе, вы должны использоватьself::
. Поэтому, чтобы избежать потенциальных ошибок (и строгих предупреждений), лучше использоватьself
.$this
, но проблема не возникала до тех пор, пока код не был переданstage
. ошибок не возвращалось, значение было просто0
. будьте осторожны с этим, используйтеself::
Давайте предположим, что это ваш класс:
Из
foo()
метода, давайте посмотрим на различные варианты:Так что это вызывает
staticMethod()
как метод экземпляра, верно? Это не. Это потому, что метод объявлен какpublic static
интерпретатор, будет вызывать его как статический метод, поэтому он будет работать как положено. Можно утверждать, что это делает из кода менее очевидным, что происходит статический вызов метода.Начиная с PHP 5.3 вы можете использовать,
$var::method()
чтобы означать<class-of-$var>::
; это довольно удобно, хотя приведенный выше вариант использования все еще довольно нетрадиционен. Итак, это приводит нас к наиболее распространенному способу вызова статического метода:Теперь, прежде чем вы начинаете думать , что
::
это оператор статического вызова, позвольте мне дать вам еще один пример:Это напечатает
baz = 1
, что означает, что$this->bar()
иself::bar()
делать то же самое; это потому, что::
это просто оператор разрешения области видимости. Это там , чтобы сделатьparent::
,self::
иstatic::
работу , и вы получите доступ к статическим переменным; способ вызова метода зависит от его сигнатуры и способа вызова.Чтобы увидеть все это в действии, посмотрите этот вывод 3v4l.org .
источник
self::bar()
кажется вводящим в заблуждение - это теперь осуждается? (используетсяself::
для вызова метода экземпляра, а не статического метода).self
при вызове статического метода. По определению: статический метод вызывается из любого места и не получает параметр «self». Тем не менее, я вижу удобство этогоphp
синтаксиса, так что вам не нужно писатьMyClassName::
. Я привык к языкам со статической типизацией, где компилятору должны быть указаны все переменные, доступные в текущей области видимости, поэтому (эквивалент)self::
может быть опущен. Так сказал только одинself instanceMethod
; нет причин говоритьself staticMethod
.Это очень поздний ответ, но он добавляет некоторые детали к предыдущим ответам
Когда речь идет о вызове статических методов в PHP из другого статического метода в том же классе, важно различать
self
имя класса.Возьмите для примера этот код:
Выход этого кода:
Это потому, что
self
относится к классу, в котором находится код, а не к классу кода, из которого он вызывается.Если вы хотите использовать метод, определенный в классе, который наследует исходный класс, вам нужно использовать что-то вроде:
источник
self::
происходит в (редком) случае, когда статический метод A вызывает другой статический метод B, а B был переопределен в подклассе. ИМХО, менее запутанно ограничивать переопределение метода методами «экземпляра»; используйте эту способность экономно на статическом уровне. Другими словами, читатели вашего кода ожидают переопределения методов экземпляров (что является сущностью ОО-кодирования), но не статических.self
что в этом случае оно не будет использовано. Вы объявили отдельный класс как расширение первого класса. Использованиеself
в расширенном классе будет ссылаться на расширенный класс. Это не противоречит другим ответам, но, безусловно, помогает продемонстрировать масштабself
.В более поздней версии PHP
self::staticMethod();
также не будет работать. Это бросит строгую стандартную ошибку.В этом случае мы можем создать объект того же класса и вызвать объект
вот пример
источник
fun1
не используетеself
, не логично делать это методом экземпляра. Правильный способ сделать это в PHP, чтобы объявитьpublic static function fun1
, а затем вызвать, указав класс:Foo::fun1
. Я уверен, что это намеченный способ исправить эту строгую стандартную ошибку.