Рассылка закрыта
При закрытии подписчики были переданы в рассылку "Заметки Дизайнера" на которую и рекомендуем вам подписаться.
Вы можете найти рассылки сходной тематики в Каталоге рассылок.
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 Архив рассылки |
Отписаться
Вебом
Почтой
Вспомнить пароль |
| В избранное | ||


