Публичный:
Когда вы объявляете метод (функцию) или свойство (переменную) как 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
Разделение класса дедушки с помощью Reflection
Эта тема на самом деле не выходит за рамки, и я добавляю ее сюда, чтобы доказать, что отражение действительно мощно. Как я указывал в трех приведенных выше примерах, к членам 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. Статические члены класса не отображаются.
Дополнительные ресурсы:
20.02.2014
protected
, если вы хотите сделать свою переменную / функцию видимой во всех классах, расширяющих текущий класс И его родительские классы. 02.05.2012http://www.php.net/manual/en/language.oop5.visibility.php#109324
18.10.2012