Разработчику. Сборник рецептов PHP
Задавайте вопросы

Классы и объекты

Вернуться назад

Введение

Изначально PHP не был объектно-ориентированным (ОО) языком. Но по мере развития объектно-ориентированные возможности стали в нем появляться. Сначала можно было определять классы, но не было конструкторов. Затем появились конструкторы, но не было деструкторов. Медленно, но уверенно, по мере роста количества пользователей, сталкивавшихся с ограничениями синтаксиса PHP, добавлялись новые возможности, призванные удовлетворить требования программистов.

Однако тот, кто хочет, чтобы PHP был настоящим OO языком, возможно, будет разочарован. По своей сути PHP – язык процедурно-ориентированный. Это не Java. Но для тех, кому в программе требуются некоторые OO возможности, вероятно, PHP как раз то, что нужно.

Класс – это пакет, содержащий, во-первых, данные, а во-вторых, методы для доступа или модификации данных. Данные состоят из переменных и известны как свойства. Другую часть класса составляют функции, которые могут изменять свойства класса, и называются они методами.

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

Классы также организованы в определенную иерархию. Вверху цепочки находится родовой класс. В PHP этому классу дано имя stdClass, «стандартный» класс. Каждый нижележащий класс более специализирован, чем его родитель. Например, родительский класс может быть зданием. А здания уже могут подразделяться на жилые и промышленные. Жилые здания можно разделить на индивидуальные и многоквартирные и т. д.

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

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

Объявить и создать классы в PHP нетрудно:

class guest_book {
     var $comments;
     var $last_visitor;
     function update($comment , $visitor) {
          ...
     }
}

Ключевое слово class определяет класс точно так же, как слово function определяет функцию. Свойства объявляются с помощью ключевого слова var. Объявление метода идентично объявлению функции.

Ключевое слово new создает экземпляр объекта:

$gb = new guest_book;

Более подробно реализация объекта описывается в примере "Реализация объектов"

Внутри класса можно объявить свойства с помощью ключевого слова var. Делать это не обязательно, но полезно к этому привыкнуть. Поскольку PHP не требует предварительного объявления всех переменных, то можно создать их внутри класса, и при этом PHP не выдаст ошибки или какого-либо предупреждения. Поэтому список переменных в начале определения класса может ввести в заблуждение, так как он может не совпадать с реальным списком переменных класса.

Помимо объявления свойства, можно также присвоить ему значение:

var $last_visitor = ' Donnan ';

Следующая конструкция позволяет присвоить только постоянное значение:

var $last_visitor = ' Donnan ';               // правильно
var $last_visitor = 9;                             // правильно
var $last_visitor = array(' Jesse ');        // правильно
var $last_visitor = pick_visitor( );        // неправильно
var $last_visitor = ' Chris ' . ' 9 ';        // неправильно

Если вы попытаетесь присвоить что-нибудь еще, то PHP прекратит работу с синтаксической ошибкой.

Для присваивания непостоянного значения применяется внутренний метод класса.

var $last_visitor;

function update($comment , $visitor) {
       if (!empty($comment)) {
              array_unshift($this -> comments , $comment);
              $this -> last_visitor = $visitor;
       }
}

Если посетитель оставил свой комментарий, то вы добавляете его в начало массива комментариев и отмечаете этого посетителя в гостевой книге как последнего. Переменная $this – это специальная переменная, ссылающаяся на текущий объект. Поэтому, чтобы получить доступ к свойству $size объекта изнутри этого объекта, сошлитесь на $this -> $size.

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

class guest_book {
       var $comments;
       var $last_visitor;

       function guest_book($user) {
              $dbh = mysql_connect(' localhost ' , ' username ' , ' password ');
              $db = mysql_select_db(' sites ');
              $user = mysql_real_escape_string($user);
              $sql = " SELECT comments , last_visitor FROM
                            guest_books WHERE user=' $user ' ";
       $r = mysql_query($sql);

       if ($obj = mysql_fetch_object($r)) {
              $this -> comments = $obj -> comments;
              $this -> last_visitor = $obj -> last_visitor;
       }
     }
}

$gb = new guest_book(' stewart ');

Конструкторам посвящен пример "Определение конструкторов объектов" Учтите, что функция mysql_real_escape_string() впервые появилась в версии PHP 4.3; в более ранних версиях следует вызывать функцию mysql_escape_string().

Будьте внимательны, чтобы по ошибке не напечатать $this -> $size. Это допустимо, но не то же самое, что $this -> size. Иначе получится свойство, имя которого представляет значение переменной $size. Скорее всего, переменная $size не определена, поэтому $this -> $size покажет пустое значение. За более подробной информацией о переменных именах свойств обращайтесь к примеру "Создание функции, принимающей переменное количество аргументов"

Для доступа к методу или члену переменной помимо символа -> можно использовать и символ ::. Этот синтаксис позволяет получить доступ к статическим методам класса. Эти методы одинаковы для каждого экземпляра класса, поскольку они не могут зависеть от данных, характерных только для конкретного экземпляра. Например:

Чтобы реализовать наследование путем расширения существующего класса, применяется ключевое слово extends:

class convert {
     // преобразование из градусов по Цельсию в градусы по Фаренгейту
     function c2f($degrees) {
          return (1.8 * $degrees) + 32;
     }
}

$f = convert :: c2f(100); // 212

Чтобы реализовать наследование путем расширения существующего класса, применяется ключевое слово extends:

class xhtml extends xml {

}

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

class DB {
     var $result;

     function getResult() {
          return $this -> result;
     }

     function query($sql) {
          error_log(" query() must be overridden by a database - specific child");
          return false;
     }
}

class MySQL extends DB {
     function query($sql) {
          $this -> result = mysql_query($sql);
     }
}

Приведенный выше класс MySQL наследует неизмененный метод getResult() родительского класса DB, но имеет свою собственную, специфичную для MySQL версию метода query().

Предваряйте имя метода строкой parent:: для явного вызова родительского метода:

function escape($sql) {
     $safe_sql = mysql_real_escape_string($sql); // переводим специальные
                                                                        // символы в escape-последовательности
     $safe_sql = parent :: escape($safe_sql);      // родительский метод
                                                                                     // добавляет ' ' вокруг $sql
     return $safe_sql;
}

Лежащий в основе мощи PHP механизм называется Zend. PHP 4 использует Zend Engine 1; PHP 5 будет основан на усовершенствованной версии – Zend Engine 2 (ZE2). ZE2 имеет совершенно новую объектную модель, которая поддерживает массу новых объектно-ориентированных возможностей: конструкторы и деструкторы, частные методы, обработку исключений и вложенные классы.

Вернуться назад

Рейтинг@Mail.ru

Яндекс.Метрика

Индекс цитирования

Рейтинг Сайтов ДОСКИ.РУ