Intereting Posts
Хотите подключиться к серверу iCloud caldav и добавить событие, желательно из PHP Установите lang по умолчанию, используя php переменные, передающие ничего, показывают неопределенную ошибку переменной, поэтому вы хотите поместить значение по умолчанию для переменной Ошибка PHP из памяти, хотя memory_limit не достигнут Как объявить глобальную переменную в PHP, которую я могу использовать во всех шаблонах? Запустите MySQL INSERT Query несколько раз (введите значения в несколько таблиц) Как сохранить постоянный скрипт PHP? Symfony 2.1 Security Sub Subdomain Как получить доступ к определенному значению в смешанном объекте (stdClass) и конструкции массива? Может ли метод redirectToRoute () иметь аргументы вроде render ()? Как использовать файлы cookie в двух разных доменах? Создание предварительного просмотра шрифта Возвращает false при выполнении этого запроса mysql_connect (): расширение mysql устарело и будет удалено в будущем: вместо этого используйте mysqli или PDO Как вставить данные формы из нескольких полей в один столбец таблицы sql

В чем разница между государственным, частным и защищенным?

Когда и почему я должен использовать public , private и protected функции и переменные внутри класса? В чем разница между ними?

Примеры:

 // Public public $variable; public function doSomething() { // ... } // Private private $variable; private function doSomething() { // ... } // Protected protected $variable; protected function doSomething() { // ... } 

Ты используешь:

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

  • если вы хотите, чтобы ваша переменная / функция была видимой только в своем классе.

  • если вы хотите сделать свою переменную / функцию видимой во всех классах, расширяющих текущий класс, включая родительский класс.

Подробнее: (для получения исчерпывающей информации)

dd

Общественность:

Когда вы объявляете метод (функцию) или свойство (переменную) public , к этим методам и свойствам можно обращаться:

  • Тот же класс, который его объявил.
  • Классы, наследующие указанный выше класс.
  • Любые внешние элементы вне этого класса могут также получить доступ к этим вещам.

Пример:

 <?php class GrandPa { public $name='Mark Henry'; // A public variable } class Daddy extends GrandPa // Inherited class { function displayGrandPaName() { return $this->name; // The public variable will be available to the inherited class } } // Inherited class Daddy wants to know Grandpas Name $daddy = new Daddy; echo $daddy->displayGrandPaName(); // Prints 'Mark Henry' // Public variables can also be accessed outside of the class! $outsiderWantstoKnowGrandpasName = new GrandPa; echo $outsiderWantstoKnowGrandpasName->name; // Prints 'Mark Henry' 

Защищено:

Когда вы объявляете метод (функцию) или свойство (переменную) как protected , эти методы и свойства могут быть доступны

  • Тот же класс, который его объявил.
  • Классы, наследующие указанный выше класс.

Члены аутсайдера не могут получить доступ к этим переменным. «Аутсайдеры» в том смысле, что они не являются объектными экземплярами объявленного класса.

Пример:

 <?php class GrandPa { protected $name = 'Mark Henry'; } class Daddy extends GrandPa { function displayGrandPaName() { return $this->name; } } $daddy = new Daddy; echo $daddy->displayGrandPaName(); // Prints 'Mark Henry' $outsiderWantstoKnowGrandpasName = new GrandPa; echo $outsiderWantstoKnowGrandpasName->name; // Results in a Fatal Error 

Точная ошибка будет такова:

PHP Неустранимая ошибка: не удается получить доступ к защищенному свойству GrandPa :: $ name


Частный:

Когда вы объявляете метод (функцию) или свойство (переменную) как private , к этим методам и свойствам можно обращаться:

  • Тот же класс, который его объявил.

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

Пример:

 <?php class GrandPa { private $name = 'Mark Henry'; } class Daddy extends GrandPa { function displayGrandPaName() { return $this->name; } } $daddy = new Daddy; echo $daddy->displayGrandPaName(); // Results in a Notice $outsiderWantstoKnowGrandpasName = new GrandPa; echo $outsiderWantstoKnowGrandpasName->name; // Results in a Fatal Error 

Точные сообщения об ошибках будут:

Примечание. Неопределенное свойство: Daddy :: $ name
Неустранимая ошибка: не удается получить доступ к частной собственности GrandPa :: $ name


Рассеивание класса дедушки с использованием отражения

Этот вопрос не совсем вне поля зрения, и я добавляю его здесь, чтобы доказать, что отражение действительно мощное. Как я уже сказал в приведенных выше трех примерах, protected и private члены (свойства и методы) не могут быть доступны за пределами класса.

Тем не менее, с размышлением вы можете сделать сверхстандартное , даже обращаясь к protected и private членам вне класса!

Ну, что такое отражение?

Reflection добавляет возможность перепроектировать классы, интерфейсы, функции, методы и расширения. Кроме того, они предлагают способы получения комментариев к документам для функций, классов и методов.

преамбула

У нас есть класс под названием Grandpas и говорят, что у нас есть три свойства. Для удобства понимания, есть три дедушки с именами:

  • Марк Генри
  • Джон Клэш
  • Уилл Джонс

Давайте сделаем их (назначим модификаторы) public , protected и private соответственно. Вы очень хорошо знаете, что protected и private члены не могут быть доступны за пределами класса. Теперь давайте противоречим утверждению, используя отражение.

Код

 <?php class GrandPas // The Grandfather's class { public $name1 = 'Mark Henry'; // This grandpa is mapped to a public modifier protected $name2 = 'John Clash'; // This grandpa is mapped to a protected modifier private $name3 = 'Will Jones'; // This grandpa is mapped to a private modifier } # Scenario 1: without reflection $granpaWithoutReflection = new GrandPas; # Normal looping to print all the members of this class echo "#Scenario 1: Without reflection<br>"; echo "Printing members the usual way.. (without reflection)<br>"; foreach($granpaWithoutReflection as $k=>$v) { echo "The name of grandpa is $v and he resides in the variable $k<br>"; } echo "<br>"; #Scenario 2: Using reflection $granpa = new ReflectionClass('GrandPas'); // Pass the Grandpas class as the input for the Reflection class $granpaNames=$granpa->getDefaultProperties(); // Gets all the properties of the Grandpas class (Even though it is a protected or private) echo "#Scenario 2: With reflection<br>"; echo "Printing members the 'reflect' way..<br>"; foreach($granpaNames as $k=>$v) { echo "The name of grandpa is $v and he resides in the variable $k<br>"; } 

Вывод:

 #Scenario 1: Without reflection Printing members the usual way.. (Without reflection) The name of grandpa is Mark Henry and he resides in the variable name1 #Scenario 2: With reflection Printing members the 'reflect' way.. The name of grandpa is Mark Henry and he resides in the variable name1 The name of grandpa is John Clash and he resides in the variable name2 The name of grandpa is Will Jones and he resides in the variable name3 

Общие заблуждения:

Пожалуйста, не путайте приведенный ниже пример. Как вы все еще можете видеть, private и protected члены не могут быть доступны за пределами класса без использования отражения

 <?php class GrandPas // The Grandfather's class { public $name1 = 'Mark Henry'; // This grandpa is mapped to a public modifier protected $name2 = 'John Clash'; // This grandpa is mapped to a protected modifier private $name3 = 'Will Jones'; // This grandpa is mapped to a private modifier } $granpaWithoutReflections = new GrandPas; print_r($granpaWithoutReflections); 

Вывод:

 GrandPas Object ( [name1] => Mark Henry [name2:protected] => John Clash [name3:GrandPas:private] => Will Jones ) 

Функции отладки

print_r , var_export и var_dump – функции отладчика . Они представляют информацию о переменной в удобочитаемой форме. Эти три функции покажут protected и private свойства объектов с PHP 5. Статические члены класса не будут показаны.


Больше ресурсов:

  • Руководство PHP – Свойства ООП
  • Руководство PHP – видимость ООП
  • Techflirt.com – Видимость в PHP-классах
  • Jordizle.com – открытый, закрытый, защищенный в PHP 5
  • Tuxradar.com – Общественный, Частный и Защищенный

Обычно считается хорошей практикой по умолчанию для минимальной видимости, поскольку это способствует инкапсуляции данных и хорошему дизайну интерфейса. При рассмотрении видимости элементов и видимости метода думайте о роли, которую играет член во взаимодействии с другими объектами.

Если вы «кодируете интерфейс, а не реализацию», тогда обычно довольно легко принимать решения о видимости. В общем, переменные должны быть частными или защищенными, если у вас нет веских оснований для их раскрытия. Вместо этого используйте общедоступные средства доступа (getters / seters), чтобы ограничить и регулировать доступ к внутренним классам.

Чтобы использовать автомобиль в качестве аналогии, такие вещи, как скорость, передача и направление, будут частными переменными экземпляра. Вы не хотите, чтобы водитель напрямую манипулировал такими вещами, как соотношение воздух / топливо. Вместо этого вы публикуете ограниченное количество действий в качестве общедоступных методов. Интерфейс к машине может включать такие методы, как accelerate() , deccelerate() / brake() , setGear() , turnLeft() , turnRight() и т. Д.

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

Этот подход также позволяет вам изменять и улучшать реализацию общедоступных методов в вашем классе, не нарушая контракт с клиентским кодом. Например, вы можете улучшить метод accelerate() чтобы быть более экономичным, но использование этого метода останется прежним; клиентский код не потребует никаких изменений, но по-прежнему пользуется преимуществами повышения эффективности.

Редактирование: поскольку кажется, что вы все еще находите в центре изучения объектно-ориентированных концепций (которые намного сложнее освоить, чем синтаксис любого языка), я настоятельно рекомендую собрать экземпляр объектов PHP, шаблонов и практики Matt Zandstra. Это книга, которая впервые научила меня эффективно использовать ООП, а не просто преподавать мне синтаксис. Я узнал синтаксис за несколько лет раньше, но это бесполезно, не понимая «почему» ООП.

private – может быть доступен только из класса ININ

protected – можно получить доступ из класса WITHIN и INHERITING

public – может быть доступен из кода OUTSIDE класса

Это относится как к функциям, так и к переменным.

Разница заключается в следующем:

Public :: Доступ к открытой переменной или методу может получить любой пользователь этого класса.

Protected :: Защищенная переменная или метод не могут быть доступны пользователям класса, но могут быть доступны внутри подкласса, который наследуется от класса.

Private . Частная переменная или метод могут быть доступны только внутри класса, в котором он определен. Это означает, что частную переменную или метод нельзя вызывать из дочернего объекта, который расширяет класс.

Области видимости с абстрактными примерами :: Делает легкое понимание

Эта видимость свойства или метода определяется путем предварительной фиксации объявления одного из трех ключевых слов (Public, protected и private)

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

  • Аннотация, например. Подумайте о широте видимости общественности как о «публичном пикнике», к которому может прийти любой человек.

Защищено: когда доступность свойств или методов для защищенных членов может быть доступ только к самому классу, а также к унаследованным и наследующим классам. (Унаследовано: – класс может иметь все свойства и методы другого класса).

  • Подумайте, как защищенную область видимости как «пикник компании», где члены компании и члены их семей допускаются не публично. Это наиболее распространенное ограничение по объему.

Закрыто: когда свойство или видимость метода настроено на закрытый, только класс, который имеет частные члены, может получить доступ к этим методам и свойствам (внутри внутри класса), несмотря на то, что, возможно, какое-либо отношение классов.

  • с аналогией пикника считают «пикником компании, где допускаются только члены компании» на пикнике. а не семья, ни широкая публика не допускается.
 /** * Define MyClass */ class MyClass { public $public = 'Public'; protected $protected = 'Protected'; private $private = 'Private'; function printHello() { echo $this->public; echo $this->protected; echo $this->private; } } $obj = new MyClass(); echo $obj->public; // Works echo $obj->protected; // Fatal Error echo $obj->private; // Fatal Error $obj->printHello(); // Shows Public, Protected and Private /** * Define MyClass2 */ class MyClass2 extends MyClass { // We can redeclare the public and protected method, but not private protected $protected = 'Protected2'; function printHello() { echo $this->public; echo $this->protected; echo $this->private; } } $obj2 = new MyClass2(); echo $obj2->public; // Works echo $obj2->private; // Undefined echo $obj2->protected; // Fatal Error $obj2->printHello(); // Shows Public, Protected2, Undefined 

Извлечен из :

http://php.net/manual/en/language.oop5.visibility.php

В руководстве по PHP есть хорошее мнение по этому вопросу.

Видимость свойства или метода может быть определена путем префикса декларации ключевыми словами public, protected или private. К членам класса, объявленным публичными, можно получить доступ во всех странах. Доступ к элементам, объявленным защищенными, может быть доступен только внутри самого класса и наследуемых и родительских классов. Участникам, объявленным как private, может быть доступен только класс, определяющий участника.

Учитывая «когда»:
Я склонен сначала объявлять все как личные, если не уверен. Причина в том, что обычно гораздо проще превращать приватный метод публики, чем наоборот. Это потому, что вы можете хотя бы убедиться, что частный метод не использовался нигде, кроме самого класса. Общедоступный метод может быть использован повсюду, возможно, требует обширной перезаписи.

Обновление: в настоящее время я использую protected по умолчанию, потому что я пришел к выводу, что он достаточно хорош для инкапсуляции и не мешает, когда я расширяю классы (которых я все равно избегаю). Только если у меня есть веская причина использовать две другие, я буду.

Хорошей причиной для private метода будет тот, который реализует нечто присущее этому объекту, что даже расширяющийся класс не должен меняться (фактическая причина, в дополнение к инкапсуляции). В конце концов, до сих пор достаточно легко отслеживать, где обычно используется protected метод, поэтому я по умолчанию protected настоящее время. Я признаю, что не 100% объективный опыт «в траншеях».

⚡️ Вот простой способ запомнить объем public , protected и private .

PUBLIC :

  • public scope: общедоступная переменная / функция доступна как для объектов, так и для других классов.

PROTECTED :

  • protected scope: защищенная переменная / функция доступна для всех классов, расширяющих текущий класс.
  • Нет! Объекты не могут получить доступ к этой области

PRIVATE :

  • private scope: частная переменная / функция видна только в текущем классе, где она определена.
  • Нет! Класс, расширяющий текущий класс, не может получить доступ к этой области.
  • Нет! Объекты не могут получить доступ к этой области.

Прочитайте Видимость метода или переменной в Руководстве по PHP.

Они предназначены для разных уровней инкапсуляции

Переменные в PHP представлены в трех разных типах:

Публикация: значения этих типов переменных доступны во всей области действия и требуют выполнения кода. объявить как: public $examTimeTable;

Закрыто: значения этого типа переменных доступны только для класса, к которому он принадлежит. private $classRoomComputers;

Protected: значения этого класса доступны и доступны только в том случае, если Access был предоставлен в виде наследования или их дочернего класса. обычно используется :: для предоставления доступа родительским классом

protected $familyWealth;

Для меня это самый полезный способ понять три типа собственности:

Публикация : используйте это, когда вы в порядке, при этом эта переменная напрямую доступна и изменена из любого места вашего кода.

Пример использования вне класса:

 $myObject = new MyObject() $myObject->publicVar = 'newvalue'; $pubVar = $myObject->publicVar; 

Защищено : используйте это, когда вы хотите заставить других программистов (и самостоятельно) использовать геттеры / сеттеры вне класса при доступе и настройке переменных (но вы должны быть последовательными и использовать геттеры и сеттеры внутри класса). Это или private как правило, по умолчанию, вы должны настроить все свойства класса.

Зачем? Потому что, если вы решите в какой-то момент в будущем (может быть, даже в течение 5 минут), что вы хотите манипулировать значением, которое возвращается для этого свойства или что-то с ним делать до получения / настройки, вы можете сделать это без рефакторинга везде, где есть использовал его в вашем проекте.

Пример использования вне класса:

 $myObject = new MyObject() $myObject->setProtectedVar('newvalue'); $protectedVar = $myObject->getProtectedVar(); 

Частное : private свойства очень похожи на protected свойства. Но отличительная особенность / разница заключается в том, что сделать ее private также делает ее недоступной для дочерних классов без использования геттера или сеттера родительского класса.

Таким образом, в основном, если вы используете геттеры и сеттеры для свойства (или если он используется только внутри родительского класса, и он не предназначен для доступа нигде), вы можете также сделать его private , чтобы предотвратить пытаясь использовать его напрямую и вводить ошибки .

Пример использования внутри дочернего класса (который расширяет MyObject):

 $this->setPrivateVar('newvalue'); $privateVar = $this->getPrivateVar(); 

Возрождение старого вопроса, но я думаю, что действительно хороший способ подумать об этом – с точки зрения API, который вы определяете.

  • public – Все, что является общедоступным, является частью API, который будет использовать и полагаться на всех, кто использует ваш класс / интерфейс / другой.

  • protected – Не обманывайте себя, это тоже часть API! Люди могут подклассы, расширять ваш код и использовать все, что было защищено.

  • private – частные свойства и методы могут быть изменены так, как вам нравится. Никто другой не может их использовать. Это единственные вещи, которые вы можете изменить, не внося изменений.

Или в терминах Семвера :

  • Изменения в чем-либо public или protected должны рассматриваться как ОСНОВНЫЕ изменения.

  • Любое новое public или protected должно быть (по крайней мере) MINOR

  • Только новые / изменения чего-либо private могут быть PATCH

Таким образом, с точки зрения поддержания кода, хорошо быть осторожным в отношении того, что вы public или protected потому что это то, что вы обещаете своим пользователям.

Public: это состояние по умолчанию, когда вы объявляете переменную или метод, к которому можно получить доступ непосредственно к объекту.

Защищено: может быть доступно только внутри объекта и подклассов.

Закрыто: можно ссылаться только на объект, а не на подклассы.