6.8. Типы доступа
Типы доступа позволяют разработчикам ограничить доступ к элементам определенного класса. Это является новинкой PHP 5, но для объектно-ориентированных языков программирования это достаточно известная возможность. Типы доступа обеспечивают фундаментальный блок для создания надежных объектно-ориентированных приложений и представляют собой одно из основных требований для повторно используемых библиотек объектно-ориентированных инфраструктур.
Подобно C++ и Java, PHP имеет три типа доступа: public (общедоступный), private (частный) и protected (защищенный). Элемент класса может иметь один из вышеперечисленных типов доступа. Если тип доступа не определен, элемент будет иметь тип доступа public. Тип доступа может присваиваться статическому элементу, в таком случае тип доступа должен предшествовать ключевому слову static. Доступ к общедоступным элементам осуществляется без ограничений. Любой код, находящийся вне класса, имеет право доступа на чтение и запись общедоступных свойств. Общедоступные методы можно вызывать из любой части сценария. В предыдущих версиях PHP все методы и свойства были общедоступными, и это наводило на мысль, что объекты представляют собой массивы особого типа.
Частные элементы видны только элементам, которые принадлежат одному и тому же классу. Изменение и даже чтение значения частного свойства вне метода класса невозможно. Аналогично, только другие методы данного класса могут вызывать частные методы. Даже порожденные классы не имеют доступа к частным элементам.
Необходимо всегда помнить, что любой элемент класса, а не только конкретный экземпляр имеет возможность доступа к частным элементам. В качестве иллюстрации ко всему сказанному рассмотрим листинг 6.8. Метод equals сравнивает две заготовки (widget). Оператор == сравнивает свойства двух объектов одного и того же класса, но в этом примере каждому экземпляру присваивается уникальный идентификатор. Метод equals сравнивает только название и цену. Обратим внимание на то, как метод equals осуществляет доступ к частным свойствам другого экземпляра Widget. Языки Java и C имеют аналогичные возможности.

Листинг 6.8. Частные элементы

<?php
class Widget
{
private $name; private $price; private $id;
public function __construct($name, $price)
{
$this->name = $name; $this->price = floatval($price); $this->id = uniqid();
}
//проверка идентичности двух заготовок public function equals($widget)
{
return(($this->name == $widget->name)AND ($this->price == $widget->price));
}
}
$w1 = new Widget('Cog', 5.00); $w2 = new Widget('Cog', 5.00); $w3 = new Widget('Gear', 7.00);
//TRUE
if($w1->equals($w2))
{
print("w1 и w2 идентичны <br>n");
}
//FALSE
if($w1->equals($w3))
{
print("w1 и w3 идентичны <br>n");

//FALSE, == включает в процесс сравнения идентификатор if($w1 == $w2)
{
print("w1 и w2 идентичны <br>n");
}
?>

Если вы не имеете достаточного опыта в ООП, то для вас может остаться неясным предназначение частных элементов. Вернемся к идеям инкапсуляции и сцепления, которые обсуждались в начале этой главы. Частные элементы позволяют инкапсулировать данные внутри объекта. Они остаются скрытыми и недоступными для внешнего кода и способствуют свободному сцеплению. Если код вне структуры данных не имеет возможности осуществить доступ к данным непосредственно, он не может реализовать скрытую зависимость.
Конечно, большая часть частных свойств по-прежнему представляет информацию, которая будет разделена с кодом, находящимся вне объекта. Решение заключается в наличии пары общедоступных методов (конструкторов), предназначенных для передачи и установки. Обычно этот конструктор также принимает первоначальные значения для свойств. Это позволяет осуществлять взаимодействие с элементами через узкий, хорошо определенный интерфейс. Он также позволяет изменять значения по мере прохождения через метод. Обратите внимание на то, что конструктор в листинге 6.8 преобразует формат представления цены в вещественный формат.