Я собираюсь спросить, в чем разница между: продолжение A; $ this-> A и self :: A
timmz
Ответы:
1728
Короткий ответ
Используйте $thisдля ссылки на текущий объект. Используйте selfдля ссылки на текущий класс. Другими словами, используйте
$this->memberдля нестатических элементов, используйте self::$memberдля статических элементов.
Полный ответ
Вот пример правильного использования $thisи selfдля нестатических и статических переменных-членов:
<?php
class X {private $non_static_member =1;privatestatic $static_member =2;function __construct(){
echo $this->non_static_member .' '.self::$static_member;}}new X();?>
Вот пример неправильного использования $thisи selfдля нестатических и статических переменных-членов:
<?php
class X {private $non_static_member =1;privatestatic $static_member =2;function __construct(){
echo self::$non_static_member .' '. $this->static_member;}}new X();?>
Вот пример полиморфизма с $thisдля функций-членов:
<?php
class X {function foo(){
echo 'X::foo()';}function bar(){
$this->foo();}}class Y extends X {function foo(){
echo 'Y::foo()';}}
$x =new Y();
$x->bar();?>
Вот пример подавления полиморфного поведения с помощью selfфункций-членов:
<?php
class X {function foo(){
echo 'X::foo()';}function bar(){self::foo();}}class Y extends X {function foo(){
echo 'Y::foo()';}}
$x =new Y();
$x->bar();?>
Идея состоит в том, чтобы $this->foo()вызывать foo()функцию-член любого типа, который является точным типом текущего объекта. Если объект имеет type X, он таким образом вызывает X::foo(). Если объект имеет type Y, он вызывает Y::foo(). Но с self :: foo () X::foo()всегда вызывается.
Этот ответ слишком упрощен. Как указано в других ответах, selfиспользуется с оператором разрешения контекста ::для ссылки на текущий класс; это можно сделать как в статическом, так и в нестатическом контексте. Кроме того, совершенно законно использовать $thisдля вызова статических методов (но не для ссылки на поля).
Артефакт
50
Также рассмотрите возможность использования static :: вместо :: self, если вы используете 5.3+. В противном случае это может вызвать невыразимые головные боли, см. Мой ответ ниже, почему.
Sqoo
25
-1. Этот ответ вводит в заблуждение, прочитайте другие ответы для получения дополнительной информации.
Pacerier
6
Это может быть чрезмерно упрощено, но оно ответило на мой основной вопрос уровня, не заставляя мою голову взорваться. Я получил дополнительную информацию, которая мне показалась полезной в дальнейшем, но сейчас я просто пытался выяснить, почему я ударил свои атрибуты класса с помощью $ this-> attrib, а константы класса с помощью self :: constant. Это помогло мне понять это лучше
MydKnight
Как насчет $this::?
Джеймс
742
Ключевое слово self НЕ относится только к «текущему классу», по крайней мере не таким образом, чтобы ограничивать вас статическими членами. В контексте нестатического члена selfтакже предоставляет способ обхода vtable ( см. Wiki по vtable ) для текущего объекта. Точно так же, как вы можете использовать parent::methodName()для вызова родительской версии функции, вы также можете вызвать, self::methodName()чтобы вызвать текущую классовую реализацию метода.
Здравствуйте, я Людвиг гик
Прощай, Людвиг, человек
sayHello()использует $thisуказатель, поэтому vtable вызывается для вызова Geek::getTitle().
sayGoodbye()использует self::getTitle(), поэтому vtable не используется и Person::getTitle()называется. В обоих случаях мы имеем дело с методом экземпляра объекта и имеем доступ к $thisуказателю в вызываемых функциях.
Этот ответ будет еще лучше, если вы начнете с общего правила, а не с исключением. Это вопрос стиля, а не технических знаний. Это лучший пример, который я когда-либо видел, о разнице между self :: и $ this->, но стыдно скрывать это, опровергая сначала понятие.
апреля
3
@adjwilli: Почему этот плохой стиль? Разве это не поднимает сознание, если ожидание (тезис) ОП сначала отклоняется (антитезис), а затем объяснение дается как обобщение?
Хакре
1
Я нахожу «текущий класс» действительно проблематичным. Поскольку это словосочетание может пониматься как «класс, в котором selfнаходится» / «определение класса, которое является буквальной частью», так и «класс объекта» (который фактически будет static).
Якуми
Как насчет $this::?
Джеймс
1
@James - нет веских причин для использования $this::; все возможные случаи уже охвачены более часто используемыми синтаксисами. В зависимости от того, что вы имеете в виду, использование $this->, self::или static::.
ToolmakerSteve
460
НЕ ИСПОЛЬЗУЙТЕ self::, используйтеstatic::
Есть еще один аспект самости, который стоит упомянуть. Раздражающе self::относится к области действия в точке определения, а не в точке исполнения . Рассмотрим этот простой класс с двумя методами:
classPerson{publicstaticfunction status(){self::getStatus();}protectedstaticfunction getStatus(){
echo "Person is alive";}}
Если мы позвоним, Person::status()то увидим «Человек жив». Теперь рассмотрим, что происходит, когда мы создаем класс, который наследуется от этого:
classDeceasedextendsPerson{protectedstaticfunction getStatus(){
echo "Person is deceased";}}
Вызов, который Deceased::status()мы ожидаем увидеть «Человек умер», однако мы видим «Человек жив», так как область действия содержит первоначальное определение метода, когда self::getStatus()был определен вызов .
PHP 5.3 имеет решение. то static::оператор реализует разрешение « в конце статической привязки» , который представляет собой причудливый способ сказать , что это связано с областью класса называется. Измените строку status()на static::getStatus()и вы получите ожидаемые результаты. В более старых версиях PHP вам нужно будет найти ключ для этого.
«Вызываем умершего :: status () мы ожидаем увидеть« Человек умер »». Нет. Это статический вызов функции, поэтому здесь нет полиморфизма.
cquezel
2
Из всех недостатков PHP, я не думаю, что это вообще безумие. Как еще они позволят кодировщикам определять методы в текущем классе (в отличие от поиска их в виртуальной таблице)? Если бы они назвали его по-другому (возможно, с подчеркиванием), то люди, которые хотят эту функцию, будут критиковать ее за уродство. Иначе, какое бы здравомыслящее имя они ни использовали, оно, похоже, всегда будет легко запутывать людей, которые будут критиковать его за «безумное» поведение, вероятно, не обращая внимания на то, как диспетчеризация метода даже работает.
TNE
2
Мне кажется, что этот пример сбивает с толку: я вижу getStatusметод, который я бы назвал для экземпляра класса, а не для класса.
Янис Элмерис
1
@Sqoo - странно сказать, что «НЕ ИСПОЛЬЗОВАТЬ self ::, используйте static ::» - это намеренно не та же самая операция. Я думаю, что вы на самом деле делаете следующее: «яснее, если вы используете фактическое имя класса« MyClass :: », а не« self :: » . То есть, если вам нужно поведение self::, вы можете получить это, меньше смешения, используя определенное имя класса, например MyClass::.
ToolmakerSteve
248
Чтобы по-настоящему понять, о чем мы говорим, когда говорим « selfпротив» $this, нам нужно действительно разобраться в том, что происходит на концептуальном и практическом уровне. Я не чувствую, что какой-либо из ответов делает это соответствующим образом, вот моя попытка.
Давайте начнем с разговора о том, что такое класс и объект .
Классы и объекты, концептуально
Итак, что это класс ? Многие люди определяют его как проект или шаблон для объекта. На самом деле, вы можете прочитать больше о классах в PHP здесь . И в какой-то степени это то, что есть на самом деле. Давайте посмотрим на класс:
Как вы можете заметить, в этом классе есть свойство, которое вызывается, и вызывается $nameметод (функция) sayHello().
Это очень важно отметить , что класс является статической структурой. Это означает, что Personкогда-то определенный класс всегда одинаков везде, где вы на него смотрите.
С другой стороны, объект - это то, что называется экземпляром класса. Это означает, что мы берем «план» класса и используем его для создания динамической копии. Эта копия теперь специально привязана к переменной, в которой она хранится. Поэтому любые изменения экземпляра являются локальными для этого экземпляра.
$bob =newPerson;
$adam =newPerson;
$bob->name ='Bob';
echo $adam->name;// "my name"
Мы создаем новые экземпляры класса, используя newоператор.
Поэтому мы говорим, что класс - это глобальная структура, а объект - локальная структура. Не беспокойтесь об этом забавном ->синтаксисе, мы немного углубимся в это.
Еще одна вещь, о которой мы должны поговорить, это то, что мы можем проверить , является ли экземпляр instanceofконкретным классом: $bob instanceof Personкоторый возвращает логическое значение, если $bobэкземпляр был создан с использованием Personкласса или потомка Person.
Определение состояния
Итак, давайте немного углубимся в то, что на самом деле содержит класс. Есть 5 типов «вещей», которые содержит класс:
Свойства - Думайте о них как о переменных, которые будет содержать каждый экземпляр.
classFoo{public $bar =1;}
Статические свойства - Думайте о них как о переменных, которые используются на уровне класса. Это означает, что они никогда не копируются каждым экземпляром.
classFoo{publicstatic $bar =1;}
Методы - это функции, которые каждый экземпляр будет содержать (и работать с экземплярами).
classFoo{publicfunction bar(){}}
Статические методы - это функции, которые являются общими для всего класса. Они работают не с экземплярами, а только со статическими свойствами.
classFoo{publicstaticfunction bar(){}}
Константы - класс разрешенных констант. Здесь не буду углубляться, но добавлю для полноты:
classFoo{const BAR =1;}
Таким образом, в основном, мы храним информацию о классе и контейнере объекта, используя «подсказки» о статических данных, которые определяют, является ли информация общей (и, следовательно, статической) или нет (и, следовательно, динамической).
Состояние и методы
Внутри метода экземпляр объекта представлен $thisпеременной. Текущее состояние этого объекта есть, и изменение (изменение) любого свойства приведет к изменению этого экземпляра (но не других).
Если метод вызывается статически, $thisпеременная не определена . Это потому, что нет никакого экземпляра, связанного со статическим вызовом.
Здесь интересно то, как выполняются статические звонки. Итак, давайте поговорим о том, как мы получаем доступ к состоянию:
Доступ к государству
Теперь, когда мы сохранили это состояние, нам нужно получить к нему доступ. Это может получить немного сложнее (или путь больше , чем немного), так что давайте разделить это на двух точек зрения: с внешней стороны экземпляра / класса (скажем , от обычного вызова функции или глобальной области видимости), так и внутри экземпляра / класс (изнутри метода объекта).
Снаружи экземпляра / класса
Снаружи экземпляра / класса наши правила довольно просты и предсказуемы. У нас есть два оператора, и каждый немедленно сообщает нам, имеем ли мы дело с экземпляром или классом static:
->- object-operator - всегда используется при доступе к экземпляру.
$bob =newPerson;
echo $bob->name;
Важно отметить, что вызов Person->fooне имеет смысла (поскольку Personэто класс, а не экземпляр). Следовательно, это ошибка разбора.
::- scope-resolution-operator - всегда используется для доступа к статическому свойству или методу Class.
echo Foo::bar()
Кроме того, мы можем вызвать статический метод для объекта таким же образом:
echo $foo::bar()
Это чрезвычайно важно отметить , что , когда мы делаем это снаружи , экземпляр объекта скрыт от bar()метода. Это означает, что это то же самое, что и бег:
$class = get_class($foo);
$class::bar();
Поэтому $thisне определяется в статическом вызове.
Изнутри экземпляра / класса
Здесь все немного меняется. Используются те же операторы, но их значение становится значительно размытым.
Объект-оператор-> по - прежнему используется для выполнения вызовов в состояние экземпляра объекта.
Вызов Foo::bar()будет вызывать baz()метод статически и, следовательно $this, не будет заполнен. Стоит отметить, что в последних версиях PHP (5.3+) это вызовет E_STRICTошибку, потому что мы вызываем нестатические методы статически.
В контексте экземпляра
С другой стороны, в контексте экземпляра вызовы, выполняемые с использованием, ::зависят от получателя вызова (метода, который мы вызываем). Если метод определен как static, то он будет использовать статический вызов. Если это не так, он перешлет информацию об экземпляре.
Итак, глядя на приведенный выше код, вызов $foo->bar()вернется true, поскольку «статический» вызов происходит внутри контекста экземпляра.
Есть смысл? Я так не думал. Это сбивает с толку.
Сокращенные Ключевые слова
Поскольку связывать все вместе, используя имена классов, довольно грязно, PHP предоставляет 3 основных «горячих» ключевых слова, чтобы облегчить определение области видимости.
self- Это относится к текущему имени класса. Так self::baz()же, как и Foo::baz()внутри Fooкласса (любой метод на нем).
parent - Это относится к родителю текущего класса.
static- Это относится к названному классу. Благодаря наследованию дочерние классы могут переопределять методы и статические свойства. Поэтому вызов их с использованием staticвместо имени класса позволяет нам определить источник вызова, а не текущий уровень.
Примеры
Самый простой способ понять это - начать смотреть на некоторые примеры. Давайте выберем класс:
Теперь мы также смотрим на наследование здесь. На мгновение проигнорируйте, что это плохая объектная модель, но давайте посмотрим, что происходит, когда мы играем с этим:
Таким образом, счетчик идентификаторов является общим для обоих экземпляров и дочерних элементов (потому что мы используем selfдля доступа к нему. Если бы мы использовали static, мы могли бы переопределить его в дочернем классе).
var_dump($bob->getName());// Bob
var_dump($adam->getName());// Adam
var_dump($billy->getName());// child: Billy
Обратите внимание, что мы выполняем метод Person::getName()экземпляра каждый раз. Но мы используем это, parent::getName()чтобы сделать это в одном из случаев (дочерний случай). Это то, что делает этот подход мощным.
Слово предостережения № 1
Обратите внимание, что вызывающий контекст определяет, используется ли экземпляр. Следовательно:
Теперь это действительно странно здесь. Мы вызываем другой класс, но экземпляр, $thisкоторый передается Foo::isFoo()методу, является экземпляром класса $bar.
Это может вызвать всевозможные ошибки и концептуальные WTF-еры. Поэтому я настоятельно рекомендую избегать ::оператора внутри методов экземпляра на что - либо , кроме этих трех виртуальных «укороченных» ключевых слов ( static, selfи parent).
Слово предостережения № 2
Обратите внимание, что статические методы и свойства доступны всем. Это делает их в основном глобальными переменными. С такими же проблемами, которые идут с глобалами. Так что я бы не решался хранить информацию в статических методах / свойствах, если вы не уверены, что она действительно глобальная.
Слово предостережения № 3
В общем, вы захотите использовать то, что известно как Late-Static-Binding, используя staticвместо self. Но обратите внимание, что это не одно и то же, поэтому выражение «всегда использовать staticвместо selfдействительно недальновидно». Вместо этого остановитесь и подумайте о вызове, который вы хотите сделать, и подумайте, хотите ли вы, чтобы дочерние классы могли переопределять это статическое разрешение. вызов.
TL / DR
Жаль, вернись и прочитай это. Это может быть слишком долго, но это так долго, потому что это сложная тема
TL / DR # 2
Хорошо. Короче говоря, selfиспользуется для ссылки на текущее имя класса внутри класса, где as $thisссылается на текущий экземпляр объекта . Обратите внимание, что selfэто ярлык копирования / вставки. Вы можете смело заменить его своим именем класса, и оно будет работать нормально. Но $thisэто динамическая переменная, которая не может быть определена заранее (и может даже не быть вашим классом).
TL / DR # 3
Если используется объект-оператор ( ->), то вы всегда знаете, что имеете дело с экземпляром. Если используется оператор scope-resolution-operator ( ::), вам нужно больше информации о контексте (мы уже в объект-контексте? Мы вне объекта? И т. Д.).
Слово предостережения № 1: $ это не будет определено при вызове статического метода: 3v4l.org/9kr0e
Марк Аше
Ну ... $thisне будет определено, если вы следуете "Строгим Стандартам" и не вызываете методы статически, которые не определены как статические. Я вижу результат, который вы объяснили здесь: 3v4l.org/WeHVM Согласен, действительно странно.
Марк Ачи
2
Полностью прочитав длинное описание, я почувствовал себя ленивым, чтобы прокрутить вверх снова, чтобы выразить его. Просто пошутил, я это высказал: D. Спасибо, это очень полезно.
Mr_Green
3
было бы неплохо добавить четкое объяснение разницы между self :: $ property и self :: property; Я думаю, что это тоже довольно запутанно
Томмазо Барбугли
1
WoC # 1 ведет себя иначе, чем PHP 7. Как Foo::isFoo()называется статически, $thisне будет определен. Это более интуитивное поведение на мой взгляд. - Другой другой результат дается, если Barбы продлить с Foo. Тогда вызов Foo::isFoo()будет на самом деле в контексте экземпляра (не специфично для PHP7).
Kontrollfreak
117
self(не $ self) относится к типу класса, где as $thisотносится к текущему экземпляру класса. selfпредназначен для использования в статических функциях-членах, чтобы позволить вам получить доступ к статическим переменным-членам. $thisиспользуется в нестатических функциях-членах и является ссылкой на экземпляр класса, для которого была вызвана функция-член.
Поскольку thisэто объект, вы используете его как:$this->member
Поскольку selfэто не объект, это в основном тип, который автоматически ссылается на текущий класс, вы используете его следующим образом:self::member
$this-> используется для ссылки на конкретный экземпляр переменных класса (переменных-членов) или методов.
Example:
$derek =newPerson();
$ derek теперь является конкретным экземпляром Person. У каждого персонажа есть имя и фамилия, но у $ derek есть конкретные имя и фамилия (Дерек Мартин). Внутри экземпляра $ derek мы можем ссылаться на них как $ this-> first_name и $ this-> last_name
ClassName :: используется для ссылки на этот тип класса и его статические переменные, статические методы. Если это поможет, вы можете мысленно заменить слово «статический» на «общий». Поскольку они являются общими, они не могут ссылаться на $ this, что относится к конкретному экземпляру (не общему). Статические переменные (то есть static $ db_connection) могут быть общими для всех экземпляров типа объекта. Например, все объекты базы данных совместно используют одно соединение (статическое соединение $).
Пример статических переменных: представьте,
что у нас есть класс базы данных с одной переменной-членом: static $ num_connections; Теперь поместите это в конструктор:
function __construct(){if(!isset $num_connections || $num_connections==null){
$num_connections=0;}else{
$num_connections++;}}
Так же, как объекты имеют конструкторы, они также имеют деструкторы, которые выполняются, когда объект умирает или не устанавливается:
function __destruct(){
$num_connections--;}
Каждый раз, когда мы создаем новый экземпляр, он увеличивает счетчик подключений на единицу. Каждый раз, когда мы уничтожаем или прекращаем использовать экземпляр, он уменьшает счетчик соединений на единицу. Таким образом, мы можем отслеживать количество экземпляров объекта базы данных, с которым мы используем:
echo DB::num_connections;
Поскольку $ num_connections является статическим (общим), оно будет отражать общее количество активных объектов базы данных. Возможно, вы видели этот метод, используемый для совместного использования соединений с базой данных среди всех экземпляров класса базы данных. Это сделано потому, что создание соединения с базой данных занимает много времени, поэтому лучше всего создать только одно и поделиться им (это называется Singleton Pattern).
Статические методы (т. Е. Открытый статический View :: format_phone_number ($ digits)) могут использоваться БЕЗ первого создания экземпляра одного из этих объектов (т. Е. Они внутренне не ссылаются на $ this).
Как видите, публичная статическая функция prettyName ничего не знает об объекте. Он просто работает с параметрами, которые вы передаете, как обычная функция, которая не является частью объекта. Зачем тогда беспокоиться, если бы мы могли иметь это не как часть объекта?
Во-первых, прикрепление функций к объектам помогает вам упорядочить вещи, чтобы вы знали, где их найти.
Во-вторых, это предотвращает конфликты имен. В большом проекте у вас, скорее всего, есть два разработчика, создающих функции getName (). Если один создает ClassName1 :: getName (), а другой создает ClassName2 :: getName (), это не проблема. Нет конфликта Yay статические методы!
SELF ::
Если вы кодируете вне объекта, у которого есть статический метод, на который вы хотите сослаться, вы должны вызвать его, используя имя объекта View :: format_phone_number ($ phone_number); Если вы кодирование внутри объекта , который имеет статический метод , который вы хотите обратиться, вы можете либо использовать имя View :: format_phone_number объекта ($ Pn), или вы можете использовать автоматический :: format_phone_number ($ Pn) ярлык
То же самое касается статических переменных:
Пример: View :: templates_path и self :: templates_path
Внутри класса DB, если бы мы ссылались на статический метод какого-либо другого объекта, мы бы использовали имя объекта:
Пример: Session :: getUsersOnline ();
Но если бы класс DB хотел ссылаться на свою статическую переменную, он просто сказал бы: Self:
Example: self :: connection;
В PHP вы используете ключевое слово self для доступа к статическим свойствам и методам.
Проблема в том, что вы можете заменить $this->method()на что self::method()угодно, независимо от того method(), объявлено ли оно статическим или нет. Так какой из них вы должны использовать?
Рассмотрим этот код:
classParentClass{function test(){self::who();// will output 'parent'
$this->who();// will output 'child'}function who(){
echo 'parent';}}classChildClassextendsParentClass{function who(){
echo 'child';}}
$obj =newChildClass();
$obj->test();
В этом примере self::who()всегда будет выводиться «parent», в то время как $this->who()будет зависеть от того, какой класс имеет объект.
Теперь мы можем видеть, что self ссылается на класс, в котором он вызывается, а $thisссылается на класс текущего объекта .
Таким образом, вы должны использовать self только тогда, когда $thisон недоступен или когда вы не хотите, чтобы классы-потомки перезаписывали текущий метод.
По данным http://www.php.net/manual/en/language.oop5.static.php нет $self. Существует только $thisдля ссылки на текущий экземпляр класса (объект) и self, которые можно использовать для ссылки на статические члены класса. Различие между экземпляром объекта и классом вступает здесь в игру.
Предложение: Прочтите этот ответ, когда спотыкаетесь о кислоту.
а20
16
Я считаю, что вопрос был не в том, можно ли вызвать статический член класса, позвонив ClassName::staticMember. Вопрос был в чем разница между использованием self::classmemberи $this->classmember.
Например, оба следующих примера работают без ошибок, используете ли вы self::или$this->
Особенно забавно, что вы начинаете свой ответ с «Я полагаю, вопрос был не в том, можете ли вы вызвать статический член класса, вызвав ClassName :: staticMember. Вопрос был в том, в чем разница между использованием self :: classmember и $ this-> classmember» и затем вы продолжаете показывать никаких различий вообще. Фактически, вы показываете пример, в котором две опции работают одинаково. -1
Баттл Буткус
Тем не менее полезно. Сфера была о разрешении, и эта часть не ясна в руководстве по PHP. Я все еще нахожу это полезным
renoirb
2
Fatal error: Access to undeclared static property: Person::$name in D:\LAMP\www\test.php on line 16
K-Gun
16
self ссылается на текущий класс (в котором он называется),
$thisссылается на текущий объект. Вы можете использовать статические вместо себя. Смотрите пример:
Указатель $thisна объект ссылается на текущий объект.
Значение класса staticотносится к текущему объекту.
Значение класса selfотносится к точному классу, в котором оно было определено.
Значение класса parentотносится к родителю того класса, в котором он был определен.
Смотрите следующий пример, который показывает перегрузку.
<?php
class A {publicstaticfunction newStaticClass(){returnnewstatic;}publicstaticfunction newSelfClass(){returnnewself;}publicfunction newThisClass(){returnnew $this;}}class B extends A
{publicfunction newParentClass(){returnnew parent;}}
$b =new B;
var_dump($b::newStaticClass());// B
var_dump($b::newSelfClass());// A because self belongs to "A"
var_dump($b->newThisClass());// B
var_dump($b->newParentClass());// Aclass C extends B
{publicstaticfunction newSelfClass(){returnnewself;}}
$c =new C;
var_dump($c::newStaticClass());// C
var_dump($c::newSelfClass());// C because self now points to "C" class
var_dump($c->newThisClass());// C
var_dump($b->newParentClass());// A because parent was defined *way back* in class "B"
Большую часть времени вы хотите сослаться на текущий класс, поэтому вы используете staticили $this. Однако бывают случаи, когда вам нужно,self потому что вы хотите оригинальный класс, независимо от того, что его расширяет. (Очень, очень редко)
Это результаты для 2 000 000 прогонов, и вот код, который я использовал:
<?php
require'../vendor/autoload.php';// My small class to do benchmarks// All it does is looping over every test x times and record the// time it takes using `microtime(true)`// Then, the percentage is calculated, with 100% being the quickest// Times are being rouned for outputting only, not to calculate the percentages
$b =newTleb\Benchmark\Benchmark(2000000);classFoo{publicfunction calling_this(){
$this->called();}publicfunction calling_self(){self::called();}publicfunction calling_static(){static::called();}publicstaticfunction called(){}}
$b->add('$this->',function(){ $foo =newFoo; $foo->calling_this();});
$b->add('self::',function(){ $foo =newFoo; $foo->calling_self();});
$b->add('static::',function(){ $foo =newFoo; $foo->calling_static();});
$b->run();
Вызов функции no-op 2 000 000 раз длится 1 с. Должен любить PHP.
rr-
Старый добрый PHP. :) Но звонок = 0,001мс. Это так плохо?
tleb
Я полагаю, что это (и подобные вещи) является причиной того, что такие вещи, как ORM, чувствуют себя медленно, если вы не кешируете вещи, а генераторы статических сайтов - вещь.
rr-
2
Теоретически он должен занимать 1 тактовый такт процессора, что составляет примерно 1 / 2e9 s = 0.5 nsэти дни
Buddy
Просто перечитайте мой ответ. Будьте осторожны: он тоже создает класс . Я не знаю, почему я не использовал useключевое слово tbh, но у меня больше нет PHP, чтобы повторить тест, и я не очень хочу переустанавливать его.
tleb
13
Когда selfиспользуется с ::оператором, он ссылается на текущий класс, что может быть сделано как в статическом, так и в нестатическом контексте. $thisотносится к самому объекту. Кроме того, совершенно законно использовать $thisдля вызова статических методов (но не для ссылки на поля).
Всякий раз, когда вы используете статические методы или статические атрибуты и хотите вызывать их без создания экземпляра объекта класса, вам нужно использовать их self:для вызова, потому что $thisвсегда требуется создание объекта.
$thisссылается на текущий объект класса, selfссылается на текущий класс (не объект). Класс - это план объекта. Итак, вы определяете класс, но вы создаете объекты.
Другими словами, используйте self for staticи this for none-static members or methods.
также в дочернем / родительском сценарии self / parentчаще всего используются идентифицированные дочерние и родительские классные члены и методы.
Только в информационных целях, начиная с PHP 5.3, когда имеешь дело с экземплярами объектов, чтобы получить текущее значение области, в отличие от использования static::, можно альтернативно использовать $this::подобное.
classFoo{const NAME ='Foo';//Always Foo::NAME (Foo) due to selfprotectedstatic $staticName =self::NAME;publicfunction __construct(){
echo $this::NAME;}publicfunction getStaticName(){
echo $this::$staticName;}}classBarextendsFoo{const NAME ='FooBar';/**
* override getStaticName to output Bar::NAME
*/publicfunction getStaticName(){
$this::$staticName = $this::NAME;
parent::getStaticName();}}
$foo =newFoo;//outputs Foo
$bar =newBar;//outputs FooBar
$foo->getStaticName();//outputs Foo
$bar->getStaticName();//outputs FooBar
$foo->getStaticName();//outputs FooBar
Использование приведенного выше кода не является общепринятой или рекомендуемой практикой, а просто иллюстрирует его использование и действует как «Знаете ли вы?» со ссылкой на оригинальный вопрос автора.
Это также представляет использование, $object::CONSTANTнапример, echo $foo::NAME;в отличие от$this::NAME;
Используйте, selfесли вы хотите вызвать метод класса без создания объекта / экземпляра этого класса, тем самым экономя ОЗУ (иногда для этой цели используйте self). Другими словами, это фактически вызывает метод статически. Используйте thisдля перспективы объекта.
По php.net есть три специальные ключевые слова в данном контексте: self, parentи static. Они используются для доступа к свойствам или методам из определения класса.
$thisс другой стороны, используется для вызова экземпляра и методов любого класса, если этот класс доступен.
self :: keyword используется для текущего класса и в основном используется для доступа к статическим членам, методам и константам. Но в случае $ this вы не можете вызывать статический член, метод и функции.
Вы можете использовать ключевое слово self :: в другом классе и получать доступ к статическим членам, методам и константам. Когда это будет продолжаться от родительского класса и то же самое в случае $ этого ключевого слова. Вы можете получить доступ к нестатическим членам, методам и функциям в другом классе, когда он будет расширяться из родительского класса.
Код, приведенный ниже, является примером self :: и $ this ключевого слова. Просто скопируйте и вставьте код в ваш файл кода и посмотрите результат.
class cars{var $doors=4;static $car_wheel=4;publicfunction car_features(){
echo $this->doors." Doors <br>";
echo self::$car_wheel." Wheels <br>";}}class spec extends cars{function car_spec(){print(self::$car_wheel." Doors <br>");print($this->doors." Wheels <br>");}}/********Parent class output*********/
$car =new cars;
print_r($car->car_features());
echo "------------------------<br>";/********Extend class from another class output**********/
$car_spec_show=new spec;print($car_spec_show->car_spec());
Ответы:
Короткий ответ
Полный ответ
Вот пример правильного использования
$this
иself
для нестатических и статических переменных-членов:Вот пример неправильного использования
$this
иself
для нестатических и статических переменных-членов:Вот пример полиморфизма с
$this
для функций-членов:Вот пример подавления полиморфного поведения с помощью
self
функций-членов:С http://www.phpbuilder.com/board/showthread.php?t=10354489 :
Автор: http://board.phpbuilder.com/member.php?145249-laserlight
источник
self
используется с оператором разрешения контекста::
для ссылки на текущий класс; это можно сделать как в статическом, так и в нестатическом контексте. Кроме того, совершенно законно использовать$this
для вызова статических методов (но не для ссылки на поля).$this::
?Ключевое слово self НЕ относится только к «текущему классу», по крайней мере не таким образом, чтобы ограничивать вас статическими членами. В контексте нестатического члена
self
также предоставляет способ обхода vtable ( см. Wiki по vtable ) для текущего объекта. Точно так же, как вы можете использоватьparent::methodName()
для вызова родительской версии функции, вы также можете вызвать,self::methodName()
чтобы вызвать текущую классовую реализацию метода.Это выведет:
sayHello()
использует$this
указатель, поэтому vtable вызывается для вызоваGeek::getTitle()
.sayGoodbye()
используетself::getTitle()
, поэтому vtable не используется иPerson::getTitle()
называется. В обоих случаях мы имеем дело с методом экземпляра объекта и имеем доступ к$this
указателю в вызываемых функциях.источник
self
находится» / «определение класса, которое является буквальной частью», так и «класс объекта» (который фактически будетstatic
).$this::
?$this::
; все возможные случаи уже охвачены более часто используемыми синтаксисами. В зависимости от того, что вы имеете в виду, использование$this->
,self::
илиstatic::
.НЕ ИСПОЛЬЗУЙТЕ
self::
, используйтеstatic::
Есть еще один аспект самости, который стоит упомянуть. Раздражающе
self::
относится к области действия в точке определения, а не в точке исполнения . Рассмотрим этот простой класс с двумя методами:Если мы позвоним,
Person::status()
то увидим «Человек жив». Теперь рассмотрим, что происходит, когда мы создаем класс, который наследуется от этого:Вызов, который
Deceased::status()
мы ожидаем увидеть «Человек умер», однако мы видим «Человек жив», так как область действия содержит первоначальное определение метода, когдаself::getStatus()
был определен вызов .PHP 5.3 имеет решение. то
static::
оператор реализует разрешение « в конце статической привязки» , который представляет собой причудливый способ сказать , что это связано с областью класса называется. Измените строкуstatus()
наstatic::getStatus()
и вы получите ожидаемые результаты. В более старых версиях PHP вам нужно будет найти ключ для этого.Смотрите PHP документацию
Так что ответить на вопрос не так, как задали ...
$this->
ссылается на текущий объект (экземпляр класса), тогда какstatic::
ссылается на классисточник
getStatus
метод, который я бы назвал для экземпляра класса, а не для класса.self::
, вы можете получить это, меньше смешения, используя определенное имя класса, напримерMyClass::
.Чтобы по-настоящему понять, о чем мы говорим, когда говорим «
self
против»$this
, нам нужно действительно разобраться в том, что происходит на концептуальном и практическом уровне. Я не чувствую, что какой-либо из ответов делает это соответствующим образом, вот моя попытка.Давайте начнем с разговора о том, что такое класс и объект .
Классы и объекты, концептуально
Итак, что это класс ? Многие люди определяют его как проект или шаблон для объекта. На самом деле, вы можете прочитать больше о классах в PHP здесь . И в какой-то степени это то, что есть на самом деле. Давайте посмотрим на класс:
Как вы можете заметить, в этом классе есть свойство, которое вызывается, и вызывается
$name
метод (функция)sayHello()
.Это очень важно отметить , что класс является статической структурой. Это означает, что
Person
когда-то определенный класс всегда одинаков везде, где вы на него смотрите.С другой стороны, объект - это то, что называется экземпляром класса. Это означает, что мы берем «план» класса и используем его для создания динамической копии. Эта копия теперь специально привязана к переменной, в которой она хранится. Поэтому любые изменения экземпляра являются локальными для этого экземпляра.
Мы создаем новые экземпляры класса, используя
new
оператор.Поэтому мы говорим, что класс - это глобальная структура, а объект - локальная структура. Не беспокойтесь об этом забавном
->
синтаксисе, мы немного углубимся в это.Еще одна вещь, о которой мы должны поговорить, это то, что мы можем проверить , является ли экземпляр
instanceof
конкретным классом:$bob instanceof Person
который возвращает логическое значение, если$bob
экземпляр был создан с использованиемPerson
класса или потомкаPerson
.Определение состояния
Итак, давайте немного углубимся в то, что на самом деле содержит класс. Есть 5 типов «вещей», которые содержит класс:
Свойства - Думайте о них как о переменных, которые будет содержать каждый экземпляр.
Статические свойства - Думайте о них как о переменных, которые используются на уровне класса. Это означает, что они никогда не копируются каждым экземпляром.
Методы - это функции, которые каждый экземпляр будет содержать (и работать с экземплярами).
Статические методы - это функции, которые являются общими для всего класса. Они работают не с экземплярами, а только со статическими свойствами.
Константы - класс разрешенных констант. Здесь не буду углубляться, но добавлю для полноты:
Таким образом, в основном, мы храним информацию о классе и контейнере объекта, используя «подсказки» о статических данных, которые определяют, является ли информация общей (и, следовательно, статической) или нет (и, следовательно, динамической).
Состояние и методы
Внутри метода экземпляр объекта представлен
$this
переменной. Текущее состояние этого объекта есть, и изменение (изменение) любого свойства приведет к изменению этого экземпляра (но не других).Если метод вызывается статически,
$this
переменная не определена . Это потому, что нет никакого экземпляра, связанного со статическим вызовом.Здесь интересно то, как выполняются статические звонки. Итак, давайте поговорим о том, как мы получаем доступ к состоянию:
Доступ к государству
Теперь, когда мы сохранили это состояние, нам нужно получить к нему доступ. Это может получить немного сложнее (или путь больше , чем немного), так что давайте разделить это на двух точек зрения: с внешней стороны экземпляра / класса (скажем , от обычного вызова функции или глобальной области видимости), так и внутри экземпляра / класс (изнутри метода объекта).
Снаружи экземпляра / класса
Снаружи экземпляра / класса наши правила довольно просты и предсказуемы. У нас есть два оператора, и каждый немедленно сообщает нам, имеем ли мы дело с экземпляром или классом static:
->
- object-operator - всегда используется при доступе к экземпляру.Важно отметить, что вызов
Person->foo
не имеет смысла (посколькуPerson
это класс, а не экземпляр). Следовательно, это ошибка разбора.::
- scope-resolution-operator - всегда используется для доступа к статическому свойству или методу Class.Кроме того, мы можем вызвать статический метод для объекта таким же образом:
Это чрезвычайно важно отметить , что , когда мы делаем это снаружи , экземпляр объекта скрыт от
bar()
метода. Это означает, что это то же самое, что и бег:Поэтому
$this
не определяется в статическом вызове.Изнутри экземпляра / класса
Здесь все немного меняется. Используются те же операторы, но их значение становится значительно размытым.
Объект-оператор
->
по - прежнему используется для выполнения вызовов в состояние экземпляра объекта.Вызов
bar()
метода$foo
(экземпляраFoo
) с использованием объекта-оператора:$foo->bar()
приведет к версии экземпляра$a
.Так вот как мы ожидаем.
Смысл
::
оператора хоть и меняется. Это зависит от контекста вызова текущей функции:В статическом контексте
В статическом контексте любые вызовы, сделанные с использованием
::
, также будут статическими. Давайте посмотрим на пример:Вызов
Foo::bar()
будет вызыватьbaz()
метод статически и, следовательно$this
, не будет заполнен. Стоит отметить, что в последних версиях PHP (5.3+) это вызоветE_STRICT
ошибку, потому что мы вызываем нестатические методы статически.В контексте экземпляра
С другой стороны, в контексте экземпляра вызовы, выполняемые с использованием,
::
зависят от получателя вызова (метода, который мы вызываем). Если метод определен какstatic
, то он будет использовать статический вызов. Если это не так, он перешлет информацию об экземпляре.Итак, глядя на приведенный выше код, вызов
$foo->bar()
вернетсяtrue
, поскольку «статический» вызов происходит внутри контекста экземпляра.Есть смысл? Я так не думал. Это сбивает с толку.
Сокращенные Ключевые слова
Поскольку связывать все вместе, используя имена классов, довольно грязно, PHP предоставляет 3 основных «горячих» ключевых слова, чтобы облегчить определение области видимости.
self
- Это относится к текущему имени класса. Такself::baz()
же, как иFoo::baz()
внутриFoo
класса (любой метод на нем).parent
- Это относится к родителю текущего класса.static
- Это относится к названному классу. Благодаря наследованию дочерние классы могут переопределять методы и статические свойства. Поэтому вызов их с использованиемstatic
вместо имени класса позволяет нам определить источник вызова, а не текущий уровень.Примеры
Самый простой способ понять это - начать смотреть на некоторые примеры. Давайте выберем класс:
Теперь мы также смотрим на наследование здесь. На мгновение проигнорируйте, что это плохая объектная модель, но давайте посмотрим, что происходит, когда мы играем с этим:
Таким образом, счетчик идентификаторов является общим для обоих экземпляров и дочерних элементов (потому что мы используем
self
для доступа к нему. Если бы мы использовалиstatic
, мы могли бы переопределить его в дочернем классе).Обратите внимание, что мы выполняем метод
Person::getName()
экземпляра каждый раз. Но мы используем это,parent::getName()
чтобы сделать это в одном из случаев (дочерний случай). Это то, что делает этот подход мощным.Слово предостережения № 1
Обратите внимание, что вызывающий контекст определяет, используется ли экземпляр. Следовательно:
Это не всегда так.
Теперь это действительно странно здесь. Мы вызываем другой класс, но экземпляр,
$this
который передаетсяFoo::isFoo()
методу, является экземпляром класса$bar
.Это может вызвать всевозможные ошибки и концептуальные WTF-еры. Поэтому я настоятельно рекомендую избегать
::
оператора внутри методов экземпляра на что - либо , кроме этих трех виртуальных «укороченных» ключевых слов (static
,self
иparent
).Слово предостережения № 2
Обратите внимание, что статические методы и свойства доступны всем. Это делает их в основном глобальными переменными. С такими же проблемами, которые идут с глобалами. Так что я бы не решался хранить информацию в статических методах / свойствах, если вы не уверены, что она действительно глобальная.
Слово предостережения № 3
В общем, вы захотите использовать то, что известно как Late-Static-Binding, используя
static
вместоself
. Но обратите внимание, что это не одно и то же, поэтому выражение «всегда использоватьstatic
вместоself
действительно недальновидно». Вместо этого остановитесь и подумайте о вызове, который вы хотите сделать, и подумайте, хотите ли вы, чтобы дочерние классы могли переопределять это статическое разрешение. вызов.TL / DR
Жаль, вернись и прочитай это. Это может быть слишком долго, но это так долго, потому что это сложная тема
TL / DR # 2
Хорошо. Короче говоря,
self
используется для ссылки на текущее имя класса внутри класса, где as$this
ссылается на текущий экземпляр объекта . Обратите внимание, чтоself
это ярлык копирования / вставки. Вы можете смело заменить его своим именем класса, и оно будет работать нормально. Но$this
это динамическая переменная, которая не может быть определена заранее (и может даже не быть вашим классом).TL / DR # 3
Если используется объект-оператор (
->
), то вы всегда знаете, что имеете дело с экземпляром. Если используется оператор scope-resolution-operator (::
), вам нужно больше информации о контексте (мы уже в объект-контексте? Мы вне объекта? И т. Д.).источник
$this
не будет определено, если вы следуете "Строгим Стандартам" и не вызываете методы статически, которые не определены как статические. Я вижу результат, который вы объяснили здесь: 3v4l.org/WeHVM Согласен, действительно странно.Foo::isFoo()
называется статически,$this
не будет определен. Это более интуитивное поведение на мой взгляд. - Другой другой результат дается, еслиBar
бы продлить сFoo
. Тогда вызовFoo::isFoo()
будет на самом деле в контексте экземпляра (не специфично для PHP7).self
(не $ self) относится к типу класса, где as$this
относится к текущему экземпляру класса.self
предназначен для использования в статических функциях-членах, чтобы позволить вам получить доступ к статическим переменным-членам.$this
используется в нестатических функциях-членах и является ссылкой на экземпляр класса, для которого была вызвана функция-член.Поскольку
this
это объект, вы используете его как:$this->member
Поскольку
self
это не объект, это в основном тип, который автоматически ссылается на текущий класс, вы используете его следующим образом:self::member
источник
$this->
используется для ссылки на конкретный экземпляр переменных класса (переменных-членов) или методов.$ derek теперь является конкретным экземпляром Person. У каждого персонажа есть имя и фамилия, но у $ derek есть конкретные имя и фамилия (Дерек Мартин). Внутри экземпляра $ derek мы можем ссылаться на них как $ this-> first_name и $ this-> last_name
ClassName :: используется для ссылки на этот тип класса и его статические переменные, статические методы. Если это поможет, вы можете мысленно заменить слово «статический» на «общий». Поскольку они являются общими, они не могут ссылаться на $ this, что относится к конкретному экземпляру (не общему). Статические переменные (то есть static $ db_connection) могут быть общими для всех экземпляров типа объекта. Например, все объекты базы данных совместно используют одно соединение (статическое соединение $).
Пример статических переменных: представьте, что у нас есть класс базы данных с одной переменной-членом: static $ num_connections; Теперь поместите это в конструктор:
Так же, как объекты имеют конструкторы, они также имеют деструкторы, которые выполняются, когда объект умирает или не устанавливается:
Каждый раз, когда мы создаем новый экземпляр, он увеличивает счетчик подключений на единицу. Каждый раз, когда мы уничтожаем или прекращаем использовать экземпляр, он уменьшает счетчик соединений на единицу. Таким образом, мы можем отслеживать количество экземпляров объекта базы данных, с которым мы используем:
Поскольку $ num_connections является статическим (общим), оно будет отражать общее количество активных объектов базы данных. Возможно, вы видели этот метод, используемый для совместного использования соединений с базой данных среди всех экземпляров класса базы данных. Это сделано потому, что создание соединения с базой данных занимает много времени, поэтому лучше всего создать только одно и поделиться им (это называется Singleton Pattern).
Статические методы (т. Е. Открытый статический View :: format_phone_number ($ digits)) могут использоваться БЕЗ первого создания экземпляра одного из этих объектов (т. Е. Они внутренне не ссылаются на $ this).
Пример статического метода:
Как видите, публичная статическая функция prettyName ничего не знает об объекте. Он просто работает с параметрами, которые вы передаете, как обычная функция, которая не является частью объекта. Зачем тогда беспокоиться, если бы мы могли иметь это не как часть объекта?
SELF :: Если вы кодируете вне объекта, у которого есть статический метод, на который вы хотите сослаться, вы должны вызвать его, используя имя объекта View :: format_phone_number ($ phone_number); Если вы кодирование внутри объекта , который имеет статический метод , который вы хотите обратиться, вы можете либо использовать имя View :: format_phone_number объекта ($ Pn), или вы можете использовать автоматический :: format_phone_number ($ Pn) ярлык
То же самое касается статических переменных: Пример: View :: templates_path и self :: templates_path
Внутри класса DB, если бы мы ссылались на статический метод какого-либо другого объекта, мы бы использовали имя объекта: Пример: Session :: getUsersOnline ();
Но если бы класс DB хотел ссылаться на свою статическую переменную, он просто сказал бы: Self: Example: self :: connection;
Надеюсь, что это поможет прояснить ситуацию :)
источник
$
знак. Напримерself::$templates_path
Из этого сообщения в блоге :
источник
В PHP вы используете ключевое слово self для доступа к статическим свойствам и методам.
Проблема в том, что вы можете заменить
$this->method()
на чтоself::method()
угодно, независимо от тогоmethod()
, объявлено ли оно статическим или нет. Так какой из них вы должны использовать?Рассмотрим этот код:
В этом примере
self::who()
всегда будет выводиться «parent», в то время как$this->who()
будет зависеть от того, какой класс имеет объект.Теперь мы можем видеть, что self ссылается на класс, в котором он вызывается, а
$this
ссылается на класс текущего объекта .Таким образом, вы должны использовать self только тогда, когда
$this
он недоступен или когда вы не хотите, чтобы классы-потомки перезаписывали текущий метод.источник
Внутри определения класса
$this
ссылается на текущий объект, аself
ссылается на текущий класс.Необходимо ссылаться на элемент класса с помощью
self
и ссылаться на элемент объекта с помощью$this
.источник
источник
По данным http://www.php.net/manual/en/language.oop5.static.php нет
$self
. Существует только$this
для ссылки на текущий экземпляр класса (объект) и self, которые можно использовать для ссылки на статические члены класса. Различие между экземпляром объекта и классом вступает здесь в игру.источник
Я считаю, что вопрос был не в том, можно ли вызвать статический член класса, позвонив
ClassName::staticMember
. Вопрос был в чем разница между использованиемself::classmember
и$this->classmember
.Например, оба следующих примера работают без ошибок, используете ли вы
self::
или$this->
источник
Fatal error: Access to undeclared static property: Person::$name in D:\LAMP\www\test.php on line 16
self
ссылается на текущий класс (в котором он называется),$this
ссылается на текущий объект. Вы можете использовать статические вместо себя. Смотрите пример:Вывод: родительский ребенок
источник
$this
на объект ссылается на текущий объект.static
относится к текущему объекту.self
относится к точному классу, в котором оно было определено.parent
относится к родителю того класса, в котором он был определен.Смотрите следующий пример, который показывает перегрузку.
Большую часть времени вы хотите сослаться на текущий класс, поэтому вы используете
static
или$this
. Однако бывают случаи, когда вам нужно,self
потому что вы хотите оригинальный класс, независимо от того, что его расширяет. (Очень, очень редко)источник
Поскольку никто здесь не говорил о выступлениях, вот небольшой тест, который я сделал (5.6):
Это результаты для 2 000 000 прогонов, и вот код, который я использовал:
источник
1 / 2e9 s = 0.5 ns
эти дниuse
ключевое слово tbh, но у меня больше нет PHP, чтобы повторить тест, и я не очень хочу переустанавливать его.Когда
self
используется с::
оператором, он ссылается на текущий класс, что может быть сделано как в статическом, так и в нестатическом контексте.$this
относится к самому объекту. Кроме того, совершенно законно использовать$this
для вызова статических методов (но не для ссылки на поля).источник
Я столкнулся с тем же вопросом, и простой ответ:
$this
требует экземпляра классаself::
неВсякий раз, когда вы используете статические методы или статические атрибуты и хотите вызывать их без создания экземпляра объекта класса, вам нужно использовать их
self:
для вызова, потому что$this
всегда требуется создание объекта.источник
$this
ссылается на текущий объект класса,self
ссылается на текущий класс (не объект). Класс - это план объекта. Итак, вы определяете класс, но вы создаете объекты.Другими словами, используйте
self for static
иthis for none-static members or methods
.также в дочернем / родительском сценарии
self / parent
чаще всего используются идентифицированные дочерние и родительские классные члены и методы.источник
Кроме того, так как
$this::
еще не обсуждался.Только в информационных целях, начиная с PHP 5.3, когда имеешь дело с экземплярами объектов, чтобы получить текущее значение области, в отличие от использования
static::
, можно альтернативно использовать$this::
подобное.http://ideone.com/7etRHy
Использование приведенного выше кода не является общепринятой или рекомендуемой практикой, а просто иллюстрирует его использование и действует как «Знаете ли вы?» со ссылкой на оригинальный вопрос автора.
Это также представляет использование,
$object::CONSTANT
например,echo $foo::NAME;
в отличие от$this::NAME;
источник
Используйте,
self
если вы хотите вызвать метод класса без создания объекта / экземпляра этого класса, тем самым экономя ОЗУ (иногда для этой цели используйте self). Другими словами, это фактически вызывает метод статически. Используйтеthis
для перспективы объекта.источник
Случай 1: использование
self
может использоваться для констант классаЕсли вы хотите вызвать его вне класса, используйте
classA::POUNDS_TO_KILOGRAMS
для доступа к константамСлучай 2: для статических свойств
источник
По php.net есть три специальные ключевые слова в данном контексте:
self
,parent
иstatic
. Они используются для доступа к свойствам или методам из определения класса.$this
с другой стороны, используется для вызова экземпляра и методов любого класса, если этот класс доступен.источник
self :: keyword используется для текущего класса и в основном используется для доступа к статическим членам, методам и константам. Но в случае $ this вы не можете вызывать статический член, метод и функции.
Вы можете использовать ключевое слово self :: в другом классе и получать доступ к статическим членам, методам и константам. Когда это будет продолжаться от родительского класса и то же самое в случае $ этого ключевого слова. Вы можете получить доступ к нестатическим членам, методам и функциям в другом классе, когда он будет расширяться из родительского класса.
Код, приведенный ниже, является примером self :: и $ this ключевого слова. Просто скопируйте и вставьте код в ваш файл кода и посмотрите результат.
источник