Рассылка закрыта
При закрытии подписчики были переданы в рассылку "Заметки Дизайнера" на которую и рекомендуем вам подписаться.
Вы можете найти рассылки сходной тематики в Каталоге рассылок.
PHP 5: Новые возможности.
PHP 5: Новые возможности.
The Pterodactyl
Copyright 2006 Pterodactyl's School
Copyright 2005 Pterodactyl's School.
Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license is included in the section entitled "GNU Free Documentation License".
13.01.2006
История переиздания | |
---|---|
Издание 1.00 | 13.01.2006 |
Первоначальная версия. |
Аннотация
Описаны нововведения в PHP 5, касающиеся конструктора и деструктора. Рассмотрено практическое применение пакета PEAR::HTML_Page2. Начата разработка собственного класса - наследника HTML_Page2
.
Содержание
Конструктор - это специальный метод, который исполняется при создании нового объекта. От обычных методов его отличает, во-первых, то, что он вызывается автоматически, и, во-вторых, тем, что он ничего не возвращает (и в принципе не может вернуть).
Подсказка
В связи с последней особенностью обычный способ контроля за успешностью выполнения метода при помощи возвращаемой величины применительно к конструктору технически невозможен. Поэтому все ошибки, возникающие в процессе выполнения конструктора, рекомендуется обрабатывать с использованием одного из нововведений PHP 5 - механизма перехвата исключительных ситуаций (подробно будет рассмотрен в свое время).
В PHP 5 следует использовать единый[1] конструктор __construct
(Пример 1, «Использование единого конструктора»).
Внимание
Обратите внимание на два символа подчеркивания в начале названия!
Пример 1. Использование единого конструктора
<?php class Foo { function __construct($bar) { print $bar; } } ?>
<?php $foo = new Foo('Oops!'); ?>
Oops!
<?php $foo = new Foo('WOW!'); ?>
WOW!
Принятый ранее стиль объявления конструктора с именем, совпадающим с названием класса, также поддерживается, поэтому классы, разработанные для PHP 4, будут работать и с PHP 5.
В каждом классе должно быть не более одного конструктора. Впрочем, если в конструкторе нет необходимости, то его может и не быть вообще.
Замечание
Если все же объявить оба конструктора (новый и старый), то исполнен будет только новый, так как его наличие проверяется раньше (Пример 2, «Неправильное объявление двух конструкторов»).
Деструктор - это специальный метод __destruct
, который автоматически исполняется при разрушении объекта (Пример 3, «Использование деструктора»). Объект разрушается, когда больше нет ни одной ссылки на него, а также при достижении конца скрипта.
Внимание
Обратите внимание на два символа подчеркивания в начале названия!
Пример 3. Использование деструктора
<?php class Foo { function __destruct() { print 'Hi from the destructor.'; } } $foo = new Foo; $foo = null; ?>
Hi from the destructor.
Так как PHP самостоятельно заботится об освобождении использованных ресурсов, то роль деструктора оказывается достаточно ограниченной. Тем не менее, в ряде случаев он может быть полезен, например, для опустошения (flushing) буфера вывода или регистрации (logging) самого факта разрушения объекта.
Внимание
При использовании деструктора следует избегать возможных подводных камней.
- Не гарантируется исполнение деструктора непосредственно сразу после освобождения последней ссылки на объект; прежде могут быть исполнены еще одна или несколько последующих строк кода.
- Вывод из деструктора, исполняемого на сайте по завершению скрипта, не обязательно отобразится в броузере, так как к этому времени обработка HTTP запроса к странице может быть уже завершена.
- Обращаться из деструктора к другому объекту крайне рискованно, так как может оказаться, что тот объект уже разрушен.
- В теле деструктора недопустимы никакие HTTP заголовки, так как к моменту его исполнения все заголовки уже посланы.
- Попытка создать исключительную ситуацию в теле деструктора приводит к возникновению фатальной ошибки.
На этом практическом занятии нам предстоит решить следующие задачи.
- Установить пакеты PEAR::HTML_Common и зависящий от него PEAR::HTML_Page2.
- Ознакомиться с особенностями пакета HTML_Page2.
- Унаследовать от HTML_Page2 свой собственный класс.
- Использовать унаследованный класс.
Для установки пакета PEAR::HTML_Page2 необходимы два архива: непосредственно сам пакет HTML_Page2 и пакет, от которого он зависит, - HTML_Common.
Процедура 1. Установка HTML_Page2
-
Скачайте и распакуйте необходимые архивы.
-
Выберите последние версии пакетов на страницах загрузки HTML_Common и HTML_Page2.
-
Для распаковки воспользуйтесь любым архиватором, поддерживающим формат
.tgz
(tar + gzip).
-
-
Создайте на своем сайте, если это не было сделано ранее, необходимую структуру каталогов.
-
Каталог
/pear/
(непосредственно в корневом каталоге сайта). -
Каталог
/pear/HTML/
.
-
-
Закачайте следующие файлы на свой сайт в каталог
/pear/HTML/
.-
Файлы
HTML/Common.php
иHTML/Page2.php
. -
Весь каталог
HTML/Page2/
целиком.
Подсказка
В результате на сайте должна получиться следующая структура.
/ |-- pear/ |-- HTML/ |-- Common.php |-- Page2.php |-- Page2/ |-- *.*
-
Пакет HTML_Page2 предназначен для создания HTML и XHTML страниц. Наше знакомство с пакетом начнем с особенностей, заложенных в него по умолчанию (Пример 4, «Использование HTML_Page2 по умолчанию»).
Прежде всего, настроим пути к включаемым файлам. Затем включим файл HTML/Page2.php
[2]. Далее создадим объект класса HTML_Page2
. Воспользуемся методом setBody
, чтобы установить содержимое тела страницы. Наконец, вызовем метод display
, который выведет готовую страницу.
Пример 4. Использование HTML_Page2 по умолчанию
<?php ///////////////////////////////////////////////////////////////////// $PEAR_PATH_LOCAL = $_SERVER['DOCUMENT_ROOT'].'/pear'; set_include_path(get_include_path().PATH_SEPARATOR.$PEAR_PATH_LOCAL); ///////////////////////////////////////////////////////////////////// require_once 'HTML/Page2.php'; $page = new HTML_Page2; $page->setBody('<p>Hello, world!</p>'); $page->display(); ?>
Посмотреть этот код в действии можно здесь.
При исполнении данного скрипта, как и следовало ожидать, в броузере отобразится страница со следующим содержимым.
Hello, world!
Однако, куда более впечатляющим окажется просмотр исходного HTML кода этой страницы (View Source).
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3c.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> <head> <meta name="Generator" content="PEAR HTML_Page" /> <title>New XHTML 1.0 Transitional Compliant Page</title> </head> <body> <p>Hello, world!</p> </body> </html>
Как видим, созданный нами объект класса HTML_Page2
отнюдь не ограничился выводом заданного текста, а сгенерировал вместо этого полноценную страницу, содержащую все необходимые служебные элементы и соответствующую стандартам W3C[3].
Значения аттрибутов по умолчанию можно перекрыть своими собственными (Пример 5, «Углубленное использование HTML_Page2»). Для этого при создании нового объекта следует передать конструктору ассоциативный массив собственных аттрибутов. Например, таким образом можно установить DTD, язык, кодировку и т. п. Многие аттрибуты можно изменить при помощи вызываемых методов: например, заголовок
страницы (setTitle
).
Пример 5. Углубленное использование HTML_Page2
<?php $attributes['doctype'] = 'XHTML 1.0 Strict'; $attributes['language'] = 'ru'; $attributes['charset'] = 'windows-1251'; ///////////////////////////////////////////////////////////////////// $PEAR_PATH_LOCAL = $_SERVER['DOCUMENT_ROOT'].'/pear'; set_include_path(get_include_path().PATH_SEPARATOR.$PEAR_PATH_LOCAL); ///////////////////////////////////////////////////////////////////// require_once 'HTML/Page2.php'; $page = new HTML_Page2($attributes); $page->setTitle('Hello, world!'); $page->setBody('<p>Привет, мир!</p>'); $page->display(); >>
Посмотреть этот код в действии можно здесь.
На выходе, соответственно, получим следующее.
Привет, мир!
<?xml version="1.0" encoding="windows-1251"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3c.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ru"> <head> <meta name="Generator" content="PEAR HTML_Page" /> <title>Hello, world!</title> </head> <body> <p>Привет, мир!</p> </body> </html>
Начнем разработку класса, который станет основой нашего учебного проекта. Унаследуем этот класс от HTML_Page2
. Целесообразность такого наследования (вместо непосредственного использования HTML_Page2
) станет ясной при анвлизе значений аттрибутов страницы, принятых в HTML_Page2
по умолчанию (Таблица 1, «HTML_Page2: Значения аттрибутов по умолчанию»).
По меньшей мере, один аттрибут - tab
- должен быть перекрыт, так как его значение по умолчанию противоречит достигнутому нами ранее соглашению об использованию для отступов четырех пробелов вместо табуляции.
Аттрибут | Описание | Значение | Примечание |
---|---|---|---|
charset |
Кодировка символов | utf-8 | |
lineend |
Стиль разделителя строк | unix | \n |
tab |
Стиль отступов | \t | |
doctype |
Определение !DOCTYPE | XHTML 1.0 Transitional | |
language |
Язык страницы | en | |
cache |
Управляет кэшированием страницы | false | |
mime |
MIME тип | text/html | |
namespace |
Пространство имен | пустая строка | |
profile |
Профиль документа | пустая строка | |
prolog |
Наличие XML пролога | true |
Таким образом, нам предстоит создать новый класс, который мы назовем SSS
(от Simple Site Solution), унаследовав его от HTML_Page2
и перекрыв значение аттрибута tab
по умолчанию своим собственным (см. Создание класса SSS
).
Процедура 2. Создание класса SSS
-
Встроенная документация страничного уровня
-
Скопируйте содержимое созданного на предыдущем занятии шаблона в новый файл
SSS.php
. -
Исправьте в начале описания '
A part of the...
' на 'The main part of...
'. -
Исправьте номер версии на '
0.01
'.
-
-
Включаемые файлы
-
Единственным включаемым файлом в данном случае является
HTML/Page2.php
. Не поленитесь сопроводить эту операцию комментарием./** * Include the parent class */ require_once 'HTML/Page2.php';
-
Внесем соответствующее дополнение во встроенную документацию страничного уровня.
* Required: PEAR::HTML_Page2.
-
-
Объявление класса
А здесь предварить объявление класса встроенной документацией просто необходимо. Впрочем, пока что, кроме самого общего описания класса, добавить нечего.
/** * Advanced (X)HTML Page Generation Class * * Features: * * Usage: * * @todo more features * @todo usage */ class SSS extends HTML_Page2 { /* ... */ }
-
Конструктор
-
Воспользуйтесь единым конструктором
__construct
. Конструктор должен принимать в качестве аргумента ассоциированный массив аттрибутов, как и конструктор родительского класса.function __construct($attributes) { /* ... */ } // end class constructor
-
Повторите функциональность родительского класса, вызвав его конструктор с принятым массивом аттрибутов в качестве параметра.
parent::__construct($attributes);
Замечание
Строго говоря, в родительском классе -
HTML_Page2
- используется одноименный конструктор в стиле PHP 4. Тем не менее, здесь вполне допустимо использование единого конструктора__construct
вместоHTML_Page2
. -
Перекройте значение по умолчанию аттрибута
tab
(до вызова родительского конструктора).$attributes['tab'] = ' ';
Замечание
Далеко не лучший способ решения проблемы. Дело в том, что таким образом будет перекрыто не только значение по умолчанию, но и могущее быть переданное в конструктор в ассоциативном массиве при создании нового объекта. На следующем занятии данный недостаток будет исправлен. А пока добавьте напоминание во встроенную документацию.
* @todo fix the tab attribute overridding
Отметьте также совместимость со стандартами кодирования, принятыми в PEAR, во встроенной документации класса.
* + PEAR Coding Standards compliance
-
Перекройте выводимые по умолчанию мета данные о генераторе страницы.
$this->setMetaData('Generator', 'Simple Site Solution');
Замечание
Переменная
$this
соответствует самому содержащему данный код объекту. -
Отобразите все это во встроенной документации.
/** * Class constructor * * Accepts an array of attributes (just as the parent). * * Overrides the tab attribute. * Calls the parent's constructor. * Sets the Generator meta data. * * @param array $attributes Associative array of page * @todo fix the tab attribute overridding */
Итоговый листинг кода конструктора имеет следующий вид.
/** * Class constructor * * Accepts an array of attributes (just as the parent). * * Overrides the tab attribute. * Calls the parent's constructor. * Sets the Generator meta data. * * @param array $attributes Associative array of page * @todo fix the tab attribute overridding */ function __construct($attributes) { $attributes['tab'] = ' '; parent::__construct($attributes); $this->setMetaData('Generator', 'Simple Site Solution'); } // end class constructor
-
Сведя все воедино, получим полный листинг кода (Пример 6, «SSS 0.01»).
Пример 6. SSS 0.01
<?php /** * The main part of the Simple Site Solution package * * The SSS package provides a simple interface for generating an web site. * * Required: PEAR::HTML_Page2. * * PHP version 5 * * LICENSE: This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * * @package SSS * @author The Pterodactyl <ptero@pterodactyl.l2p.net> * @copyright 2006 Pterodactyl's School * @license http://www.gnu.org/licenses/gpl.txt GNU General Public License * @version 0.01 * @link http://pterodactyl.l2p.net/php5/examples/SSS */ /** * Include the parent class */ require_once 'HTML/Page2.php'; /** * Advanced (X)HTML Page Generation Class * * Features: * + PEAR Coding Standards compliance * * Usage: * * @todo more features * @todo usage */ class SSS extends HTML_Page2 { /** * Class constructor * * Accepts an array of attributes (just as the parent). * * Overrides the tab attribute. * Calls the parent's constructor. * Sets the Generator meta data. * * @param array $attributes Associative array of page * @todo fix the tab attribute overridding */ function __construct($attributes) { $attributes['tab'] = ' '; parent::__construct($attributes); $this->setMetaData('Generator', 'Simple Site Solution'); } // end class constructor } ?>
На сайте этот код находится здесь.
Для начала определимся с местоположением класса SSS
. Его можно расположить в одной директории с использующим его скриптом - чтобы не заботиться о настройке пути к включаемым файлам. Однако, нет гарантии, что вызовы класса будут происходить только из этой директории. Кроме того, таких используемых классов может быть несколько, и размещать их в одной директории с использующими их скриптами представляется не совсем удачной идеей. Поэтому создадим на сайте новую директорию
/classes/
и сохраним в нее файл SSS.php
.
Теперь нам надо добавить путь к новой директории в include_path
. Это можно сделать несколькими способами (учтите, что мы по-прежнему должны добавить путь и к директории /pear/
).
$PEAR_PATH_LOCAL = $_SERVER['DOCUMENT_ROOT'].'/pear'; $CLASSES_PATH = $_SERVER['DOCUMENT_ROOT'].'/classes'; set_include_path(get_include_path().PATH_SEPARATOR.$PEAR_PATH_LOCAL. PATH_SEPARATOR.$CLASSES_PATH);
$PEAR_PATH_LOCAL = $_SERVER['DOCUMENT_ROOT'].'/pear'; $CLASSES_PATH = $_SERVER['DOCUMENT_ROOT'].'/classes'; set_include_path(get_include_path().PATH_SEPARATOR.$PEAR_PATH_LOCAL); set_include_path(get_include_path().PATH_SEPARATOR.$CLASSES_PATH);
Первый способ выглядит несколько тяжеловесным, второй - неуклюжим. Особенно, если придется добавлять большее количество директорий. Остановимся на следующем способе.
$include_path[] = get_include_path(); $include_path[] = $_SERVER['DOCUMENT_ROOT'].'/pear'; $include_path[] = $_SERVER['DOCUMENT_ROOT'].'/classes'; set_include_path(implode(PATH_SEPARATOR, $include_path));
Влючим файл SSS.php
и создадим новый объект класса SSS
. Зададим русский язык страницы и кодировку windows-1251
.
$attributes = array('language' => 'ru', 'encoding' => 'windows-1251'); require_once 'SSS.php'; $page = new SSS($attributes);
Установим заголовок и тело страницы.
$page->setTitle('SSS Test'); $page->setBody('<p>Это просто тест.</p>');
Осталось отобразить подготовленную страницу.
$page->display();
Весь демонстрационный скрипт целиком будет выглядеть следующим образом (Пример 7, «Использование SSS 0.01
»).
Пример 7. Использование SSS 0.01
<?php $attributes = array('language' => 'ru', 'encoding' => 'windows-1251'); ///////////////////////////////////////////////////////// $include_path[] = get_include_path(); $include_path[] = $_SERVER['DOCUMENT_ROOT'].'/pear'; $include_path[] = $_SERVER['DOCUMENT_ROOT'].'/classes'; set_include_path(implode(PATH_SEPARATOR, $include_path)); ///////////////////////////////////////////////////////// require_once 'SSS.php'; $page = new SSS($attributes); $page->setTitle('SSS Test'); $page->setBody('<p>Это просто тест.</p>'); $page->display(); ?>
Этот код на сайте можно найти здесь.
А вот что мы увидим.
Это просто тест.
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3c.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ru"> <head> <meta name="Generator" content="Simple Site Solution" /> <title>SSS Test</title> </head> <body> <p>Это просто тест.</p> </body> </html>
Заметим, что отступы в сгенерированном HTML коде страницы образованы при помощи четырех пробелов вместо символа табуляции; причем без малейшего вмешательства с нашей стороны.
Остается только внести соответствующие дополнения во встроенную документацию класса SSS
.
* Usage: * require_once 'SSS.php'; * $page = new SSS; * $page->setBody('...'); * $page->display();
[1] PHP Manual. http://www.php.net/manual/en/. Gabor Hojtsy. 10-01-2006. Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 .
[2] PHP 5 for Dummies. Janet Valade. Wiley Publishing, Inc.. www.wiley.com. Copyright 2004 Wiley Publishing, Inc..
[1] Единый, потому что его название одинаково для всех классов.
[2] Ввиду зависимости HTML_Page2 от HTML_Common отметим, что включать также и файл HTML/Common.php
не нужно (он будет включен автоматически из HTML/Page2.php
). Однако, если бы мы использовали в своем скрипте HTML_Common непосредственно
(сами создавали объект класса HTML_Common
, вызывали бы его методы и т. п.), то файл HTML/Common.php
следовало бы все же включить (require_once 'HTML/Common.php';
).
[3] World Wide Web Consortium (W3C) - международноая организация, разрабатывающая, в том числе, Web стандарты.
С последней версией этой и других статей Вы можете ознакомиться на сайте рассылки [http://pterodactyl.l2p.net/php5/].
Subscribe.Ru
Поддержка подписчиков Другие рассылки этой тематики Другие рассылки этого автора |
Подписан адрес:
Код этой рассылки: inet.webbuild.php5whatsnew Архив рассылки |
Отписаться
Вебом
Почтой
Вспомнить пароль |
В избранное | ||