25-02-2007
Copyright © 2001, 2002, 2003, 2004, 2005, 2006, 2007 The PEAR Documentation Group
Авторские права
Авторские права на это руководство принадлежат PEAR Documentation Group (2001-2003). Это руководство может распространяться при условии соблюдения условий Open Publication License, версии 1.0 или более поздней (последняя версия лицензии доступна по адресу http://www.opencontent.org/openpub/).
Распространение существенно модифицированных версий этого документа без прямого разрешения правообладателя запрещено.
Распространение работ или производных работ в любой обычной (бумажной) форме без прямого разрешения правообладателя запрещено.
PEAR Documentation Group состоит из всех людей, которые принимали участие в составлении документации к PEAR. Официальные представители перечислены на первой странице. Если вы хотите связаться с группой - вам следует написать по адресу pear-doc@lists.php.net.
Это руководство создано с помощью XML с использованием DocBook XML DTD и DSSSL (Document Style and Semantics Specification Language) для форматирования. Утилиты, использовавшиеся для форматирования HTML и PDF версий: Jade, который создал James Clark и The Modular DocBook Stylesheets, которые создал Norman Walsh.
Руководство основывается на большом объеме работы, которую в свое время сделали участники PHP Documentation Group. Подробнее читайте здесь - About the PHP manual.
Здесь вы сможете найти описание обшей структуры, разметки и соглашений, которые используются в руководстве по PEAR. Руководство разделено на 5 основных частей:
Эта секция содержит небольшой вступление на тему что такое PEAR и что он может предложить. В нее также включена общая информация об установке и использовании PEAR, вариантах поддержки и ответы на часто задаваемые вопросы о PEAR.
Эта секция содержит документацию по базовым классам PEAR. Эти классы являются базовыми для каждого класса PEAR, понимание их основ позволит вам использовать PEAR. Обсуждаемые темы включают: базу PEAR, администрирование PEAR, обработку ошибок с помощью PEAR_Error и команды системы. Эти классы поставляются вместе с релизами PHP.
Существует много пакетов PEAR и их количество растет день ото дня. Почти каждый пакет документирован и почти каждый не ставится по умолчанию. Информацию об установке классов PEAR на вашей системе вы можете найти в главе Установка.
Каждый документированный класс содержит основную документацию о функциях, которые он предоставляет. Может быть, также, дополнительная информация в виде введения, списка констант и примеров использования пакета. Дополнительная информация может присутствовать в исходниках пакета.
Описание каждой функции может содержать некоторые или все из нижеперечисленных частей:
Обзор
Содержит описание структуры и прототип функции.
Описание
Содержит описание того, что делает эта функция.
Параметр
Описывает каждый параметр функции с указанием имен и типов каждого из них. Перечислены обязательные и опциональные параметры.
Возвращаемое значение
Описывает возвращаемое значение, если функция не завершается ошибкой.
Throws
Описывает объекты класса PEAR_Error, возвращаемые в случае завершении функции с ошибкой.
Заметка
Дополнительные заметки и информация о функции. Содержит пример, если фукнция может быть вызвана статически.
См. также
Ссылки на другие функции и разделы руководства.
Пример
Пример использование функции или класса.
Пакеты PECL - это обычные модули PHP, написанные на C. Структура документации аналогична описанной выше.
Содержит информацию о написании и добавлении в PEAR своих собственных пакетов.
The following is a list of people that are helping to maintain this documentation. If you would like to contact one of them, please write to pear-doc@lists.php.net.
Lorenzo Alberton
Gregory Beaver
Daniel Convissor
David Costa
Thomas V.V. Cox
Christophe GeschИ
Martin Jansen
Alan Knowles
Clay Loveless
Alexander Merz
Stefan Neufeind
Jon Parise
Tobias Schlitt
Stephan Schmidt
Mika Tuupola
Michael Wallner
Christian Weiske
(In alphabetic order.)
PEAR посвящается Malin Bakken, родившейся 21 ноября 1999 года (первые строки PEAR были написаны всего за два часа до её рождения).
PEAR - это аббревиатура от "PHP Extension and Application Repository" (Репозиторий приложений и модулей PHP).
PEAR - это:
структурированная библиотека открытого кода, созданная для пользователей PHP;
система управления пакетами и распространения кода среди разработчиков;
стандарт написания PHP-кода (подробнее о стандарте см. здесь);
базовые классы PHP-кода (подробнее о базовых классах см. здесь;
библиотека дополнительных модулей для PHP (The PHP Extension Code Library, PECL), подробную информацию о PECL можно узнать здесь;
веб-сайт, листы рассылки и зеркала для загрузки - все это предназначено для поддержания и развития сообщества разработчиков PHP/PEAR.
Код в PEAR разделен на так называемые "пакеты". Каждый пакет - это отдельный проект со своей командой разработчиков, номером версии, циклом разработки, документацией и определенным отношением к остальным пакетам (включая возможные зависимости). Пакеты распространяются в виде архивов *.TAR.GZ, которые включают в себя описание пакета, и устанавливаются на вашей системе с помощью инсталлятора PEAR.
Есть два типа пакетов: пакеты исходного кода (содержат, соответственно, только исходники) и бинарные пакеты (содержат платформозависимые бинарные файлы и, возможно, их исходный код). Естественно, что установка пакетов, которые содержат код на C, из исходников требует присутствия среды для компиляции C-кода.
В PEAR существует определенное дерево пакетов, в котором каждой ветвью является часть имени пакета. Ветви разделяются по темам, их названия в именах пакетов разделяются символом подчеркивания. Например, "MP3_Id", "Archive_Tar" и "HTTP_Post".
Пакеты могут находиться в зависимости друг от друга, однако не существует какой-либо обязательной зависимости между пакетом и его "родителем" в дереве пакетов (например, "HTTP_Post" не зависит от "HTTP").
Несколько ветвей высшего уровня называются "суб-репозиториями" и выполняют специальные функции. На данный момент это: PECL, Gtk и App. Каждый из них достоин отдельной темы, поэтому за дополнительной информацией лучше обратиться в соответствующие разделы настоящей документации.
Руководство по стилю написания кода, Стандарт кодирования PEAR (или коротко - PCS), существует для облегчения совместной работы разработчиков PEAR, для повышения качества и портабельности, а также для того, чтобы помочь разработчикам в создании cтандартизированных программных интерфейсов. В пакетах, которые входят в PFC (The PHP Foundation Classes), стандарт кодирования соблюдается особо строго, для других - менее.
Все пакеты PEAR регистрируются и загружаются в центральную базу данных, которая доступна на pear.php.net. Сторонние пакеты с открытыми исходниками так же могут быть зарегистрированы и загружены. Пакеты с закрытыми исходниками PEAR предназначена только для кода с открытыми исходниками.
Pear.php.net предоставляет два варианта интерфейсов к базе данных PEAR: дружественный для пользователя интерфейс (HTML) и интерфейс для машины (на данный момент это XML-RPC). Загрузка пакетов осуществляется с помощью HTTP. Также, pear.php.net выполняет и другие функции:
управление пользовательскими записями (интегрированное с сервером CVS)
управление пакетами
управление релизами пакетов
Пакеты распространяются в виде архивов *.TAR.GZ с описанием в формате XML. Описание содержит информацию о пакете, список файлов и их предназначений, а также список зависимостей.
Базовые классы (The PHP Foundation Classes, PFC) - это подмножество PEAR, основными целями которого являются качество, универсальность, многофункциональность и совместимость. В том случае, если PHP и далее будет поставляться вместе с пакетами PEAR и установщиком, то этими пакетами непременно будут базовые классы.
Повышенное качество этих пакетов означает то, что ни один пакет с уровнем ниже "stable" не будет допущен в PFC.
Универсальность означает, что пакеты не должны без особых на то причин зависеть от любого вида внешнего окружения (например, формата вывода, операционной системы, веб-сервера, SAPI и др.)
Многофункциональность пакетов означает, что их удобно использовать в других пакетах, они имеют стабильный и стандартизированный API, предпочитают использовать устоявшиеся компоненты, а также не зависят от внешней среды (версии PHP, SAPI, операционной системы и др.)
Совместимость - это не просто поддержка синтаксиса и семантики предыдущих версий, это также заблаговременное планирование. Проектирование кода таким образом, что добавление новой функциональности не требует больших усилий, делает код "совместимым с будущими версиями".
PECL (The PHP Extension Code Library) - это суб-репозиторий PEAR для модулей, написанных на C, как и те, которые распространяются вместе с самим PHP. На самом деле, одним из мотивов создания PECL была необходимость перемещения куда-либо модулей из PHP. Модули в PECL соблюдают стандарты кодирования, использованные при написании PHP, а не стандарты кодирования PEAR, однако они распространяются и устанавливаются с помощью пакетов PEAR.
Процесс перемещения модулей из PHP в PECL называется "pickling" (от PECL и от "pick" - "отбирать").
Пакеты Gtk - это пакеты, которые используют функциональность проекта PHP-GTK. Код в этом суб-репозитории следует стандарту кодирования PEAR.
На данный момент еще нет определенного плана о том, как они будут распространяться.
Эта глава описывает процесс установки пакетов PEAR.
В этой главе предполагается, что вы уже знакомы со структурой PEAR.
Базовая установка, которая поставляется вместе с дистрибутивом PHP как часть базовых классов, содержит инструменты, необходимые для запуска установки PEAR. Если у вас установлен один из последних дистрибутивов PHP4 - можете быть спокойны, базовая инсталляция PEAR уже установлена в вашей системе, если только вы не конфигурировали PHP с флагом '--without-pear'.
Пакеты, которые не входят в число базовых, могут быть установлены с помощью менеджера пакетов PEAR, который является подобием "apt-get" в Debian. Еще раз повторим: если у вас установлена одна из последних версий PHP (> 4.3.0pre1), то вы можете пропустить следующий параграф. Если же вы используете PHP 4.2.* или более раннюю версию, то вам придется установить менеджер пакетов вручную.
Кроме установки пакетов, менеджер пакетов PEAR также выполняет некоторые другие задачи: он может создавать новые пакеты на вашей машине, управлять реестром установленных пакетов, проверять зависимости и общаться со службой XML-RPC на pear.php.net для выполнения некоторых других задач.
Для всех тех, кто не использует последние версии PHP (> 4.3.0pre1) мы предоставляем достаточно простой способ установки менеджера пакетов PEAR, который описан на это странице.
Уже сейчас вы можете использовать скрипт, который находится на go-pear.org для установки базовых классов PEAR и менеджера пакетов PEAR. Просто наберите в командной строке:
$ lynx -source http://go-pear.org | php |
и все остальное произойдет автоматически.
Замечание: Некоторые дистрибутивы Linux (например, RedHat) могут использовать links вместо lynx в качестве комманд-лайн браузера. В этом случае вы должны изменить приведенную строку соответствующим образом.
Замечание |
Нижеследующее описание относится к последней версии менеджера пакетов PEAR. |
Установка из командной строки - это самый простой способ установить пакеты PEAR в вашей системе: установщик соединяется с сервером PEAR через обычное HTTP-соединение, загружает пакет на вашу машину и устанавливает в указанное место.
Установки с использованием командной строки достаточно проста: просто наберите следующую стркоу в шелле:
$ pear install <package> |
<package> - это имя пакета, который вы хотите установить (например, HTTP_Upload). Чтобы просмотреть список доступных пакетов - вы можете воспользоваться браузером пакетов PEAR или выполнить команду:
$ pear list-remote-packages |
Эта команда выведет список всех пакетов, которые доступны в PEAR на данный момент.
Если вы загрузили пакет с pear.php.net в виде *.tar.gz, то вы так же можете установить его локально. Для этого, выполните следующую команду в шелле:
$ pear install <file>.tgz |
Эта команда автоматически установит пакет без использования соединения с удаленным сервером. <file>.tgz - это имя пакета, который вы загрузили и хотите установить.
В этом параграфе будет описан способ установки самых последних версий пакетов PEAR с CVS.
В этой главе описываются способы получения технической поддержки в том случае, если у вас есть вопросы, касающиеся PEAR.
В большинстве проектов с открытыми исходниками поддержка осуществляется с помощью списков рассылки. В случае PEAR, имеются пять списков рассылки:
Рассылка изменений в CVS
Первые четыре списка рассылки предназначены для того, чтобы помочь вам, если у вас имеются какие-то вопросы. Пожалуйста, дочитайте эту главу до конца, чтобы понять какой из них подходит именно вам. Рассылка изменений в CVS предназначена для разработчиков PEAR: все добавления и изменения в системе контроля версий (CVS) отражаются в этом списке рассылки.
Вы можете подписаться на списки рассылки PEAR здесь.
Рассылка для пользователей PEAR - это список рассылки, где вы можете задать вопрос, касающийся установки PEAR, использования конкретных пакетов и т.п.
Этот список рассылки не предназначен для вопросов по использования PHP. Для этого, пожалуйста, используйте php-general@lists.php.net.
Как вы уже догадались, это список рассылки для разработчиков PEAR, которые обсуждают здесь вопросы, связанные с развитием PEAR.
Если вы не являетесь разработчиком PEAR, этот список рассылки не должен представлять для вас никакого интереса, если только вы не
хотите знать что происходит внутри PEAR
хотите добавить в PEAR свой код
нашли ошибку в пакете PEAR и хотите предложить патч для ее решения.
Адрес этого списка рассылки - pear-dev@lists.php.net.
Этот список рассылки предназначен для обсуждения вопросов, которые касаются документации по PEAR.
Если вы хотите помочь в документировании пакетов PEAR - пишите сюда.
Если вы обнаружили проблему на нашем веб-сайте или у вас имеется вопрос по его использованию, вы можете связаться с веб-мастерами pear.php.net с помощью pear-webmaster@php.net .
Существует большое количество веб-ресурсов, касающихся PEAR. Мы объединили их в общий список, который находится тут. Если вашего сайта там не хватает - напишите веб-мастеру.
У проекта PEAR имеется свой собственный канал #PEAR, который доступен в сети EFnet. Приходите и встретитесь с гуру, которые находятся в IRC круглые сутки.
Замечание: Стандарты кодирования PEAR используються в коде, который в итоге стает частью PEAR, который в свою очередь поставляеться с дистрибутивом PHP или доступен для скачивания через утилиты инсталяции PEAR.
Используйте для отступа 4 пробела, а не табуляцию. Если вы используете Emacs для редактирования кода, вы должны установить indent-tabs-mode в ноль. Ниже приведен пример настройки Emacs для этой цели:
(defun php-mode-hook () (setq tab-width 4 c-basic-offset 4 c-hanging-comment-ender-p nil indent-tabs-mode (not (and (string-match "/\\(PEAR\\|pear\\)/" (buffer-file-name)) (string-match "\.php$" (buffer-file-name)))))) |
А это пример конфигурации для редактора VIM:
set expandtab set shiftwidth=4 set tabstop=4 |
Управляющие структуры включают в себя операторы if, for, while, switch, и др. Ниже приведен пример оформления оператора if, который в этом отношении является самым сложным:
if ((condition1) || (condition2)) { action1; } elseif ((condition3) && (condition4)) { action2; } else { defaultaction; } |
В управляющих структурах между ключевым словом и открывающей круглой скобкой должен находиться пробел, чтобы отличать их от вызова функций.
Настойчиво рекомендуется использовать фигурные скобки, даже в том случае, когда их использование не является необходимостью. Использование фигурных скобок увеличивает читабельность кода и уменьшает вероятность логических ошибок при изменении кода.
Cинтаксис оператора switch:
switch (condition) { case 1: action1; break; case 2: action2; break; default: defaultaction; break; } |
Вызовы функций должны быть написаны без отступв между именем функции, открывающей скобкой и первым параметром. Отступы в виде пробела должны присутствовать после каждой запятой в перечислении параметров. Пробелов также не должно быть между последним параметром, закрывающей скобкой и точкой с запятой. Пример:
$var = foo($bar, $baz, $quux); |
Как можно заметить, в примере используются пробелы с двух сторон от знака "=". Если подобные присвоения результатов функций переменным объединяются в блоки, то для повышения читабельности рекомендуется следующий синтаксис:
$short = foo($bar); $long_variable = foo($baz); |
Определения функций следуют такому cоглашению:
function fooFunction($arg1, $arg2 = '') { if (condition) { statement; } return $val; } |
Аргументы функций со значениями по умолчанию должны находиться в конце списка аргументов. Функции всегда должны возвращать значение, если это возможно в принципе. Чуть более подробный пример:
function connect(&$dsn, $persistent = false) { if (is_array($dsn)) { $dsninfo = &$dsn; } else { $dsninfo = DB::parseDSN($dsn); } if (!$dsninfo || !$dsninfo['phptype']) { return $this->raiseError(); } return true; } |
Комментарии внутри кода классов должны соответствовать синтаксису комментариев PHPDoc, который напоминает Javadoc. За дополнительной информацией о PHPDoc обращайтесь сюда: http://www.phpdoc.org/
Дополнительные комментарии, кроме тех, что предусмотрены PHPDoc, только приветствуются. Основное правило в данном случае - каждая часть кода повышенной сложности должна быть прокомментирована до того, как вы забыли как она работает.
Подходят комментарии в стилях C (/* */) и C++ (//). Использование комментариев в стиле Perl/shell (#) не рекомендуется.
В тех местах, где вы используете подключение файлов других классов вне зависимости от условий, используйте конструкцию require_once(). Если же подключение файлов зависит от каких-либо условий, то следует использовать include_once(). В этом случае вы всегда будете уверены в том, что файлы подключаются только единожды.
Замечание: include_once() и require_once() и являются конструкциями, а не функциями. Вам не обязательно использовать скобки вокруг имени файла, который подключается.
Всегда используйте <?php ?> вместо <? ?>для выделения PHP-кода. Это необходимо для обеспечения работы PEAR на разных операционных системах и с различными настройками.
Все базовые файлы исходного кода в PEAR должны содержать следующий ниже блок комментариев в заголовке:
/* vim: set expandtab tabstop=4 softtabstop=4 shiftwidth=4: */ // +----------------------------------------------------------------------+ // | PHP version 4 | // +----------------------------------------------------------------------+ // | Copyright (c) 1997-2002 The PHP Group | // +----------------------------------------------------------------------+ // | This source file is subject to version 2.0 of the PHP license, | // | that is bundled with this package in the file LICENSE, and is | // | available at through the world-wide-web at | // | http://www.php.net/license/2_02.txt. | // | If you did not receive a copy of the PHP license and are unable to | // | obtain it through the world-wide-web, please send a note to | // | license@php.net so we can mail you a copy immediately. | // +----------------------------------------------------------------------+ // | Authors: Original Author <author@example.com> | // | Your Name <you@example.com> | // +----------------------------------------------------------------------+ // // $Id$ |
Нет четкого правила, которое определяет момент, когда новый разработчик должен быть добавлен в список авторов данного файла. В общем случае, его внос в изменения этого файла должен относиться к категории "значительных" (т.е. около 10%-20% процентов кода). Исключения могут быть в случае переписывания функций или добавления новой логики.
Простая реорганизация кода и исправление ошибок не приводит к добавлению нового участника в список авторов.
Файлы, которые не входят в базовую часть PEAR должны такой же блок комментариев в заголовке, включая авторские права, лицензию и список авторов. Комментарии должны быть отформатированы для того, чтобы сохранять свою целостность.
Эта часть касается только пакетов, использующих CVS на cvs.php.net.
Включайте ключевое слово CVS - $Id$ в каждый файл. Добавьте эту метку в каждый файл, если там ее еще нет или исправьте уже существующую запись "Last Modified:" и т.п.).
В оставшейся части этой главы предполагается, что вы имеете представление о тэгах CVS и ветках (branches).
Тэги CVS предназначены для того, чтобы пометить файлы, которые принадлежат к конкретному релизу. Ниже приводится список необходимых и рекомендуемых тэгов:
(обязательный) Используется для пометки релиза. Если вы не используете его, то вы не сможете вернуться назад и затребовать пакет в том виде, в котором он находился во время прошлого релиза.
(необязательный) Если вы чувствуете, что перед выпуском релиза необходимо выпустить предварительную версию (release candidat), то вы можете сделать ветку (branch) кода для того, чтобы изолировать релиз и вносить только критически важные изменения до релиза. При этом, обычный процесс разработки может продолжаться в основном дереве кода.
(необязательный) Если вам нужно сделать "микро-релиз" (например, версию 1.2.1 и т.п. после 1.2), вы так же можете использовать ветку в том случае, если основной код меняется достаточно активно и вы хотите вносить только небольшие изменения в микро-релизы.
Пример того, как пометить тэгом релиза 1.2 пакет "Money_Fast":
Сделав так, вы получаете возможность использовать веб-сайт PEAR для дальнейшего процесса выпуска релизов.Пример создания ветки для QA:
Тэг "QA_2_0_BP" - это тэг ветки. Рекомендуется всегда выделять ветки этим тэгом. Служебные ветви (MAINT branches) могут быть отмечены как релиз и без использования этого тэга.В общем случае, имена классов, функций и переменных всегда должны быть "говорящими" для того, чтобы читатель мог сразу понять для чего они используются.
Имена классов должны быть удобочитаемыми и понятными. Избегайте использования аббревиатур там, где это возможно. Имена классов должны начинаться с буквы в верхнем регистре. Иерархия классов PEAR также отражается на именах классов, каждый уровень отделяется знаком подчеркивания. Примеры хороших имен классов:
Функции и методы должны использовать "венгерскую нотацию" (в другом варианте - "верблюжачью" =)). Функции также должны иметь префикс в виде имени пакета для того, чтобы избежать проблем с аналогичными функциями из других пакетов. Первая буква в имени функции должна быть в нижнем регистре, каждая первая буква "слова" в имени функции - в верхнем. Несколько примеров:
Приватные методы и свойства (те методы и атрибуты, которые используются только внутри самого класса; PHP пока(?) не поддерживает их настоящее выделение) должны быть префиксированы знаком подчеркивания. Например:
Имена констант всегда должны быть в верхнем регистре с подчеркиваниями для разделения слов. В качестве префикса в именах констант должно использоваться имя пакета/класса, в котором они используются. Например, все константы, которые используются в пакете DB::, начинаются с "DB_".
Если в вашем пакете необходимо объявить глобальные переменные, то их имя должно начинаться с подчеркивания, имени пакета и еще одного пакета. Например, пакет PEAR использует глобальную переменную, которая называется $_PEAR_destructor_object_list.
Встроенные переменные PHP TRUE, FALSE and NULL должны быть написаны в нижнем регистре.
Этот раздел расказывает о том, каким образом вы можете принять участие в проекте PEAR.
PEAR является проектом с открытыми исходниками, поэтому каждый может принять участие в его разработке. Участие в проекте - это не обязательно написание кода. Участие - это и сообщения об ошибках, и поддержка обратной связи с пользователями, и предложение улучшений, и даже финансовая поддержка.
Разъяснения по поводу добавления новых пакетов могут быть найдены в Руководстве для разработчиков.
Если вы модифицировали пакет и расширили таким образом его функциональность или исправили ошибку, вам следует предоставить ваши изменения общественности (некоторые лицензии принуждают вас к этому, кроме того, это считается хорошим тоном).
Перед созданием патча, вы должны скачать самую последнюю версию пакета с CVS. Для этого вам нужно выполнить следующие команды (в примере используется пакет Foo_Bar):
cvs -d:pserver:cvsread@cvs.php.net:/repository login password is "phpfi" cvs -z3 -d:pserver:cvsread@cvs.php.net:/repository co Foo_Bar |
После того, как вы закончили добавление/изменение кода - протестируйте его. Мы не примем код, который не был протестирован. Когда будете абсолютно уверены, что ваш код не содержит новых ошибок, создайте унифицированный diff-файл командой:
cd pear/Foo_Bar cvs diff -u >Foo_Bar.diff |
Следующий шаг - это предложение патча. Напишите письмо по адресу pear-dev@lists.php.net и пошлите копию (Cc) письма разработчикам пакета. Тема письма должна начинаться с '[Patch]' для того, чтобы было ясно, что вы предлагает патч. Пожалуйста, включите в письмо развернутое объяснение изменений, которые вы предлагаете внести с помощью этого патча. И не забудьте приложить .diff к письму. Разработчики пакеты обычно перечислены в заголовке каждого файла исходников пакета. Кроме этого, их адреса электронной почты можно найти на странице пакета на http://pear.php.net/.
Замечание: Если вы используете Outlook или Outlook Express, пожалуйста, измените расширение файла с .diff на .txt. Определение MIME-типа в Outlook'е зависит от расширения файла и сработает неверно. Письма, содержащие аттачменты, у которых MIME-тип отличается от text/plain будут отвергнуты программным обеспечением рассылки.
Замечание: Если ваш патч ломает обратную совместимость, то очень велики шансы, что разработчики не будут очень рады ему. Поэтому, старайтесь исправлять ошибки так, чтобы не вносить серъезных изменений в API. Но если это абсолютно невозможно и/или ваш патч предоставляет действительно необходимые изменения, то изменения API допустимы.
Если вы считаете, что вы нашли ошибку в пакете PEAR - пожалуйста, проверьте, что вы используете последнюю версию пакета и ваша система соответствует требованиям пакета.
Если ошибка все еще проявляется даже с последней версией пакета - не стесняйтесь сообщить о ней по адресу http://bugs.php.net/. При этом вам следует выбрать категорию "PEAR related" для вашего рапорта. Разработчики PEAR будут извещены о вашем рапорте.
Подробная информация и советы по поводу составления рапортов об ошибках могут быть найдены здесь - http://bugs.php.net/how-to-report.php.
Если вы исправили ошибку, которую нашли в пакете - пожалуйста, прочтите это.
Good documentation is essential for users to fully understand any software. Several PEAR packages lack documentation or have docs which need improvement. Writing documentation provides more information about helping out on this front.
Translating documentation is another important task. Not only does new documentation need to be translated into the existing languages, additional languages are welcome. Also, existing translations need to be brought up to date because the English versions have been changed. Help on how to perform the translation process is in the Revision Tracking section of the manual.
Некоторые разработчики PEAR имеют списки пожеланий на сайте Amazon или других подобных сервисах. Если вы хотите отблагодарить конкретного разработчика - вы можете купить ему что-то из его списка пожеланий. Чтобы выяснить есть ли у разработчика такой список, зайдите в список эккаунтов, посмотрите детали разработчика и вы увидите есть ли у него список пожеланий. Покупка предметов из списков иногда может даже увеличить скорость разработки и уменьшить время, за которое исправляются ошибки =)
answer by Greg Beaver
The package in question does have releases, but none that are stable. There are two solutions.
Set preferred_state to alpha or beta and then install
$ pear config-set preferred_state alpha
$ pear install Packagename
Find out the stability or version number of the latest release and install it directly.
$ pear install Packagename-alpha
$ pear install Packagename-1.5.3
Ответ на этот вопрос находится здесь.
Отвечают Stig Bakken и Martin Jansen.
Если вы хотите сделать обычный модуль, которы не соответствует стандартам кодирования PEAR, то вы можете просто добавить его в pear/PECL/extname (это именно то место, куда будут перемещаться модули из PHP). Если же вы хотите создать модуль, который будет соответствовать соглашениям PEAR, то добавьте его в pear/Foo_Bar, подставив вместо Foo_Bar имя вашего модуля.
Первые составляющие части PEAR находились в директории php4/pear/, и поставлялись вместе с каждым релизом PHP.
Все последующие релизы PEAR не будут поставляться вместе с PHP. PEAR просто стал слишком большим для того, чтобы поставляться с каждым релизом. Поэтому, было принято решение разделить эти два проекта и создать новую директорию в CVS - pear/. Оставшиеся в php4/pear/ элементы в скором времени тоже будут перемещены. Вместе со следующими релизами PHP будут поставляться только базовые классы и менеджер пакетов PEAR.
Отвечает Stig Bakken.
Структура директорий php4/pear/ соответствует дереву дистрибутива, который по умолчанию находится в директории /usr/local/lib/php, и была организована как обычное иерархическое дерево. Однако сейчас, структура директорий pear/ основана на разделении на пакеты. Теперь файлы, которые находятся в поддиректориях пакетов абсолютно не зависят от пути, куда они будут установлены.
Отвечает Stig Bakken.
В CVS код проекта PEAR разделяется на пакеты, иерархия пакетов отражается лишь на том, где будет установлен пакет в процессе инсталляции. Например, если вы хотите использовать класс XML_RPC, то вам следует включить в ваш код файл "XML/RPC.php". Будет логично, если этот файл будет доступен в CVS как pear/XML/RPC.php , но это как раз не тот случай. XML_RPC - это независимый пакет, который находится в своей собственной ветви CVS, поэтому файл RPC.php на самом деле находится в CVS по адресу pear/XML_RPC/RPC.php. Файл описания пакета (package.xml) используется для того, чтобы определить конечный путь установки пакета.
Такая организация дерева CVS позволяет значительно упростить управление пакетами.
Да. Однако, для этого вам нужно пометить проект в документации как экспериментальный. Лучший способ это сделать - изменить тэг <status> в файле описания проекта - package.xml. Значения этого тэга:
снимок с CVS на определенную дату
релиз для разработчиков, которые хотят протестировать пакет, качество кода может варьироваться от pre-alpha до stable
начальная стадия разработки, все еще может поменяться (API, поведение) без каких-либо предупреждений, возможны серъезные баги
API уже не должен изменяться, пакетом можно пользоваться, но баги все еще возможны
пакет был протестирован, API устоялся, документация написана; этот релиз рекомендован для широкого использования
Примеры - это вообще хорошая вещь. Особенно, если ваш класс имеет достаточно сложный API. Однако примеры - это только часть документации, но не её замена. Документация и примеры должны находиться в поддиректории 'docs' директории пакета.
Особенно рекомендуется прилагать тестовые скрипты, если ваш класс нужно компилировать, если он требует специфических модулей/программ или ему необходимы дополнительные файлы (например, шаблоны или изображения). Храните их в директории 'tests'.
Никаких проблем с конкурирующими пакетами не возникает, однако мы бы хотели избежать появления 10-ти классов шаблонов, 7-ми различных классов по работе с почтой и 3-х врапперов для баз данных, которые будут выполнять одни и те же действия, отличаясь только именами функций.
Для начала, задайте себе вопрос: "Почему я хочу добавить новый пакет?". Самые плохие варианты ответа это: "Хочу увидеть мое имя в списке участников PEAR" и "Я не понимаю API уже существующего пакета".
Обычно, причиной добавления нового пакета является отсутствие функциональности, особенности поведения или проблемы со скоростью/эффективностью у существующего пакета. В этом случае, вы должны удостовериться в том, что расширить или улучшить этот класс/пакет невозможно. Если это действительно так, то вам действительно следует добавить новый пакет. "Действительно невозможно" означает, что нет никакой возможности добавить новую функциональность без изменения основ класса/пакета.
Если вы все-таки решили создать новый класс - старайтесь поддерживать совместимость API со старыми классами настолько, насколько это возможно. Если это невозможно в принципе - попробуйте сделать враппер для поддержания совместимости. И неважно, что этот враппер может требовать значительных ресурсов - так или иначе, но он значительно упростит процесс миграции.
Добавление конкурирующего класса обязательно должно быть согласовано в листе разработчиков PEAR!
Общие вопросы по использованию PEAR и его составляющих следует задавать в листе рассылки pear-general@lists.php.net .
Вопросы, касающиеся разработки PEAR и его компонентов следует задавать в листе pear-dev@lists.php.net.
Вопросы по веб-сайту PEAR пишите в лист pear-webmaster@php.net.
Информация о подписке на эти списки рассылки находится здесь.
Официальным языком всех этих рассылок является английский и постарайтесь быть повежливей =).
Да. Вы должны подключать каждый пакет, который вам требуется, с помощью require_once() или include_once (), даже если он уже подключен в другом пакете.
Для того, чтобы PEAR работал под Windows, вам нужно всего лишь добавить путь к дистрибутиву PEAR (обычно это c:\php\pear) в директиву include_path в файле php.ini.
Примечание: Есть несколько классов (например Schedule/At.php), которые не будут работать под Windows, т.к. они используют команды, встречающиеся только в *nix-системах.
Отвечают Jan Lehnardt, Tomas V.V. Cox и Rasmus Lerdorf.
Любую из лицензий ПО с открытыми исходниками или свободного ПО. Cм. список лицензий ПО с открытыми исходниками здесь и список лицензий, который были приняты Фондом Свободного ПО - здесь. Выберите любую из этих двух списков. Однако, это не должна быть GPL-совместимая лицензия. Вот примерный список подходящих лицензий: Apache License, Artistic license, BSD license, Common Public License, GPL, IBM Public License, Intel Open Source License, Jabber Open Source License, LGPL, MIT license, Mozilla Public License, PHP License, Python license, Python Software Foundation License, QPL, Sleepycat License, Sun Industry Standards Source License (SISSL), Sun Public License, W3C license, zlib/libpng license, Zope Public license.
Рекомендуется использовать лицензии PHP, LGPL или BSD.
Учтите: если модули из PECL собираются вместе с PHP, то их лицензия должна быть совместима с лицензий PHP. Это означает, что модули PECL с лицензией GPL не могут быть использованы вместе с PHP, т.к. это будет нарушать лицензию GPL. Аналогичная проблема возникает, если ваш модуль использует библиотеку с GPL-лицензией - лицензия будет нарушаться. Если использование такой библиотеки необходимо - попросите разрешения у её автора.
Для того, чтобы распространять пакет из PEAR/PECL под определенной лицензией, добавьте её в начало каждого файла исходного кода, а так же добавьте ее тип в тэг <license> файла описания пакета (package.xml).
Отвечает Stig Bakken.
Использование пробелов вместо табуляций - это единственное решение, которое позволяет быть уверенным в том, что код отображается одинаково во всех редакторах и просмотрщиках. Большое количество редакторов использует длину табуляции, равную 4-м пробелам, но значительно количество терминалов и утилит использует для этого 8 пробелов. Пример:
printf("%s",
$arg);
printf("%s",
$arg);
И наоборот:
if ($foo &&
$bar) {
}
if ($foo &&
$bar) {
}
В обществе, подобном PEAR, где состоит большое количество людей, использующих различные системы и редакторы, использование табуляций просто бессмысленно. Участники будут бесконечно изменять файлы для того, чтобы сохранить нормальное форматирование в их редакторе, изменяя его при этом для всех остальных. И только пробелы могут позволить коду выглядеть одинаково везде.
Jamie Zawinski тоже об этом как-то написал, см. здесь.
Существует также утилита Astyle, которая создана для конвертации кода в соответствующий вид.
Unlike other aspects of PEAR development, the windows build of PHP 4.3.x is not tracked in CVS. Instead, it is located on the machine that builds windows snapshots. Often, this will not be updated when the rest of PEAR is updated. Note that PHP 5.x releases use a different build system and are automatically updated to the latest versions of PEAR.
If you find that PHP 4.3.x has out-of-date versions of packages, or no longer works, then please report that the windows bundle of PEAR is out of date to pear-dev@lists.php.net
Working on the translations is not just translating an English file and commiting the results. Much of the work is needed to update the already translated ones, to get in sync with the content of the English files. To follow the modifications in the English tree, you should subscribe to the PEAR documentation mailing list to get CVS commit messages, or read the archives. If you never update your files, the translations can get useless.
Updating a foreign language file can get difficult, as you may not know when and who translated that file, so you may not know where you should look for the updates needed. We have one system for tracking the revisions and modification dates of the files in peardoc.
Instead of storing all responsibilities in a central file, the revision comment system stores them in the files they provide information about. Information about translator, revision numbers, and status information is stored in the revision comment. Let's see what would be in the header of the example file bookinfo.xml file in this case:
<!-- EN-Revision: 1.16 Maintainer: jane Status: ready --> |
We can see the revision number for the last english file used to update the translation (EN-Revision: 1.16), the translator cvs account name. But we can also add some other status information in the case it is needed (eg. "partial" for incomplete translations). This revision comment system is basically about storing the information in the XML files, and not in a central place. This is extremely convenient now, as there are more than 2400 files in the English tree.
Currently, all three fields (English revision, Maintainer, Status) are needed. Maintainer is intended to be a CVS user name, or some nickname without a space, status can be anything without a space. Note, that this header is not updated by CVS (in contrast with $Revision, which is updated automatically). This is only updated when you edit the contents of the comment yourself.
You may see this as a good thing, but using these comments, you lose the quick look on the whole list of your files. No, you do not lose this, but get much more! If you would like to build a full list of you files, you can go to the /peardoc/ directory and run:
./scripts/revcheck_pear.php xx > revcheck.html |
There are some optional extensions introduced for this script, to be available in this generated HTML page. This is why the translation.xml files are introduced. Here comes a simple translation.xml file for the imaginary xx language :
<?xml version="1.0" encoding="iso-8859-1" ?> <!DOCTYPE translation SYSTEM "../dtds/translation.dtd"> <translation> <intro> This is some introductory text for the xx language translators about who is the manager of the translation, and where to find more information. This paragraph is printed on the top of the generated revcheck.html page. </intro> <translators> <person name="Joe Doe" email="joe@hotmail.com" nick="joedoe" cvs="yes" editor="yes"/> <person name="Jane Smith" email="jsmith@yahoo.com" nick="jane" cvs="yes"/> <person name="Joe Forever" email="joe@forever.net" nick="joefo" cvs="no"/> </translators> <work-in-progress> <file name="appendices/aliases.xml" person="joedoe" type="working"/> <file name="functions/dbx.xml" person="joefo" type="working"/> </work-in-progress> </translation> |
There are two optional parameters you can add to a <file>, if you would like to record it: the date and revision. Date is assumed to be the date when the work was started, revision is the checked out revision of the English file used to start the work (denoted as CO-Revision in the generated table). There is currently no fixed format for the date parameter.
Another addon to this system is just to give credit to all people who worked on one file, and not just the current maintainer. To achieve this goal, we added the credit comments. One credit comment in eg. history.xml may look like this (in case Joe Doe translated the file initially, but Jane followed him to be the maintainer):
<!-- CREDITS: joedoe --> |
You are seeing the warnings because pear.php.net uses a SSL key that is signed by CAcert, whose root certificate is unfortunately not bundled with most browser.
If you are using a Mozilla browser, you can import the certificate on this site by clicking on the link "Root Certificate (PEM Format)". When asked if you want to trust the new Certificate Authority, you need to check at least the "Trust this CA to identify web sites." box and click "Ok".
People using Internet Explorer may find help here.
Mac OS X users must download the above mentioned PEM file. The certificate can then be imported with the "Keychain Access" utility via "Import" in the "File" menu.
One of the jobs of the PEAR Group is to issue administrative documents about diverse topics in PEAR. This chapter contains all of them.
Let's assume we have a package The_Package_Name that contains one or more sub-classes (eg. The_Package_Name_Module), with some documentation (perhaps a README, copies of RFCs, etc.), a battery of test scripts (unit tests, regression tests, etc.), and it uses some data files (localization strings, etc.), the dir tree would look like:
The_Package_Name |-- Name (contains Module.php) |-- data |-- docs | `-- examples |-- misc |-- scripts `-- tests |
Name refers to the last part of the The_Package_Name, all subclasses of the main class, should be put in there or subdirectories of it. You can refer to http://cvs.php.net/cvs.php/pear/Cache_Lite/ - the directory Lite as an example (this basically documents what we currently do anyway).
The data and misc directories are optional, because it will not make sense to have them for every single package in PEAR.
The directories that are required are docs/examples and tests. A package may have no extra documentation, but it should have at least one example. There must also be some basics test to be able to verify that the package is working. The preferred type of testing script system to use is PHPUnit or .phpt. But for now we would be content with any sort of test script.
Files in scripts will be installed into a directory available in $PATH, such as /usr/local/bin.
Anything that does not fit any of the above categories is placed into the misc directory.
Maintainers are expected to modify their existing packages to match this new standard.
The PEAR Group would like to announce the following refinement of the current license FAQ entry.
Vote result: 5 (+1), 0 (-1), 3 (+0)
The current list allows a great number of licenses which vary greatly. This means that users may have to learn the in's and out's of alot of licenses. Also some of the license choices impose comparitively high restrictions to the standard PHP license (GPL, QPL ..). As PEAR aims to extend the functionality provided by PHP users of PHP should fairly safely be able to also use any PEAR package without licensing worries, be it for commercial or non commercial, closed or opensource use.
Therefore with this announcement the license choices are reduced to the following short list:
PHP License
Apache License
LGPL
BSD style
MIT License
Other licenses may be accepted on a case by case basis, but will have to fit the above criterias. This decision has been made to simplify the current situation, and as with all decisions is open to be refined in the future using the RFC proposal methodology.
All packages, which are already part of PEAR as of now, which use other licenses, do not need to follow this regulation.
Замечание: In the meantime the FAQ entry linked above has also been updated to reflect the decisions from this document.
The goal is to make it possible to be able to run multiple major versions in one script.
For this reason new major versions (BC break or when the maintainer feels it makes sense as a result of dramatic feature additions or rewrites) require a new package using the following naming convention in the following order of preference (where 'Foo' is the package name and 'X' the major version number):
FooX
FoovX
Foo_vX
The choice should be made based on preventing current and future misleading or ambiguous names. This means good care should be taken in making the right choice for the package. Obviously the first two allow for some ambiguity (is DB2 a package for IBM's DB2 or just the major version 2 of DB? - is IPv4 a package for IPv4 or is it the 4th major release if IP?). They don't break the idea of "_" mapping to directories (the class DB_NestedSet implies that there is a nestedset.php in the DB dir). The last one prevents any ambiguity but it's the least visually pleasing and also breaks the '_' to directory mapping and is therefore the last choice.
We also came to the conclusion that the pear installer should not be clever about the relationship between two major releases aside from printing out notices about the fact that there is a newer major version when a user installs an earlier one. However all major versions of a package will be listed on one package home. This is especially important in order to not break tutorials that cover older major releases (tutorial xyz for major version 1 simply says 'pear install Foo' - if the system would then install 'Foo2' the user might be in for an unpleasant surprise).
Therefore, new major versions are for all intents and purposes new packages with the above mentioned exceptions. The names of these new packages are derived using one of the above mentioned naming conventions.
Sometimes a package is left without care for a long time. It becomes lonely and full of bugs. This is a very sad situation and somebody needs to step up to remedy it.
The following are considered orphaned packages:
A package with bugs open for longer than 2 months and the developers have not commented on the bug or made any commits to CVS during that time frame.
A package that has no open bugs and has bug fixes committed to CVS but does not have a release within 6 months of the bugs being fixed.
A package owned by somebody who is commonly known to be inactive.
A package denounced by its leads (i.e. The lead actually says that he is no longer maintaining it on pear-dev)
A QA core-team member tries to contact the current maintainers and developers (cc'ing the QA list) asking about an update about their work on the package.
A package lead answers:
he states that he has no interest in the package anymore, he allows QA team to take the necessary steps
he states that he still intends to work on the package, but is busy at that point. Either a timeframe will then be decided upon by the lead and QA during which some activity must occur (i.e. I'm going to be busy the rest of this month but I'll get back to it on the 3rd of next month) OR a second lead developer will be sought to continue development
he states that he still intends to work on the package, but is busy at that point. Either a timeframe will then be decided upon by the lead and QA during which some activity must occur (i.e. I'm going to be busy the rest of this month but I'll get back to it on the 3rd of next month) OR a second lead developer will be sought to continue development
A message will be sent to pear-dev asking for volunteers.
If you are willing to take over a package you must notify the QA list and state who you are and why you want to take over.
If the QA team feels the person who stepped up is appropriate and capable, the team will make this person a new maintainer. In case several persons step up a case by case study will be carried out to assign new maintainer-ship.
If a package is orphaned, a warning and a call for maintainers will be displayed on the main package page.
Refers to the whole QA team (core and mailing list members)
Refers to the 6 elected QA team members
It happens more or less often that
PEPr proposals get stuck in a specific proposal phase,
PEPr proposals get accepted, but no package is registered / released.
In these two cases PEAR QA should step in and try to get in touch with the specific proposers. If the proposer is no more interessted in the proposal, PEAR QA should search for a new maintainer for the package or the proposal should be deleted.
For these steps the following time frames are proposed:
For proposals in stages "draft" and "proposal"
PEAR QA posts a reminder comment to the proposal after 1 week of inactivity.
If the proposer does not react within 2 weeks, the proposal gets deleted.
For proposals in stage "finished"
PEAR QA tries to contact the maintainer 4 weeks after the proposal is finished and no release has been throwen.
If the maintainer can not be contacted within 4 weeks, PEAR QA starts searching for a new maintainer.
If no new maintainer is found within 4 weeks, the proposal gets marked as orphan.
Finished proposals should not be deleted, but marked as orphan. This marker should have the following content:
To the name of the proposal the following tag will be added: [QA-ORPHAN].
To the describtion of the proposal the following text will be added at the top: "This proposal has been marked orphan by PEAR-QA on <DATE> because of the inactivity of the proposer. This means, that the proposal is invalid from this date on. If you have a similar proposal or want to re-activate this proposal, feel free to create a new PEPr proposal for it.".
If you are planning to contribute a new package to the PEAR project, this guide will provide you with the necessary information to get you started The Right Way (tm).
We will start by describing the cases in which it makes sense to contribute and in which not. After we have ensured that the package you want to contribute fits into PEAR, we will describe how to get started with the community. Once you are confident about the inner workings of the PEAR developer community, we will explain how to start the formal process of proposing a new package and we will give some tips for making your first package as successful as possible.
In this chapter we describe the cases in which it makes sense to contribute code to PEAR and in which it does not. This description is by no means complete. If you are unsure, if your contribution could be included into PEAR, contact the developers mailing list.
As you may have already noticed while browsing the list of existing packages, the PEAR packages provide a (often abstract) solution for a general problem. Thus your code will most likely fit into PEAR if it solves a problem that will not only occur in one (e.g. your) specific application, but that occurs in a lot of (web) applications. Examples are:
Support for Network protocols
Object oriented wrappers that provide easy access to otherwise complicated or less intuitive PHP extensions.
Parsing different XML dialects.
The PEAR packages that provide XML parsing functionalities can be found in the category browser.
No matter which area is covered by a package, the API should be as abstract as possible (while not becoming too complex), so that it can be utilized painlessly in as much use cases as possible.
A rough rule of thumb is that code which solves a problem that exists in one or only very few projects is not convenient for inclusion into PEAR because most people will not benefit from it.
However, this does not mean that "niche software" cannot be included in PEAR. In the Math section we have a number of elaborate packages that solve different kinds of algebraic problems. While those problems do not occur in average applications, the packages are very abstract and scientific projects benefit a lot.
Apart from code that does not fit into PEAR because of a lack of abstractness, there is another type of code that currently cannot be contributed to PEAR: Full web applications. We do however accept developer tool application like phpDocumentor but not end user applications.
Despite the fact that the "A" in PEAR stands for "Application" there is a simple reason why applications are not yet supported: Until now nobody has gotten around to make the infrastructure like the PEAR installer capable of handling packages that provide complete web applications.
When the situation changes, this site will be updated.
Upon determining your code fits into PEAR, you should get started with the PEAR community. In this chapter we will provide several ways, in which you can establish a first contact with the other PEAR developers, which will hopefully be your future open source fellows. Additionally we will tell you the different places, where you can find more information about the inner workings and rules of PEAR.
Mailing lists naturally are the most important way to communicate in projects like PEAR. We are running a number of public mailing lists, which are listed on the PEAR website. For starters the PEAR developers mailing list pear-dev@lists.php.net is of major importance for you: This mailing list is the place where the maintainers get together to discuss various aspects of their packages and this list is also the place where new packages are discussed.
If you would like to get started with maintaining packages in PEAR, you are expected to be subscribed to this mailing list. (Subscription instructions)
Замечание: During your first steps in the PEAR community, you may stumble across the term "pear-dev", which is the abbreviation for the developers mailing list in PEAR's lingo.
Some people enjoy communicating via IRC channels. We are running the channel #pear in the server network of EFnet. At this channel some of the most active PEAR developers hang out regularly. However for serious inquiries or discussions, you should mail to the developers mailing list.
The PEAR Group occasionally publishes so called Administrative Documents, which describe the Group's decisions. You are expected to read those documents before starting serious contributions to PEAR, because they contain important information about the inner workings of PEAR. The developers mailing list will be informed, when new documents are added, so you do not need to visit the site frequently.
This manual contains the Developer Guide, which provides valueable information as well.
The Coding Standards describe the standards which PEAR code must adhere to.
In the early times of PEAR, all new packages were proposed by an informal email to the PEAR developers mailing list. Over the time, the number of new proposals increased quite dramatically, making it hard to keep track of all the proposals.
A web-based proposal handling system was established to solve these problems. The system is called PEPr. It is pronounced like the spice and stands for "PEAR Proposal system".
This chapter describes the requirements and the workflow for a PEPr-based proposal. After that we will provide you with information, on how to actually start a proposal. Finally, you will learn what to do once the proposal is finished.
After reading this chapter, you will will be able to start a proposal for your code right away.
The following enumeration lists the most important things that need to be done or be made available before starting a new proposal.
Finding a name for the package
It is obvious that each package needs to have a unique name. To get a "feeling" for proper package names, you should browse the list of existing packages.
Choosing a name for the package is an iterative process and it is likely that you will change the name at a later stage of the proposal process.
Finding a category for the package
Similar to each package having a unique name, it has to be placed in one of the categories, which are listed in the package browser as well.
Writing a package description
For starting the proposal you will need to write a description of the package. This description does not need to mention every detail of the package, but it should at least outline the basic concept and feature set. When your package has been accepted, you will have to come up with a single-line summary and a fulltext description.
Choosing a license for the package
Each package has to be licensed under an accepted OpenSource license. If you are unsure about the license, you should opt for the PHP License. The PEAR Group has issued a License Announcement, which provides further details concerning this topic.
Writing examples and documentation
Without proper usage examples and documentation, neither will the PEAR developers be able to evaluate your package nor will users be able to make use of your package.
Listing dependencies
Making a list of dependencies basically means that you write down all external entities such as other PEAR packages, certain operating systems or external applications, which are required to use your proposed package.
For every package you should start a proposal in PEPr as a draft to initiate dicussion on the developers mailing list.
By discussing the package with the PEAR developers you will easily be able to find out if:
there are technical issues with the package/code
a package with similar functionality already exists
there are people working on something similar, so you can join forces
etc.
By reading between the lines, you should also be able to find out if you will be able to gather enough positive votes in the formal proposal process.
Be aware that people will scrutinize your code, so be prepared for criticism (both positive and negative) and save everybody a bunch of time by making sure your scripts adhere to the Coding Standards.
Please note that PEAR is an international project. People come from different cultural backgrounds where english may not be their native tongue. Misunderstandings may happen because of that, so assume the person is trying to do good. Do not worry if your English is not perfect but do try to be as clear as possible and do not hesitate to ask for advice.
To be able to use the proposal tool (PEPr), you have to apply for a PEAR website account. This account will usually be granted within one or two days. After that you can open a new proposal using the "New Package Proposal" interface.
The package proposal process is divided into 4 stages: "Draft", "Proposal", "Call for Votes" and "Finished". Every proposal has to run through all of these stages. During each stage (except for the draft stage) an email is send to you (the proposer) and the PEAR developers mailing list for any action.
At first your proposal is a draft. This simply means you can edit it, view it and it is shown up on the PEPr overview page as a draft. This stage is for you to play around with PEPr, to shape your proposal nicely and to prepare it for the proposal process. You can switch to the next stage when ever you want to publish your proposal and get feedback from the PEAR community.
After switching to the stage Proposal you have a real proposal. Either through email or through PEPr itself the community will give you hints and ask questions about the proposed package. Generally it is a good idea to follow these suggestions, but sometimes people in the community will have different visions for your package, which should be sorted out during this stage. After a week of comments you may switch to the next phase. You should only switch to the next stage, if you are sure that the PEAR community will accept your package.
The next stage is the voting stage, during which you may not change your proposal anymore. You may not edit nor delete the proposal from now on. During the proposal stage, "Call for Votes," every active PEAR maintainer may give one vote on the proposal. Votes are given using the numbers -1, 0 and +1, where -1 means "I'm against this package to be added to PEAR in the current form," +1 says "I'm in favour of getting this package into PEAR in the current form" and 0 means "I have looked at your package, but I am undecided." The time to vote for a package is 7 calendar days. If after this time less than 5 votes have been cast, the developers get another 7 days to cast their votes. After this time the voting is ended, whether there are 5 votes or not.
Votes on proposals can be bound to a condition. These conditional votes indicate that you have to fulfil a certain condition the voters expect to be fulfilled. If there are conditional votes you are expected to read and follow them! The conditions on a vote will be provided in the votes comment. Each vote may have comments. Reading those is always a good idea!
Now your proposal is finished. To determine if the proposal was successful or not, the sum of all votes is computed. If the result is greater or equal to 5 the proposal has been accepted. Otherwise we are sorry to say, that the community has decided to reject it. Have a look at their comments during proposal and vote stage to find out why. Maybe you can rework your package and propose it again, but please do not try to hand in a proposal the same way twice.
If your proposal has been accepted, you may put your package into PEAR. If this is your first proposal, please contact the PEAR Group via email to get your current PEAR website account upgraded to a full featured developer account. After that, you can register your package and upload releases.
The process of preparing and uploading a release is described in the Developer Guide.
In general you may not edit or delete your proposal after it has left the Proposal stage. In urgent cases you can contact the PEAR community via the developers mailing list to reach a PEAR website administrator to do a change. This is heavily discouraged however! You should have made everything clear to the community during the Proposal stage to ensure a hassle free voting process. Even if the voting has a negative result, this is no reason to delete it.
If you want to become the new lead maintainer of a package that is marked as unmaintained on the PEAR website, the following section will explain to you the necessary steps for this to happen.
The first thing is to inform the PEAR Quality Assurance mailing list about your intention. If you have not been involved in PEAR prior to that, it is a good idea to write a few words about you and your motivations.
The QA team will then state whether you can take over the package or not, eventually explaining why. You can then apply for an account for the PEAR website unless you already have one. The PEAR Group will have to grant this account, and afterwards the QA team will assign you as the new lead maintainer for the package.
If the sources of the package are kept in the PHP CVS repository, you will also need an account for this. You can sign up for it on the PHP website. Please mention in the purpose field of the request form that the PEAR QA team has told you to get an account, so that your request can be processed faster. CVS accounts are managed by the PHP Group, so PEAR unfortunately has only limited influence on this process.
Замечание: In case you already have a CVS account for cvs.php.net, it is only necessary for you to get additional "karma" for the module where the package resides. You can request this karma by sending an email to the PEAR Group. (Please also mention in this mail that you have already talked to the QA team.)
If everything has worked out well, you should by now be the lead maintainer of the previously unmaintained package. If not, don't hesitate to ask the people on the QA mailing list for help.
Основная цель создания данного руководства - предоставить разработчикам, которые хотят участвовать в проекте PEAR, всю необходимую для этого информацию.
Первая часть этого руководства содержит описание преимуществ, которые получает разработчик, используя код PEAR в повседневной работе. После этого мы покажем вам как добавить код в PEAR. А потом расскажем каким образом любой разработчик может помочь становлению PEAR.
PEAR состоит из кода только высокого качества, который соответствует стандартам кодирования PEAR. Для вас это значит, то вы используете код с cоответствующим API, который основан на стандартных компонентах и который использует один и тот же механизм управления ошибками везде.
Учтите, что это не относится к коду, который находится в PECL: в PECL весь код соответствует стандартам кодирования PHP.
PEAR дает вам шанс предоставить широкой публике, в лице многочисленных разработчиков на PHP, использовать ваш код. Подробная информация о том, как добавить ваш код в PEAR, находится здесь.
Есть несколько требований, которые должны соблюдаться для того, чтобы ваш код был добавлен в PEAR:
Соответствие стандартам кодирования
Если вы хотите добавить ваш код в PEAR, то он обязательно должен соответствовать стандартам кодирования. В свое время, после множества дискуссий о том, нужны стандарты или нет, было принято решение - необходимы. Пожалуйста, не пытайтесь продолжить споры на эту тему.
Должна быть возможность расширения кода и добавления новой функциональности ("forward-compatible" code).
Помните: ваш код должен легко расширяться, добавление новой функциональности не должно вызывать никаких проблем. Если у вас никак не получается сделать подобный код без изменения принципов работы кода, то вам, видимо, еще рано добавлять код в PEAR, попробуйте перепроектировать код.
Документация в соответствующих форматах (plain text, docbook)
Ваш код должен поставляться с соответствующей документацией в одном из следующих форматов:
Plain Text
Замечание: Существуют планы реализовать автоматическую систему конвертации формата phpDocumentor в формат Docbook XML, который уже будет добавляться в официальное руководство автоматически. Но пока вам придется писать документацию вручную.
Автор кода ("вы") должен иметь желание и возможность поддерживать в будущем свой пакет (или пакеты) и выпускать новые версии для исправления ошибок.
Если у вас нет желания поддерживать ваш код, это значит, что добавлять его в PEAR нет смысла. Поддержка кода - это в первую очередь оказание помощи другим разработчикам, которые используют ваш пакет, в основном с помощью листов рассылки, а также выпуск новых релизов кода, исправление ошибок и улучшение функциональности.
Внимание |
Код может быть удален из PEAR, если его автор не желает более заниматься его поддержкой и никто другой такого желания не проявляет. |
Присвоение новому пакету правильного имени
Одна из самых важных задач при добавлении вашего кода в PEAR - это нахождение наиболее подходящего имени для вашего пакета.
Общие правила наименования пакетов таковы: <Категория>_<Имя>. Имя <Категории> должно быть выбрано из уже существуеющего списка категорий PEAR (например, "HTTP", "Net", "HTML"). Вторая часть имени - это имя самого пакета (например, "Upload", "Portscan", "Table").
Если вы считаете, что ваш пакет не подходит ни к одной из существующих категорий, вы можете попросить создать новую. Однако, мы стараемся сохранить как можно более простую структуру категорий.
В качестве исключений из общих правил, имя пакета может содержать более одного имени категории. Например, пакет HTML_Template_PHPLIB : множество категорий в имени пакет означает, что пакет PHPLIB является частью категории Template, которая, в свою очередь, принадлежит к категории HTML. В данном случае имя формируется именно по такому принципу потому, что в PEAR могут существовать шаблонные системы, которые не будут работать с HTML, а будут предназначены для использования с другими технологиями.
Если вы хотите получить совет или нуждаетесь в помощи при выборе имени пакета - спросите в листе разработчиков.
Представление кода разработчикам PEAR
Второй шаг, который вам необходимо выполнить для добавления вашего пакета в PEAR - это представление пакета в рассылке разработчиков. Обычно такое представление вызывает порождает обсуждение и небольшое голосование, в котором разработчики будут отдавать свои голоса "за" или "против" вашего предложения. Конечно, вам стоит поучаствовать в этой дискуссии. Получение от разработчика "+1" означает, что ему нравится ваше предложение, получение "-1" - наоборот, это голос "против". При получении более пяти "+1" вы можете перейти к следующему шагу.
Получение эккаунтов
На данный момент можно отличить два вида эккаунтов, которые относятся к PEAR:
учетная запись Pear.php.net
Эта учетная запись нужна вам для того, чтобы вы могли добавлять релизы вашего пакета. С этим эккаунтом вы сможете получить доступ к необходимым страницам на pear.php.net для загрузки новых релизов.
учетная запись на сервере CVS
Если вы хотите управлять вашим кодом с помощью CVS, то вы можете получить эккаунт на CVS для получения доступа к модулю pear на cvs.php.net. Это значительно облегчит участие других разработчиков в разработке вашего пакета.
Если у вас уже есть репозиторий CVS где-то в другом месте (например, на SourceForge) или вы не хотите управлять своим кодом с помощью CVS, то CVS-эккаунт вам не нужен.
Для того, чтобы получить эккаунт на pear.php.net, зайдите на страницу запроса эккаунта в PEAR и заполните форму. Администраторы PEAR получат ваш запрос и создадут вам учетную запись, если найдут причины для этого достаточными. Вам сообщат о конечном результате по е-мэйлу. Учтите, что вам не нужен эккаунт для того, чтобы загружать себе пакеты с pear.php.net.
Для того, чтобы получить CVS-эккаунт, зайдите сюда и заполните соответствующие поля. Вопрос о создании вам эккаунта будет решаться участниками PHP Group.
Процедура выпуска релизов
Для начала, чтобы получить возможность добавить ваш пакет в PEAR, вы должны получить эккаунт на pear.php.net.
Перед выпуском первого релиза вашего пакета, вам следует зарегистрировать сам пакет. Для этого вы должны зайти сюда и заполнить соответствующие поля формы. Пожалуйста, выбирайте имя пакета, которое будет соответстовать пункту первому этой главы.
После регистрации пакета, вы сможете выпустить первую версию пакета.
Перед этим необходимо создать файл описания пакета. Этот файл в формате XML, с именем package.xml должен находиться в корневой директории исходников пакета.
Дополнительная информация о файлах описаний пакетов находится здесь.
После того, как вы создали этот файл, запустите
$ pear package |
Теперь заходите на эту страницу и загружайте tgz-файл на сервер. После этого выпуск версии 1.0 пакета уже можно считать состоявшимся.
Файл описания пакета, package.xml, как становится понятно из его имени - это XML-файл, который содержит всю информацию о пакете из PEAR.
В этой главе описываются элементы, которые могут присутствовать в файле описания пакета, а также обсуждаются способы создания такого файла для вашего пакета.
Корневым элементом файла package.xml является элемент <package version="1.0">. Допускаются следующие вложенные элементы:
<name>: Имя пакета.
<summary>: Краткое описание пакета.
<description>: Полное описание пакета.
<license>: Лицензия (PHP License, LGPL и т.п.). Более подробная информация о допустимых лицензиях в PEAR содержится в FAQ.
<maintainers>: Информация о создателях пакета.
<maintainer>: Информация о каждом создателе отдельно (может присутствовать несколько раз, для каждого разработчика).
<user>: Имя аккаунта разработчика.
<role>: Роль разработчика в процессе создания пакета. Может принимать значения: lead, developer, contributor, helper.)
<name>: Настоящее имя разработчика.
<email>: Адрес электронной почты.
<release>: Информация о текущем релизе.
<version>: Номер версии релиза.
<state>: Статус релиза. (Может быть alpha, beta, stable, devel или snapshot)
<date>: Дата релиза.
<notes>: Комментарии к релизу
<filelist>
<file role="xxx">: Имя файла
<dir name="xxx" [role="xxx"]>: Имя поддиректории. Поддиректория, в свою очередь, может содержать другие элементы <file role="xxx">.
<deps>: Список зависимостей пакета.
<dep type="xxx" rel="yyy" optional="yes">name</dep> : Более подробную информацию о зависимостях можно найти ниже.
<changelog>: Changelog(история изменений) пакета.
<release>
<version>: Версия конкретного релиза.
<state>: Статус конкретного релиза.
<date>: Дата конкретного релиза.
<notes>: Комментарии к релизу.
Внутри элементов допустимы буквы A-Z и a-z. Остальные символы, такие как И должны задаваться через сущности (entities) (в данном случае: é).
При использовании PEAR_PackageFileManager версии 1.4.0a2 и выше для создания package.xml, файл менеджер подставит сущности для недопустимых символов автоматически.
При написании файла описания пакета вручную, вам придётся вводить сущности самим. Список наиболее часто используемых сущностей находится на: http://www.evolt.org/article/A_Simple_Character_Entity_Chart/17/21234/ Если нужных вам символов в этом списке нет, попробуйте поискать их в других http://www.oasis-open.org/docbook/xmlcharent/0.1/index.shtml .
После создания файла package.xml, его синтаксис можно проверить с помощью команды
$ pear package-validate package.xml |
Также можно использовать утилиту xmllint, которая идёт в составе libxml2.
xmllint --dtdvalid http://pear.php.net/dtd/package-1.0 --noout package.xml
Пример 16-1. Образец package.xml
|
Этот файл package.xml может послужить вам шаблоном, т.к. он уже содержит все необходимые поля. В большинстве случаев, вам нужно будет всего лишь поменять текст между тэгами, чтобы использовать пример в вашем пакете.
Пример 16-2. Вложенные директории
|
В этом примере демонстрируется очень удобный прием: когда в какой-то из ваших директорий содержатся файлы только одного типа, вы можете использовать атрибут "role" у элемента <dir> вместо того, чтобы добавлять его у каждому элементу <file>.
После прочтения данной главы вы уже можете создавать файл описания пакета. Если у вас все еще есть вопросы по этому поводу - задавайте их в листе рассылки.
Атрибут role в элементе <file> задаёт тип файла и его месторасположение при инсталляции
Таблица 16-1. Возможные значения
Значение | Директория инсталляции | |
---|---|---|
php | Исходный текст PHP | директория определяется по имени пакета |
ext | Расширение, динамически подгружаемая библиотека | директория расширений PHP или PHP_PEAR_EXTENSION_DIR, если определена |
doc | Файл документации | {PEAR_documentation_dir}/Package_Name/ |
data | Файлы данных пакета (графика, таблицы, и т.п.) | {PEAR_data_dir}/Package_Name/ |
test | Тестовые файлы пакета (unit-тесты и пр.) | {PEAR_test_dir}/Package_Name/ |
script | Системные (shell) скрипты пакета | непосредственно директория PHP или PHP_PEAR_BIN_DIR, если определена |
src and extsrc | Исходный код на C или C++ | напрямую не копируется - используется для сборки расширения |
PEAR Package Manager или менеджер пакетов позволяет задавать различные требования к системе. Вы можете определить зависимости от этих требований с помощью элемента <dep>:
Пример 16-3. package.xml с зависимостями Следующий пример показывает, как прописать зависимости от версии PHP не ниже 4.3.0, и от пакета XML_Parser 1.0.
|
Поддерживаются следующие типы зависимостей:
Таблица 16-2. значения type
Значение | Смысл | Пример | |
---|---|---|---|
pkg | Пакет | зависимость от определённого пакета | "HTML_Flexy" |
ext | Расширение | зависимость от определённого расширения PHP | "curl" |
php | PHP | зависимость от версии PHP | "4.2" |
prog | Программа | зависимость от определённой программы в системном пути. Не поддерживается инсталлятором PEAR. | "latex" |
os | Операционная система | требование конкретной ОС | "Linux" |
sapi | Server API | зависимость от определёного Server API. Не поддерживается инсталлятором PEAR. | "Apache" |
zend | Zend | требование конкретной версии Zend API. Не поддерживается инсталлятором PEAR. | "2" |
Внимание |
DTD для файла описания пакета включает и другие типы, которые пока не поддерживаются. |
Атрибут rel определяет отношение между существующей возможностью и требованием.
Таблица 16-3. значения rel
Значение | Смысл | Используется с | |
---|---|---|---|
has | has | существующая возможность должна иметь требование - атрибут version игнорируется | pkg, ext, php, prog, os, sapi, zend |
eq | equal | существующая возможность должна в точности соответствовать номеру версии | pkg, ext, php, prog, os, sapi, zend |
lt | less than | версия существующей возможности должна быть меньше указанной | pkg, ext, php, zend |
le | less than or equal | версия существующей возможности должна быть меньше или равна указанной | pkg, ext, php, zend |
gt | greater than | версия существующей возможности должна быть больше указанной | pkg, ext, php, zend |
ge | greater than or equal | версия существующей возможности должна быть больше или равна указанной | pkg, ext, php, zend |
not | conflicting dependency | зависимость конфликтует с пакетом, они не могут существовать вместе, версия игнорируется. | ext, php |
Has используется, если не определено других значений. Стоит отметить, что rel обязателен для PEAR 1.4.0 и выше.
Атрибут optional может быть указан в случае, когда зависимость не требуется для работы, но её присутствие расширяет функциональность пакета. Допустимые значения "yes" и "no". Если атрибут optional не указан, то зависимость является обязательной. Когда используется optional="yes", это вызовёт сообщения при инсталляции наподобие:
$ pear install <package> Optional dependencies: Package `XML_Tree' is recommended to utilize some features. Package `MDB' is recommended to utilize some features. |
The package definition file package.xml is, as the name already implies, a well-formed XML file that contains all information about a PEAR package. Version 2.0 contains several important enhancements over version 1.0, including
Channel support
Binary PECL packages support (not fully implemented in PEAR 1.4.0)
More specific dependency resolution
For those of you with an existing package.xml version 1.0, you can create an approximate equivalent package using the
$ pear convert |
command. Note that as of version 1.6.0a1, PEAR_PackageFileManager supports package.xml 2.0 with the PEAR_PackageFileManager2 class.
PECL developers: for more information on pecl-specific features, read here.
<?xml version="1.0"?> <package version="2.0" xmlns="http://pear.php.net/dtd/package-2.0" xmlns:tasks="http://pear.php.net/dtd/tasks-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0 http://pear.php.net/dtd/tasks-1.0.xsd http://pear.php.net/dtd/package-2.0 http://pear.php.net/dtd/package-2.0.xsd"> <name>PEAR</name> <channel>pear.php.net</channel> <summary>Any one-line summary</summary> <description>any static long description. This text should not change very much between releases, use the "notes" tag for release notes </description> <lead> <name>Greg Beaver</name> <user>cellog</user> <email>cellog@php.net</email> <active>yes</active> </lead> <date>2005-02-26</date> <time>20:30:13</time> <-- note: <time> is optional --> <version> <release>1.4.0a2</release> <api>1.4.0</api> </version> <stability> <release>alpha</release> <api>alpha</api> </stability> <license uri="http://www.php.net/license">PHP License</license> <notes> Put release notes here. They can be multi-line </notes> <contents> <dir name="/"> <dir name="PEAR"> <dir name="ChannelFile"> <file name="Parser.php" role="php" /> </dir> <!-- /PEAR/ChannelFile --> <file name="Dependency2.php" role="php"> <tasks:replace from="@PEAR-VER@" to="version" type="package-info"/> </file> </dir> <!-- /PEAR --> <dir name="scripts" baseinstalldir="/"> <file name="pear.bat" role="script"> <tasks:replace from="@bin_dir@" to="bin_dir" type="pear-config" /> <tasks:replace from="@php_bin@" to="php_bin" type="pear-config" /> <tasks:replace from="@include_path@" to="php_dir" type="pear-config" /> <tasks:windowseol/> </file> <file name="pecl.bat" role="script"> <tasks:replace from="@bin_dir@" to="bin_dir" type="pear-config" /> <tasks:replace from="@php_bin@" to="php_bin" type="pear-config" /> <tasks:replace from="@include_path@" to="php_dir" type="pear-config" /> <tasks:windowseol/> </file> <file name="pear.sh" role="script"> <tasks:replace from="@php_bin@" to="php_bin" type="pear-config" /> <tasks:replace from="@php_dir@" to="php_dir" type="pear-config" /> <tasks:replace from="@pear_version@" to="version" type="package-info" /> <tasks:replace from="@include_path@" to="php_dir" type="pear-config" /> <tasks:unixeol/> </file> <file name="pecl.sh" role="script"> <tasks:replace from="@php_bin@" to="php_bin" type="pear-config" /> <tasks:replace from="@php_dir@" to="php_dir" type="pear-config" /> <tasks:replace from="@pear_version@" to="version" type="package-info" /> <tasks:replace from="@include_path@" to="php_dir" type="pear-config" /> <tasks:unixeol/> </file> <file name="pearcmd.php" role="php"> <tasks:replace from="@php_bin@" to="php_bin" type="pear-config" /> <tasks:replace from="@php_dir@" to="php_dir" type="pear-config" /> <tasks:replace from="@pear_version@" to="version" type="package-info" /> <tasks:replace from="@include_path@" to="php_dir" type="pear-config" /> </file> <file name="peclcmd.php" role="php"> <tasks:replace from="@php_bin@" to="php_bin" type="pear-config" /> <tasks:replace from="@php_dir@" to="php_dir" type="pear-config" /> <tasks:replace from="@pear_version@" to="version" type="package-info" /> <tasks:replace from="@include_path@" to="php_dir" type="pear-config" /> <tasks:footask/> </file> </dir> <!-- /scripts --> <file name="package.dtd" role="data" /> <file name="postinstall.php" role="php"> <tasks:postinstallscript/> </file> <file name="template.spec" role="foo" /> </dir> <!-- / --> </contents> <compatible> <name>FooPackage</name> <channel>pear.php.net</channel> <min>1.3.0</min> <max>1.5.0</max> </compatible> <dependencies> <required> <php> <min>4.2</min> <max>6.0.0</max> </php> <pearinstaller> <min>1.4.0dev13</min> </pearinstaller> <package> <name>Archive_Tar</name> <channel>pear.php.net</channel> <min>1.1</min> <recommended>1.2</recommended> </package> <package> <name>Foo</name> <uri>http://www.example.com/Foo-1.2.0.tgz</uri> </package> <extension> <name>xml</name> </extension> <os> <name>windows</name> <conflicts/> </os> <arch> <pattern>*-i?86-*-*</pattern> </arch> </required> <optional> <package> <name>PEAR_Frontend_Web</name> <channel>pear.php.net</channel> <min>0.5.0</min> </package> <package> <name>PEAR_Frontend_Gtk</name> <channel>pear.php.net</channel> <min>0.4.0</min> </package> </optional> <group name="remoteinstall" hint="adds the ability to install packages to a remote ftp server"> <package> <name>Net_FTP</name> <channel>pear.php.net</channel> <min>1.3.0RC1</min> <recommended>1.3.0</recommended> </package> </group> <group name="webinstaller" hint="PEAR's web-based installer"> <package> <name>PEAR_Frontend_Web</name> <channel>pear.php.net</channel> <min>0.5.0</min> </package> </group> <group name="gtkinstaller" hint="PEAR's PHP-GTK-based installer"> <package> <name>PEAR_Frontend_Gtk</name> <channel>pear.php.net</channel> <min>0.4.0</min> </package> </group> </dependencies> <usesrole> <role>foo</role> <package>Foo</package> <channel>pear.example.com</channel> </usesrole> <usestask> <task>footask</task> <package>Footask</package> <channel>pear.example.com</channel> </usestask> <phprelease> <installconditions> <os> <name>windows</name> </os> </installconditions> <filelist> <install as="pear.bat" name="scripts/pear.bat" /> <install as="pecl.bat" name="scripts/pecl.bat" /> <install as="pearcmd.php" name="scripts/pearcmd.php" /> <install as="peclcmd.php" name="scripts/peclcmd.php" /> <ignore name="scripts/pear.sh" /> <ignore name="scripts/pecl.sh" /> </filelist> </phprelease> <phprelease> <filelist> <install as="pear" name="scripts/pear.sh" /> <install as="pecl" name="scripts/pecl.sh" /> <install as="pearcmd.php" name="scripts/pearcmd.php" /> <install as="peclcmd.php" name="scripts/peclcmd.php" /> <ignore name="scripts/pear.bat" /> <ignore name="scripts/pecl.bat" /> </filelist> </phprelease> <changelog> <release> <version> <release>1.3.5</release> <api>1.3.0</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <date>2005-02-26</date> <license uri="http://www.php.net/license/3_0.txt">PHP License</license> <notes> * fix Bug #3505: pecl can't install PDO * enhance pear run-tests dramatically * fix Bug #3506: pear install should export the pear version into the environment </notes> </release> <release> <version> <release>1.4.0a1</release> <api>1.4.0</api> </version> <stability> <release>alpha</release> <api>alpha</api> </stability> <date>2005-02-26</date> <license uri="http://www.php.net/license/3_0.txt">PHP License</license> <notes> This is a major milestone release for PEAR. In addition to several killer features, every single element of PEAR has a regression test, and so stability is much higher than any previous PEAR release, even with the alpha label. New features in a nutshell: * full support for channels * pre-download dependency validation * new package.xml 2.0 format allows tremendous flexibility while maintaining BC * support for optional dependency groups and limited support for sub-packaging * robust dependency support * full dependency validation on uninstall * support for binary PECL packages * remote install for hosts with only ftp access - no more problems with restricted host installation * full support for mirroring * support for bundling several packages into a single tarball * support for static dependencies on a url-based package Specific changes from 1.3.5: * Implement request #1789: SSL support for xml-rpc and download * Everything above here that you just read </notes> </release> </changelog> </package> |
Most of the tags for PECL-style PHP extension releases are identical to those for PEAR-style PHP script releases. There are a few extsrc/extbin-specific tags that all PECL developers must know about.
Таблица 17-1. PECL extsrc/extbin-specific tags in package.xml 2.0
Tag | Description of usage | ||
---|---|---|---|
<providesextension> |
The <providesextension> tag must be right after <dependencies>. This
tag tells the installer the name of the extension provided by the package, allowing
different package names from the extension. This could be important for binary packages
(such as PDO and PDO_windows or something along those lines).
| ||
<srcpackage> or <srcuri> |
<srcpackage> or <srcuri> must follow <providesextension>.
Extension binary packages must define either a <srcpackage> tag (for package.xml
containing <channel>) or
a <srcuri> tag (for package.xml containing
<uri>).
|
Each tag that needs further explanation is documented here (unfinished)
Channels are new in PEAR 1.4.0. Channels are a systemized way of differentiating between different download sources. One such download source is pear.php.net, another is pecl.php.net, and there are several third party channels slowly springing up around the net.
The <channel> tag should contain the full channel name, not any alias (don't use "pear", use "pear.php.net".
A good rule of thumb to use when determining what channel name to use is "where do I upload my releases to?" If the answer is pear.php.net, that is your package's channel. If the answer is pecl.php.net, then that is your channel.
If you aren't running a channel server and wish to serve your packages as well as allow other packages to remotely depend on your package, the new uri-based package distribution method is the best choice, see the <uri> tag documentation link below.
If you do not have a channel server and wish to serve your packages so that others can depend on them, use <uri>. This should contain a static uri that links to a single package version's downloadable .tgz
If you do not need to allow external remote dependencies, then simply use the pear.php.net channel as your package's channel.
For instance, if you wish to serve package Foo version 1.1.0 from www.example.com, use the uri "http://www.example.com/Foo-1.1.0". Note that the uri must contain the full path MINUS THE EXTENSION. Provide both Foo-1.1.0.tgz and Foo-1.1.0.tar for users without gzip.
In package.xml 1.0, a developer was documented using the <maintainer> tag inside of a redundant <maintainers> container tag. This has been simplified in package.xml 2.0 both to slightly speed parsing and to make validation of the xml simpler. Now, the contents of the <role> tag has been extracted as 4 tags to describe the maintainers of a package.
In addition, a new internal tag <active> has been added, so that you can honor retired developers' work without having to remove them altogether from package.xml.
WARNING: tag order is important. List leads followed by developers followed by contributors and finally helpers.
In package.xml 1.0, the version was simply the version. package.xml 2.0 splits the concept of versioning into two components, release and api.
The release version is the same familiar versioning concept from package.xml 1.0. This version is validated very carefully by the packager.
The API version is informational only - the installer does not use it. It can be used for a package-time replacement by the installer. This can be very useful when implementing a reflective method such as getApiVersion(). In addition, the API version is very loosely validated, and only requires a version_compare()-compatible version number.
In package.xml 1.0, stability was known as "state" which is not the most accurate description. package.xml 2.0 introduces the term stability and like version splits the concept of stability into two components, release and api.
The release stability is the same familiar state from package.xml 1.0. It can be one of:
snapshot - a frozen picture of development at a particular moment
devel - a very new non-production release. Devel should be used for extremely new, practically untested code.
alpha - a new non-production release. Alpha should be used for new code that has an unstable API or untested code.
beta - a non-production release. Beta should be used for code that has a stable API and is nearing a fully stable release. Regresion tests and documentation should exist or soon follow to qualify as a beta release. Release candidates should use the beta stability.
stable - a production release. Stable releases must have a stable API, and must have regression tests and documentation.
The API stability is informational only - the installer does not use it.
In package.xml 1.0, the license tag only contained the name of the license. In package.xml 2.0, there are two optional attributes, "uri" and "filesource". "uri" contains a uri that identifies the text of a license, such as "http://www.php.net/license" for the PHP License. "filesource" can be used to specify a LICENSE file within an actual package that contains the text of the license.
In package.xml 1.0, the contents tag was <filelist>. The purpose of the tag changed dramatically in package.xml 2.0, warranting a name change. Now, <filelist> can be found in the release section of the package.xml.
<contents> is used to describe the contents of a tarball. Nothing further. All files in the contents tag will be placed into the tarball regardless of whether they eventually get installed by the PEAR installer. This fact can be used to create a very versatile tarball, one that can be directly unzipped and work out of the box as well as be installed by the PEAR installer and work out of the box.
For most release types, contents contains a single <dir> tag that then either contains nested dir tags and/or <file> tags.
The <dir> tag is identical to package.xml 1.0. Required attributes are name and optional attributes are baseinstalldir (the relative location where all files and subdirectories will be installed)
Note that all files must be contained in a single top-level <dir> tag. For simple packages, simply use <dir name="/"> as the directory name
The <file> tag is almost identical to package.xml 1.0. Required attributes are name and role. Optional attributes are baseinstalldir and md5sum. Optional attributes platform and install-as have been replaced by the release tags. Specifically, <install> is used to specify install-as, and the <ignore> tag can be used in conjunction with <installconditions> to exclude packages from being installed on particular platforms.
For those familiar with the platform attribute, the way to handle this example:
<file name="scripts/foo.bat" role="script" install-as="foo.bat" platform="windows">
is to in fact create two release sections. The file tag would then look like:
<file name="scripts/foo.bat" role="script">
and the release section would look like this:
<phprelease> <installconditions> <os>windows</os> </installconditions> <install name="scripts/foo.bat" as="foo.bat"/> </phprelease> <phprelease> <ignore name="scripts/foo.bat"/> </phprelease>
Note that the second <phprelease> tag could just as easily have had an <installconditions> tag containing <os>unix</os>, but this is unnecessary, as the second release will be processed on any system that is not a windows system.
Tasks provide a flexible and customizable way to manipulate file contents or to perform complex installation tasks (hence the name "tasks"). By default, PEAR comes with 4 tasks, but customized tasks can be added simply by adding a file into the PEAR/Tasks directory that follows the conventions of existing tasks. This page does not describe how to create a custom task, only how to use them in package.xml.
There are 3 basic tasks and 1 complex task distributed with PEAR. The basic tasks are "tasks:replace", "tasks:windowseol", and "tasks:unixeol". The complex task is "tasks:postinstallscript". "tasks:replace" is nearly identical to the old <replace> tag from package.xml 1.0, and does a text search-and-replace of a file's contents. "tasks:windowseol" and "tasks:unixeol" manipulate the line endings of a file to ensure that the correct line endings are in place for critical files like DOS .bat batch files and unix shell scripts. "tasks:postinstallscript" allows users to choose to run a script to perform further installation functions.
The replace task has 3 required attributes:
type - This must be either package-info or pear-config. package-info replacements extract information from package.xml itself to use as the replacement text. pear-config replacements use the value of a configuration variable (as displayed by
pear config-show |
from - Text to search for in a file. Traditionally, this text is enclosed in "@" to differentiate it from normal text, as in from="@version@"
to - Abstract item to use as a replacement for all occurences of "from". package-info replacements can be one of version, release_date, release_state, release_license, release_notes, apiversion, name, summary, description, notes, time, date, and for some packages extends, srcpackage, srcuri, and providesextension.
Note that package-info replacements are performed at packaging time, so files contain package-info replacements inside a .tgz/.tar release. pear-config replacements can only occur on the installation system, and are performed at install-time.
This task can be used to enable packaging of windows-specific files (like DOS batch files) on a non-windows system, such as unix systems that convert line endings to \n. Note that this task is performed at package-time, as well as at install-time, so files will contain the correct line endings inside a .tgz/.tar release.
This task can be used to enable packaging of unix-specific files (like sh shell scripts) on a non-unix system, such as windows systems that convert line endings to \r\n. Note that this task is performed at package-time, as well as at install-time, so files will contain the correct line endings inside a .tgz/.tar release.
The postinstallscript task informs the installer that the file it references is a post-installation script.
For security reasons, post-install scripts must be manually executed by the users, and as such the installer has special code that is separate from other tasks.
The <postinstallscript> tag may define parameters that are used by the installer to retrieve user input. In order to support both the web installer and the command-line installer, all processing of input is performed by PEAR and passed to the post-install script in a strict format. All you need to do is define the parameters using xml inside the <postinstallscript> tag.
Here is the xml representing a simple post-install script with parameters:
<tasks:postinstallscript> <tasks:paramgroup> <tasks:id>first</tasks:id> <tasks:param> <tasks:name>test</tasks:name> <tasks:prompt>Testing Thingy</tasks:prompt> <tasks:type>string</tasks:type> </tasks:param> </tasks:paramgroup> </tasks:postinstallscript> |
Note that the only type recognized at this stage is "string" but others will follow. A more complex example follows:
<tasks:postinstallscript> <tasks:paramgroup> <tasks:id>first</tasks:id> <tasks:instructions>The first group of questions relates primarily to your favorite color. Answer wisely. </tasks:instructions> <tasks:param> <tasks:name>test</tasks:name> <tasks:prompt>Testing Thingy</tasks:prompt> <tasks:type>string</tasks:type> <tasks:default>hi</tasks:default> </tasks:param> <tasks:param> <tasks:name>test2</tasks:name> <tasks:prompt>Testing Thingy 2</tasks:prompt> <tasks:type>string</tasks:type> </tasks:param> </tasks:paramgroup> <tasks:paramgroup> <tasks:id>second</tasks:id> <tasks:name>first::test</tasks:name> <tasks:conditiontype>preg_match</tasks:conditiontype> <tasks:value>g+</tasks:value> <tasks:param> <tasks:name>test</tasks:name> <tasks:prompt>Testing Thingy a</tasks:prompt> <tasks:type>string</tasks:type> <tasks:default>hi</tasks:default> </tasks:param> <tasks:param> <tasks:name>test2</tasks:name> <tasks:prompt>Testing Thingy b</tasks:prompt> <tasks:type>string</tasks:type> </tasks:param> </tasks:paramgroup> </tasks:postinstallscript> |
This post-installation script has two parameter groups. The first parameter group has special instructions that are displayed to the user to assist in answering the required prompts. After the first group is processed, the second group is processed (naturally). However, in this case, the second group is a conditional parameter group. A conditional parameter group examines the user input from previous parameter groups and only displays its parameter prompts if a single parameter fits a test. The condition is defined by three tags, <tasks:name>, <tasks:conditiontype>, and <tasks:value>. Note that all three tags are required or xml validation will fail.
<tasks:name> is the parameter name from a previous parameter group. The format of name is groupID::parameterName, so as you see above, "first::test" refers to the <tasks:param> test from the <tasks:paramgroup> first.
<tasks:conditiontype> determines how the parameter input function will process the value of the parameter specified in <tasks:name>, and can be one of three values, "=" "!=" or "preg_match".
=: This (obviously) tests whether the parameters value is equal to the <tasks:value> tag
!=: This (obviously) tests whether the parameters value is not equal to the <tasks:value> tag
preg_match: This uses the content of the <tasks:value> tag as if it were the stuff between / and / in a preg_match() function call. Do NOT include // brackets in the regular expression. In the <tasks:paramgroup> second, the value "g+" will become:
<?php preg_match('/g+/', first::test value) ?> |
The <compatible> tag is designed to be used with a <package> dependency that contains a <recommended> version tag from package pear.example.com/Bar version 1.3.0 like so:
<package> <name>Foo</name> <channel>pear.example.com</channel> <min>1.0.0</min> <recommended>1.5.2</recommended> </package> |
The above dependency can be translated into English as follows: "Use the package pear.example.com/Foo, but only versions 1.0.0 or newer. If pear.example.com/Foo is not installed, install version 1.5.2. If pear.example.com/Foo is installed and is not version 1.5.2, fail unless --force is specified, or pear.example.com/Foo is compatible with me."
That last clause "...or pear.example.com/Foo is compatible with me." is controlled by the <compatible> tag. If package Foo version 1.5.3's package.xml has a <compatible> like so:
<compatible> <name>Bar</name> <channel>pear.example.com</channel> <min>1.2.0</min> <max>1.3.0</max> <exclude>1.2.9</exclude> </compatible> |
This will instruct the installer that pear.example.com/Foo version 1.5.3 is compatible with pear.example.com/Bar versions 1.2.0 to 1.3.0 inclusive, but is not compatible with 1.2.9.
It is very important to note that only existing versions that have been tested with the package should be mentioned in the <compatible> tag. Future versions of pear.example.com/Bar should simply upgrade the <recommended> tag.
<compatible> may contain three versioning tags. The required <min> and <max> are used to define the range of tested and compatible versions, and <exclude> is used to exclude any versions within the range. In the example above, 1.3.0 and 1.2.0 are the highest and lowest versions that may be excluded. There can be an unlimited number of <compatible> tags inside a package.xml.
Dependencies are the most difficult aspect of programming. Using code written by other people can be a nightmare without simple ways to control bugs and API changes. Arguably, the handling of dependencies is PEAR's greatest strength, although there are many other nice features. Regardless of your personal opinion of the importance of dependencies, it is crucial to understand how to specify a dependency, and the different ways to ensure that your package is only used on systems that support it.
In package.xml 1.0, dependencies were relatively simple, but at the cost of usefulness. Specifying a dependency on a package for applications was actually dangerous. If you wished to limit an installed version of a package to a single version, it would mean preventing upgrade at any cost. package.xml 2.0 provides a simple way to enforce stricter dependency versioning without making upgrades onerous.
In package.xml 1.0, dependencies on PHP extensions like PECL extensions was near to a disaster. Extensions had to be present in the php.ini and loaded in memory in order to validate as being installed. This is often impossible, as a different php.ini is used for a production website versus the php.ini used for the pear installer. With package.xml 2.0, dependencies on a PECL-like extension is simple and straightforward, and only requires that the package be installed, and not that the extension be present in memory, although an older style extension dependency is also supported.
package.xml 1.0 supports two kinds of dependencies, required and optional. package.xml 2.0 also supports these two dependency types, but introduces a new kind of dependency concept: an optional dependency group. Dependency groups define a feature set. Instead of thinking "This package optionally depends on Net_FTP and optionally depends on Log" think "To remotely install packages, I need the remoteinstall feature, which needs Net_FTP and the Log package". This grouping allows defining sets of packages and extensions that comprise a feature and must be installed all at once for the feature to function properly.
package.xml 1.0 only supported php, package, and extension dependencies. package.xml 2.0 supports dependencies on php, package, extension, os, architecture, and PEAR installer. In addition, package.xml 2.0 supports depending on a static package located at a url, and depending on a package that provides an extension to PHP like PECL packages.
The PEAR installer dependency is not a dependency on the PEAR package, but a dependency on the currently running PEAR installer, and is more similar to a PHP dependency in that it requires the specified version to be running in memory. This is very useful for circumventing difficult bugs in the PEAR installer that render a package install useless.
The <dependencies> tag re-organizes dependencies into groups and "extracts" attributes into tags. It also un-abbreviates words for clarity and human-readability. The following excerpt of a package.xml version 1.0:
<deps> <dep type="pkg" rel="ge" version="1.3.1">Archive_Tar</dep> <dep type="php" rel="ge" version="4.2.0"/> <dep type="pkg" rel="has" optional="yes">PEAR_Frontend_Web</dep> </deps> |
Approximately translates into this format in package.xml 2.0:
<dependencies> <required> <pearinstaller> <min>1.4.0a7</min> </pearinstaller> <php> <min>4.2.0</min> <max>6.0.0</max> </php> <package> <name>Archive_Tar</name> <channel>pear.php.net</channel> <min>1.3.1</min> </package> </required> <optional> <package> <name>PEAR_Frontend_Web</name> <channel>pear.php.net</channel> </package> </optional> </dependencies> |
These changes were made to simplify xml validation and parsing. Note that unlike package.xml 1.0, the <pearinstaller> and <php> dependencies are required in all package.xml. In addition the <min> tag is required in both <pearinstaller> and <php> dependencies.
The <pearinstaller> dependency defines the minimum version of PEAR that can properly parse and install the package.xml containing it. As with all dependency tags that support versioning, these 4 tags are supported to define versioning:
<min> - minimum version of PEAR required to install this package.xml. This tag is required in all package.xml <pearinstaller> dependencies.
<max> - maximum version of PEAR installer supported. Use with caution! This tag will prevent the package from being installed by anyone with a newer version of PEAR!
<recommended> - recommended version of PEAR installer. This tag is used for strict version control. The installer will refuse to install a package without the --force option unless the version exactly matches recommended. This can be used to provide a level of extra security, as a package can be set to install using a version that is known to work without limiting future upgrades.
<exclude> - incompatible versions of PEAR installer. Use this to prevent the package from being installed by any PEAR version that cannot properly install the package. Multiple <exclude> tags may be used to exclude more than one version.
As with all dependency tags that support versioning, these 4 tags are supported to define versioning:
<min> - minimum version of PHP required to install this package.xml. This tag is required in all package.xml <php> dependencies.
<max> - maximum version of PHP supported.
<exclude> - incompatible versions of PHP. Use this to prevent the package from being installed by any PHP version that cannot properly work with the package. Multiple <exclude> tags may be used to exclude more than one version.
Subpackage dependencies share the same xml format as package dependencies. The subpackage dependency should only be used if a package is split into more than one package. In other words, if the child package contains the same files as any earlier version of the parent package, the child package would normally conflict with the parent package because it would be attempting to overwrite the parent package's files with its own files.
A simple example should make this clear. Package Foo 1.0.0 contains Foo.php and Foo/Bar.php. Package Foo's developers decide to split Foo into two packages: Foo and Foo_Bar. Foo 1.1.0 contains foo.php, and Foo_Bar 0.1.0 contains Foo/Bar.php. Foo_Bar 0.1.0 conflicts directly with Foo 1.0.0, as both contain the file Foo/Bar.php.
If Foo has a subpackage dependency on Foo_Bar, then the installer will ignore the conflict between Foo 1.0.0's Foo/Bar.php and Foo_Bar 0.1.0's Foo/Bar.php just as it ignores the conflict between Foo 1.0.0's Foo.php and Foo 1.1.0's Foo.php.
Understandably, the <package> dependency is PEAR's most complex dependency. PEAR 1.4.0 supports 3 different kinds of package dependencies:
Normal, traditional channel server-based package dependencies (same idea as package.xml 1.0).
Dependencies on packages that provide PHP extensions (like PECL packages). (These can be both server-based and uri-based dependencies)
Static, non-traditional uri-based package dependencies.
The most common kind of package dependency is a channel-based dependency. This dependency from package.xml version 1.0:
<deps> <dep type="pkg" rel="has">PEAR</dep> </deps> |
translates to this dependency in package.xml version 2.0:
<dependencies> <required> <!-- ... --> <package> <name>PEAR</name> <channel>pear.php.net</channel> </package> </required> </dependencies> |
Note that <channel> is a required tag for all typical package dependencies. Use pear.php.net for all packages that were packaged using package.xml 1.0, regardless of where they are downloaded from.
As with all dependency tags that support versioning, all standard versioning tags are supported (min, max, recommended, exclude). In addition, the <conflicts> tag is supported to create a negative dependency.
<min> - minimum version of a dependency. If the dependency package is installed, and is older than this version, installation will fail.
<max> - maximum version of a dependency. If the dependency package is installed, and is newer than this version, installation will fail.
<recommended> - recommended version of a dependency. This tag is used for strict version control. The installer will refuse to install a package without the --force option unless the version exactly matches recommended. This can be used to provide a level of extra security, as a package can be set to install using a version that is known to work without limiting future upgrades.
Note that use of the <compatible> tag in the dependency's package.xml can be used to circumvent the installer's strictness. In essence, the <compatible> tag tells the installer that a dependent package is compatible with the current package, even though it is not the recommended version.
<exclude> - incompatible versions of a package. Multiple <exclude> tags may be used to exclude more than one version of a dependency.
<conflicts> - Negates the dependency. If the package is installed, it cannot satisfy the requirements of the dependency or installation will fail.
Here is a rough chart describing how to convert from package.xml 1.0 "rel" attributes to a package.xml 2.0 equivalent.
Таблица 17-1. Converting package.xml 1.0 package dependencies to package.xml 2.0
1.0 | 2.0 equivalent | ||
---|---|---|---|
|
| ||
|
| ||
|
| ||
|
| ||
|
| ||
|
| ||
|
|
Let's look at uri-based package dependencies. Here is a simple example:
<package> <name>Foo<name> <uri>http://www.example.com/Foo-1.3.0</uri> </package> |
This dependency tells the installer to fetch http://www.example.com/Foo-1.3.0.tgz or http://www.example.com/Foo-1.3.0.tar (both must be available!) if the package Foo is not installed. All uri packages must contain a <uri> tag rather than a <channel> tag and will automatically belong to the pseudo-channel "__uri", but that is not important to the discussion of how to format the xml to create the uri-based package dependency.
uri-based package dependencies cannot contain any versioning information, as this is irrelevant: there is only one version possible with a static uri. uri-based dependencies can contain the <conflicts/> tag to specify an absolute conflict with the package, and the <providesextension> tag to specify an extension provided by the static package.
package.xml 2.0 supports differentiating release types, and as such also supports dependencies on PECL-style packages that use the extbinrelease or extsrcrelease type.
To specify a dependency on a PHP extension that can be distributed as a PECL package, but could also be bundled with PHP by default, such as the PDO extension, use this dependency style:
<package> <name>PDO</name> <channel>pecl.php.net</channel> <min>0.3.1</min> <providesextension>PDO</providesextension> </package> |
The magic is in the <providesextension> tag. This tag tells the installer to take this process when validating the dependency:
Is the extension "PDO" present in memory? If so, is it version 0.3.1 or higher?
If not, is the user also installing pecl.php.net/PDO at the same time as this package? If so, is it version 0.3.1 or higher?
If not, is pecl.php.net/PDO installed, and is the version 0.3.1 or higher?
If any of the three conditions above validate in the order specified, the dependency will be satisfied and installation will continue. This system allows users to use a different php.ini to install PHP extensions and also provides a fail-safe system to depend on extensions.
Внимание |
<providesextension>, like all other extension-related functions in PHP, is case-sensitive. Do not use "pdo" for the "PDO" extension, or your dependency will always fail. |
As with all dependency tags that support versioning, all standard versioning tags are supported (min, max, recommended, exclude). In addition, the <conflicts> tag is supported to create a negative dependency.
<min> - minimum version of PHP extension to install this package.xml.
<max> - maximum version of PHP extension supported.
<recommended> - recommended version of PHP extension. This tag is used for strict version control. The installer will refuse to install a package without the --force option unless the version exactly matches recommended. This can be used to provide a level of extra security, as a package can be set to install using a version that is known to work without limiting future upgrades.
<exclude> - incompatible versions of PHP extension. Multiple <exclude> tags may be used to exclude more than one version.
<conflicts> - Negates the dependency. If the extension is present, it cannot satisfy the requirements of the dependency or installation will fail.
The OS dependency is used to restrict a package to both a particular class of OSes (like unix) and to a specific OS (like darwin, or freebsd). Here is an example:
<os> <name>linux</name> </os> |
To specify that a package can be installed on every OS except the one specified, use the <conflicts/> tag:
<os> <name>windows</name> <conflicts/> </os> |
Possible OS values are:
windows
unix
linux
freebsd
darwin (use for Mac OS X)
sunos
irix
hpux
aix
In addition, any esoteric OS that supports the php_uname() function can be used. Note that the "unix" OS is defined as any of linux, freebsd, darwin, sunos, irix, hpux, or aix.
The arch dependency is used to restrict a package to a specific os and processor architecture. Here is an example:
<arch> <pattern>linux-*-i386-*</pattern> </arch> |
To specify that a package can be installed on every architecture except the one specified, use the <conflicts/> tag:
<arch> <pattern>linux-*-i?86-*</pattern> <conflicts/> </arch> |
The arch pattern is defined by the OS_Guess->matchSignature() method, and is as follows: sysname[-release[-cpu[-extra]]]. All segments within [] are optional, and the wildcard "*" can be used in all segments instead of a value. In addition, the "?" wildcard can be used to specify a single character that can match any value. i?86 will match i386, i686, i586 and so on.
sysname is the same as the os dependency, except unix is not supported.
release is the version of the operating system.
cpu is the specific cpu, and is typically i?86, sparc, powerpc.
extra is any other stuff on the end of php_uname(), including the glibc version
Standard file roles provided by default with PEAR are:
php
data
doc
test
script
src
ext
If your package chooses to use a role provided by a third party that implements some more advanced file installation handling, all you need to do is specify the role in the xml for the <file> tag that contains it like so:
<file role="foo"/> |
However, if a user does not have the package installed that provides the custom role "foo", then the error message on installation will simply say "unknown role 'foo'", which is not very helpful.
The <usesrole> tag instead prompts the installer to tell the user "this package uses the custom role 'foo', install package pear.example.com/Foo to use"
<usesrole> <role>foo</role> <package>Foo</package> <channel>pear.example.com</channel> </usesrole> |
Note that static URI packages (channel-less packages) are also supported:
<usesrole> <role>foo</role> <uri>http://pear.example.com/Foo-1.2.0</uri> </usesrole> |
Standard file tasks provided by default with PEAR are documented in this location.
If your package chooses to use a task provided by a third party, all you need to do is specify the task as part of the xml for the <file> tag that contains it like so:
<file role="php"> <tasks:foo/> </file> |
However, if a user does not have the package installed that provides the custom task "foo", then the error message on installation will simply say "unknown task 'foo'", which is not very helpful.
The <usestask> tag instead prompts the installer to tell the user "this package uses the custom task 'foo', install package pear.example.com/Foo to use"
<usestask> <task>foo</task> <package>Foo</package> <channel>pear.example.com</channel> </usestask> |
Note that static URI packages (channel-less packages) are also supported:
<usestask> <task>foo</task> <uri>http://pear.example.com/Foo-1.2.0</uri> </usesrole> |
In package.xml 1.0, there was one release type. package.xml 2.0 provides much finer control over the kind of release in order to provide three new release types: extension binary release, extension source release, and package bundle release.
All of the normal release tags (phprelease, extsrcrelease, extbinrelease) may contain two optional sections, <installconditions> and <filelist>. The purpose of these sections is to allow specification of different file install groups based on the target OS for installation, or other common install conditions.
To be clear: in package.xml, there was 1 <release> tag. package.xml 2.0 allows several adjacent release tags, each specifying a different install set. This actually simplifies complex installation filesets by separating the contents listing of the tarball from how the installer should manipulate this listing. Debugging installation file sets should be much simpler with this change.
The <filelist> tag can contain only two possible tags, <install> and <ignore>. install has two required attributes, "name" and "as". The install tag is used in the same manner as package.xml's install-as attribute for the <file>, to specify a new installation location for a file in the contents list. The ignore tag is used to completely ignore a file.
The <installconditions> tag can contain 4 tags whose format can be found in the <dependencies> section: <php>, <extension>, <os>, and <arch>. Each tag can appear exactly once except for the extension tag, which can appear limitless times.
The php tag is used to specify a php version or range of versions that an install set should be valid with.
The extension tag is used to specify extensions that must be present for an install set to be valid.
The os tag is used to specify an OS that must be present for an install set to be valid. Note that unix can be used to match all flavors, and linux can be used to match all linux-based OSes. Darwin should be used for Mac OS X, and * can be used to match all operating systems.
The arch tag is used to specify a uname string or portion of a uname string that must match in order for the install set to be valid.
The phprelease release type is designed for PEAR-style PHP script package releases. It causes a few specific validation changes. First of all, the <contents> tag must contain <file> and <dir> tags. The only valid roles for files are role="php", role="data", role="doc", and role="test" plus any custom roles that the user has installed for use in php releases.
The extsrcrelease release type is for PECL-style PHP extension releases that must be compiled in order to be useable. It causes a few specific validation changes. First of all, the <contents> tag must contain <file> and <dir> tags. The only valid roles for files are role="src", role="data", role="doc", and role="test" plus any custom roles that the user has installed for use in extension source releases.
In addition, the <providesextension> tag must be present in order to document the name of the extension this package provides must be in the package.xml as well.
The extbinrelease release type is for PECL-style PHP Extension binary releases that are pre-compiled. It causes a few specific validation changes. First of all, the <contents> tag must contain <file> and <dir> tags. The only valid roles for files are role="ext", role="data", role="doc", and role="test" plus any custom roles that the user has installed for use in extension binary releases.
In addition, the <srcpackage> or <srcuri> and the <providesextension> tags must be present in order to document the package that provides extension source for this binary release, and the name of the extension this package provides must be in the package.xml as well.
The bundle release type is designed to allow packaging several other package releases into a single bundle of packages that will all be installed at the same time. This can be used to distribute a complete application as one tarball, or to distribute a library of packages in a single tarball.
Unlike the other release types, a bundle release's <contents> tag must contain only the <bundledpackage> tag. The contents of the bundledpackage should be release names like "Foo-1.2.3.tgz"
In addition, the <bundle/> tag must be empty.
Первый шаг, который вы должны выполнить - это проверить, что при написании пакеты вы учли Стандарты кодирования PEAR. После этого вам следует получить разрешение на публикацию пакета от сообщества PEAR (на данный момент это означает, что вам нужно 5 голосов "за" (+1)).
После того, как вы получили достаточное количество голосов "за" и ваш пакет соответствует стандартам, вам следует обратиться за получением учетной записи на сайте PEAR. Для этого вы можете использовать форму запроса учетной записи - http://pear.php.net/account-request.php. После получения учетной записи вы можете переходить к следующему шагу.
Далее вам следует проверить правильность файла описания пакета - package.xml. Для этого выполните следующую команду: pear package-validate package.xml. Если возникли какие-то ошибки - исправьте их.
Замечание: pear pv package.xml - это короткий вариант команды pear package-validate package.xml.
Замечание: Дополнительную информацию по созданию файла описания пакета смотрите в разделе Создание файла описания пакета.
Теперь, когда у вас уже есть файл описания пакета, вы можете создать tar-архив релиза. В командной строке смените текущую директорию на директорию пакета и выполните команду: pear package <package definition XML file> В результате создастся tar-архив релиза пакета (сжатый с помощью gzip, если будет найдена zlib). Этот файл в дальнейшем будет ипользован для публикации пакета.
Замечание: Если ваш XML-файл описания пакета называется package.xml, то вам можно не указывать его имя в команде pear package.
Далее вам следует установить пакет локально, выполнив команду: pear install <file> (file - это tar-архив, который вы только что создали). Это необходимо для того, чтобы удостовериться в том, что файл описания пакета содержит не только правильный XML, но и правильные данные. Вы должны вручную проверить, что каждый файл установился в соответствующее место. Если ваш пакет содержит тестовые скрипты (что настойчиво рекомендуется) - выполните их.
Если на этом этапе происходят какие-либо ошибки, вам следует их исправить и проделать всю процедуру создания пакета сначала. Когда все будет в порядке - переходите к следующему шагу.
Для начала, вы должны зайти на сайт PEAR, используя пароль и логин, которые были вам выданы (см. первый шаг).
Если это первый релиз вашего пакета, то вы должны зарегистрировать его. Регистрация осуществляется с помощью формы, которая расположена здесь: http://pear.php.net/package-new.php. Если вы сомневаетесь к какой категории должен относиться ваш пакет - проконсультируйтесь у сообщества PEAR (с помощью рассылки pear-dev).
Теперь, наконец, вы можете опубликовать пакет. Делается это с помощью соответствующего веб-интерфейса. Используйте форму: http://pear.php.net/release-upload.php.
Всё! Ваш пакет был выпущен; анонс был разослан в списки рассылки; все довольны, все смеются =)
There are numerous ways to support the PEAR project, that are described in this part of the guide.
If you have a feature you would like to see included in a package, don't hesitate to contact the maintainer of the package. You can find out, who the maintainer of a package is, by browsing the package list on the PEAR website and selecting the desired package. The maintainer(s) is/are listed on the package information page.
If a developer has given up the maintainership of his package, you can take over this job. If you feel brave enough to answer support questions, fix bugs and manage release cycles, you can contact the previous maintainer or the PEAR developers mailinglist and announce your will to maintain the package.
For all the PEAR developers, PEAR is a project they are working on in their free-time, which means that they don't earn any money with it. If you or the company you are working for is using a PEAR package in one of your/their (commercial) products, you/they can do this for free, of course. But if you think that the author of the package you are using desires some credits, it would be nice to buy something from his wishlist at Amazon or another internet store. To see if a PEAR developer has registered his wishlist, surf to the Account information page and select the developer from the list there. If he has a wishlist, it's noted somewhere on the detail page.
The following recommendations describe topics which were discussed and agreed upon by the PEAR developers on the developers mailinglist. They aren't strict rules, which you need to follow (like Coding Stardards), but are intended as guidelines for a common API scheme and easier package interoperability. Please consider following them in your packages where possible.
In case a package has to deal with colors, it is recommended that developers store and use an array representation of the color values in their PEAR packages. All values are in the range of 0..255.
The following snippet defines an array that holds the RGB definition of the green coloring that is used in the official PEAR logo.
$color = array(0x33, 0x99, 0x00); |
$color = array(51, 153, 0); |
Since this an extension of the RGB representation above, it is recommended to use a forth value for alpha-channel-prepresentation. An example of the "PEAR-green" with aprox. 80% intensity would be:
$color = array(0x33, 0x99, 0x00, 0xCC); |
Please note this is in contrast to the alpha-value used by imagecolorallocate(). The alpha-representation used in PEAR was choosen for consistency with the other RGB values and because it is commonly accepted practise in many other applications (image-processing tools, etc.).
Since RGB/RGBA will used for graphic generation on a computer we decided to leave out an optional type-identifier classifying colors as RGB/RGBA. However for different color-representations an identifier is needed. The optional identifier "type" can be added to the color array.
$color = array(0x33, 0x99, 0x00, 0xCC, "type" => "RGB"); |
RGB - red, green, blue
CYMK - cyan, yellow, magenta, black (key)
Please note that also the RGBA representation has the type "RGB" since it's closely related.
The PEAR-package Image_Color will (hopefully soon) contain all needed functions to convert arbitrary color formats to the internal RGBA representation and convert different color representations.
Status: Currently Image_Color already offers functions to convert color-names (e.g. "green") and hex-representations-strings (e.g. "#339900") to the PEAR-RGBA-format. We are working to get alpha- channel support added hopefully soon and will later add funtions for CYMK-conversion as well.
This chapter provides a detailed description how to write documentation using one of the supported formats. It is aimed at both PEAR developers that are already maintaining packages in PEAR and at people who are planning to contribute a new package.
DocBook is an XML dialect that is used by a wide range of projects to maintain their documentation. Examples for DocBook usage in OpenSource projects are the documentations of KDE and PHP. PEAR has opted for using DocBook, because we believe that it provides a solid foundation for the technical documentation for PEAR packages.
The trade-off for using DocBook is that it is relatively hard to use. Testing documentation requires a number of tools to be installed and one needs to learn a (not very complicated) XML dialect. Once one is familiar with how DocBook works, they will enjoy writing documentation with it though.
The book [DocBook: The Definitive Guide], written by Norman Walsh and Leonard Muellner and published by O'Reilly & Associates, Inc., is available online and it makes up a great resource for people interested in learning DocBook.
Definitely check out the book's "DocBook Element Reference" section. This portion provides detailed information about each element, including which elements can (and must) be used as parents and children.
Even if DocBook XML can (like any other XML file) be written using a normal text editor, it is optimal for users to install some software on their machine in order to test the validity of the documenting efforts. A list of the required software and a installation instruction can be found in the PHP Documentation HOWTO. Apart from providing information about the software, this HOWTO also provides a ton of other useful information that goes far beyond this chapter. One is encouraged to completely read it. (Chapter II can be skipped, because it only contains information that is very PHP specific.)
Installation on OS X: The PHP Documentation HOWTO advises users of Mac OS X to use packages provided by Fink. Alternatively packages from the MacPorts project can be used. After installing MacPorts, the toolchain can be installed using the following command:
Unfortunately, installing that software can be difficult under some circumstances. If you are unable to get it working, don't use that as an excuse for not writing documentation. There are two test servers that automatically download peardoc from CVS and build the manual. Any parsing errors your changes cause will show up in the logs the next time the build happens:
Build from Mika Tuupola (log) (time zone: EET = UTC+2, EEST = UTC+3, updated every two hours) |
Build from TAKAGI Masahiro (log) (updated daily at 06:00 JST = 21:00 UTC) |
Внимание |
The manual on the PEAR website is built only once per week. Any XML validation errors will cause the build to fail. If the main build fails, the old version remains in place, meaning the manual will be out of date. Therefore, always check the test build logs to ensure your changes are valid. More importantly, do not commit updates shortly before the main build happens (Sundays ~12:00 UTC). |
Once the necessary software is in place, one has to get the latest version of the XML sources from PEAR's CVS repository:
$ cvs -d :pserver:<user>@cvs.php.net:/repository login [password] $ cvs -d :pserver:<user>@cvs.php.net:/repository co peardoc |
If you do not own an account for cvs.php.net, please choose cvsread as the username. When asked for the password, type phpfi.
After that the directory ./peardoc will contain a local copy ("sandbox") of the latest sources. If you are not yet familiar with CVS, then the online book "Open Source Development with CVS" will provide you with all the necessary information.
This chapter will not describe all the details about the directory structure, because one can find out the essentials about it by browsing the previously created directory peardoc. As a starting point for package documentors peardoc/en/package/ fits well. If one has further questions concerning the directory structure, they can ask on the documentation mailinglist.
Instead of a long and boring description for writing documentation using DocBook, we would like to point you to a bunch of "reference documents", from which you should be able to learn quickly:
The CVS tree has a complete set of DocBook XML templates. These files provide the standard of how PEAR documentation should look.
The simplest way to utilize them is to copy them to your working directory, rename them accordingly, edit the contents to match the reality of your program and then upload them to your package's directory in the repository.
The documentation for HTTP_Request, which is a relatively small package, only consists of a bunch of end-user documentation, which describes all of the basic features of the package. Each feature description includes at least one example. For small packages with only a handful of methods this documentation type is absolutely enough.
XML_Beautifier is a package that is also relatively compact, but which supports different configuration options. These options are described in the documentation Additionally the documentation gives usage examples and (unlike HTTP_Request) also includes API documentation for its methods.
DB is a large PEAR package and has excellent documentation, including usage examples. The DB docs carefully adhere to the formatting specified in peardoc/authoring. The link above goes to the DocBook source code in the CVS repository. It might be helpful to examine the HTML generated therefrom.
In addition to the examples above, you will find much more documentation examples by browsing the peardoc directory, which contains your local version of the CVS tree. Especially the directory peardoc/en/packages/ should be of interest for you. You can also browse the CVS module using the web interface, including the raw XML for the file you are presently reading.
Generating human-readable versions of the DocBook sources requires the existance of the above-mentioned software. The PEAR documentation system uses Unix style makefiles:
peardoc$ autoconf peardoc$ ./configure --with-lang=en peardoc$ make html |
If you want to build a language other than English, change en, above, to the appropriate language code.
This will generate a "raw" HTML version of the whole manual. The result will be placed in the subdirectory html/.
The command make test does not generate any human-readable result, but it can be used to make sure that the XML is syntactically correct and that the build runs fine. And it is much faster than make html.
Numerous developers have reported problems when using the make html command, namely that the output was not written to a file but instead dumped on the console. If you encounter this problem and have checked out the DocBook sources into e.g. /home/you/cvs/peardoc, checkout the phpdoc module (using the procedure described above) into /home/you/cvs/phpdoc, and run make html again.
Alternatively one can use the xmllint program that is part of the libxml2 toolkit. This is especially useful for systems where the DSSSL/make setup does not work properly.
In addition to testing the well-formedness of the DocBook sources, xmllint can also check the semantical correctness with the help of RELAX NG schemas. The schema files for DocBook are available as a ZIP package from docbook.org. After unzipping the package into the directory relaxng/ inside the peardoc source folder, one can run xmllint from the root folder of the PEAR documentation as follows:
xmllint --valid --noout --relaxng relaxng/ manual.xml
The build process (not the test builds, which are reasonably quick) actually takes a very long time which makes debugging and testing a very hard task. In order to increase build performance, the script make-partial.php in the root directory of the documentation module may be used. This is an interactive command line script that will enable to you to selectively include the different parts of the manual. In the following example a version of the manual is generated which only contains a certain part of the Developer's Guide and the documentation for the HTTP packages. Using these partial builds reduces the build time dramatically.
peardoc$ ./make-partial.php Include about-pear? [NO] Include guide-newmaint? [NO] Include guide-developers? [NO] y Include guide.developers.intro? [NO] Include guide.developers.meaning? [NO] Include guide.developers.contributing? [NO] Include guide.developers.packagedef? [NO] Include guide.developers.release? [NO] Include guide.developers.supporting? [NO] Include guide.developers.recommendations? [NO] Include guide.developers.documentation? [NO] y Include core? [NO] Include packages? [NO] y Include package.authentication? [NO] Include package.benchmarking? [NO] Include package.caching? [NO] Include package.configuration? [NO] Include package.console? [NO] Include package.database? [NO] Include package.datetime? [NO] Include package.encryption? [NO] Include package.fileformats? [NO] Include package.filesystem? [NO] Include package.gtk? [NO] Include package.html? [NO] Include package.http? [NO] y Include package.images? [NO] Include package.internationalization? [NO] Include package.logging? [NO] Include package.mail? [NO] Include package.math? [NO] Include package.networking? [NO] Include package.numbers? [NO] Include package.payment? [NO] Include package.pear? [NO] Include package.php? [NO] Include package.science? [NO] Include package.streams? [NO] Include package.structures? [NO] Include package.system? [NO] Include package.text? [NO] Include package.tools? [NO] Include package.xml? [NO] Include package.webservices? [NO] Include pecl? [NO] CONFIG_FILES=manual.xml CONFIG_HEADERS= ./config.status creating manual.xml /usr/bin/jade -wno-idref -d html.dsl -V use-output-dir -t sgml ./phpdocxml.dcl manual.xml |
Translating documentation is another important task. Existing translations need to be brought up to date because the English versions have been changed. Help on how to perform the translation process is in the Revision Tracking section of the manual.
We are well aware that we cannot cover all questions about writing DocBook documentation in this chapter. If you have more questions or problems, do not hesitate to get in touch with the documentation team at pear-doc@lists.php.net. To join the pear-doc list send an email to pear-doc-subscribe@lists.php.net.
This section of the chapter does not deal with the specifics of organizing documentation in the peardoc standard, but instead with how to organize documentation logically.
First, every package solves a problem. What is this problem? Try to figure out what assumptions your end-users might not have about the problem (they may not realize that this is a problem that needs solving). For instance, a template package solves the problem of both separating design from code, and separating business logic from display logic. If possible, explain the problem in terms that even a novice programmer can understand.
Next, how does the package uniquely solve the problem? This is something that most documentation lacks. For example, there are many template engines. All of them solve the same problem, but none of them do it in the same way. A block-based template engine does not have any logic at all, whereas a template like Smarty defines a whole new template language. Some template engines compile their templates, others don't. What is unique about your package? Can someone who has never seen the code get a good idea of how it solves the problem?
Provide examples! Start right away with simple examples that shows the basic feature set -- they will show users how to quickly start using the package. More complex examples will help the users in understanding advanced ways of using the package.
If your package exposes complex interfaces or multiple constants that can't be fully explained in one or two examples (which is very likely), do not miss to explain them thoroughly in the documentation. Document any interfaces that users must use, such as a database DSN, command-line arguments for applications, configuration file contents, or any other non-code element.
Last, proofread your documentation. If possible, have someone else who is not as familiar with your project take a look at the documentation. They will catch assumptions that you have missed.
The debut of PEAR 1.4.0 is very exciting. This chapter documents all of the differences between PEAR 1.3.x and the new features introduced in PEAR 1.4.
The most significant change in PEAR 1.4 is the addition of channels, a simple and effective method of distributing application development. This change has driven most of the other changes to PEAR, and in fact full application support is a major goal of this release.
In addition to channels, support for customization of the install process has been seriously enhanced with the addition of three essential features for application development:
Custom file installation roles in package.xml
Custom file tasks in package.xml
PEAR Channels provide a robust and effective way of distributing development. The addition of channel support to the PEAR installer as of version 1.4.0 means that it is now simpler to distribute any PHP code project using the PEAR installer than it ever was. PEAR Channels allow developers of applications to effectively depend upon packages from pear.php.net and any other source that provides a channel server. For users of these applications, this eliminates the complexity of installation and configuration. Now, all the user will need to do is to type a single pear install channel/Packagename command and go!
Before PEAR 1.4.0, the only solution to depending on code from several sources is to bundle the code. This has several bad side effects, the most obvious of which is that code size increases dramatically, and makes upgrading for a minor bug fix a complicated download for the user.
Channels allow an application developer to depend on packages from pear.php.net, a package from pear.example.com, and others. The user will only need to install/upgrade from a single source using the pear installer. With the current state of affairs, the pear installer is only really useful for installing, well, PEAR packages. Because of this difficulty (among others), traditionally very few packages are available as PEAR packages that can be installed with the PEAR installer.
PEAR 1.4.0+ aims to eliminate this and other barriers to application development.
Incomplete documentation |
Documentation is not yet complete |
Discovery of a channel's capabilities is extremely flexible. The XSD schema defining channel.xml can be found at http://pear.php.net/dtd/channel-1.0.xsd. Channel.xml defines:
the channel name
an optional suggested user alias for the channel
a brief summary of the channel's purpose
an optional package to perform custom validation of packages on both download and packaging
a list of protocols supported by a channel (XML-RPC, SOAP, and REST are supported)
a list of mirrors and the protocols they support.
Here is a sample channel.xml with all elements:
<channel version="1.0" xsi:schemaLocation="http://pear.php.net/channel-1.0 http://pear.php.net/dtd/channel-1.0.xsd"> <name>pear.example.com</name> <suggestedalias>foo</suggestedalias> <summary>Example channel.xml</summary> <validatepackage version="1.3.4">Foo_Validate</validatepackage> <servers> <primary port="8080" ssl="yes"> <xmlrpc> <!-- default path is xmlrpc.php --> <function version="1.0">logintest</function> <function version="1.0">package.listLatestReleases</function> <function version="1.0">package.listAll</function> <function version="1.0">package.info</function> <function version="1.0">package.getDownloadURL</function> <function version="1.1">package.getDownloadURL</function> <function version="1.0">package.getDepDownloadURL</function> <function version="1.1">package.getDepDownloadURL</function> <function version="1.0">package.search</function> <function version="1.0">channel.listAll</function> </xmlrpc> <rest> <!-- no default path, all must be defined in baseurl --> <baseurl type="package">http://pear.example.com/rest/1.0/package</baseurl> <baseurl type="category">http://pear.example.com/rest/1.0/category</baseurl> </rest> <soap path="soapy.php"> <!-- default path is soap.php --> <function version="1.0">package.listAll</function> </soap> </primary> <mirror server="foo2.example.com/pearmirror"> <xmlrpc path="mirrorxmlrpc.php"> <!-- default path is xmlrpc.php --> <function version="1.0">package.listLatestReleases</function> <function version="1.0">package.listAll</function> <function version="1.0">package.info</function> <function version="1.0">package.getDownloadURL</function> <function version="1.1">package.getDownloadURL</function> <function version="1.0">package.getDepDownloadURL</function> <function version="1.1">package.getDepDownloadURL</function> <function version="1.0">package.search</function> </xmlrpc> <rest> <!-- no default path, all must be defined in baseurl --> <baseurl type="package">http://foo2.example.com/rest/1.0/package</baseurl> </rest> </mirror> </servers> </channel> |
A channel's name should be the name of the server that users would browse to in order to learn more about the packages being offered. For instance, PEAR packages are located in the pear.php.net channel. PECL packages are located in the pecl.php.net channel. Note that for backwards compatibility, all existing packages based on package.xml version 1.0 are in the pear.php.net channel.
The benefit that comes from using the server name as the channel name is that auto-discovery becomes a real possibility, as well as ease of locating packages increases dramatically.
A channel need not be located in the document root, a channel can contain a path. This is a perfectly valid channel name: foo.example.com/path/to/pear. Note that users would have to type:
$ pear install foo.example.com/path/to/pear/Packagename |
Unless you provide a <suggestedalias>.
The channel's definition file "channel.xml" must be placed in the root channel directory. If a channel is "pear.example.com", the channel.xml must be located in "http://pear.example.com/channel.xml". If the channel is "pear.example.com/path/to/pear", then the channel.xml must be located in "http://pear.example.com/path/to/pear/channel.xml"
<suggestedalias> defines a shorter, more friendly name to use when installing packages from a channel. For instance, the pear.php.net channel's suggested alias is "pear". The best aliases for a channel will be no more than 6 characters long - remember, a user must type them often when installing or upgrading, and this can be tedious for longer aliases.
Rather than call this tag <alias>, as it was originally named, the tag is named <suggestedalias> in order to provide the user some latitude. If the user does not like the alias suggested by the channel owners, he or she can easily re-alias a channel through the channel-alias command.
This tag provides a short description of what packages the user should expect to find on this channel. The summary is what users will see when the use the list-channels command.
Most channels will be satisfied with the restrictions placed upon package naming, versioning, and so on that PEAR provides by default. However, for some channels, the validation will be too strict, and others, too relaxed. The <validatepackage> tag provides the next level of customization.
If omitted, the installer assumed that the PEAR_Validate class should be used. Note that a looser version validation is provided by the PEAR_Validate_PECL class, for channels like pecl.php.net that do not wish to deal with PEAR's warnings on version transgressions.
<validatepackage> requires a version attribute and text content. The text content must be the name of a package that can be installed via:
$ pear install channelname.example.com/Packagename-version |
as in:
$ pear install pear.example.com/Foo_Validate-1.3.4 |
for the sample channel.xml at the beginning of this section. In addition, the package must provide a single class named after the package in a file using the PEAR naming conventions (all underscores "_" converted into path separators "/" so that Foo_Validate is located in Foo/Validate.php), and this class should extend PEAR_Validate. Methods beginning with "validate" like validateVersion() are intended to be overridden by validation classes for use in extending existing validation functionality.
Mirroring is explicitly supported in channel.xml and in the PEAR installer. Users can choose their favorite mirror via the default_channel configuration option, and channel.xml can list all the possible mirrors using the (surprise) <mirror> tag.
The <primary> tag is used to define the location of protocols, and to list the protocols that are supported by the main channel server. Optional attributes can be used to modify how the PEAR installer will attempt to connect to the server. The "port" attribute can be used to define how the installer will connect to XML-RPC and SOAP services. REST services are always controlled by the individual <baseurl> tags.
channel.xml knows about the XML-RPC, SOAP, and REST protocols for web services. However, the PEAR installer only supports XML-RPC currently, and may support REST shortly. No support for SOAP is planned for the near future. However, should it ever be implemented, channel.xml is ready.
The <xmlrpc> and <soap> tags have identical formats. Both tags can contain an optional attribute "path" that tells the PEAR installer which URL to query. By default, the path is protocol.php, as in xmlrpc.php or soap.php. In other words, to access XML-RPC functions for the pear.example.com channel defined in the sample channel.xml, the installer would query https://pear.example.com:8080/xmlrpc.php for XML-RPC functions, but would query https://pear.example.com:8080/soapy.php for SOAP functions.
The <rest> tag reflects the design concept behind REST: each resource is defined by a base URL in tag <baseurl> that is then used by the installer along with hyperlinks to glean the same information that XML-RPC or SOAP would provide. Required attribute "type" tells the installer what kind of information is provided by the base URL, and how to parse that information.
The <function> tag is quite simple. A required version attribute informs the installer what the API is, and the text content informs the installer what the name of the function is. Note that multiple functions with different versions can co-exist peacefully, as in:
<function version="1.0">package.getDownloadURL</function> <function version="1.1">package.getDownloadURL</function> |
Some of you may be asking "why create another standard for web services discovery?" The answer is simple: channel.xml does not supplant the role that WSDL has for java, or XML-RPC introspection occupies. channnel.xml is a layer on top of these technologies. The point is to quickly list the remote protocols that are supported, not to describe what they do.
The PEAR installer is specialized enough that a generic listing of parameters and return values is entirely unnecessary: the installer knows exactly what xml-rpc function package.info version 1.0 requires and what it returns. Any other information simply adds wasted bandwidth and disk space.
A standard PEAR channel should support this list of XML-RPC functions:
logintest - a stub function
package.getDownloadURL - retrieve a URL to download a package
package.getDepDownloadURL - retrieve a URL to download a package dependency
package.info - retrieve information on a package
package.listAll - list all packages and verbose information on each package
package.listLatestReleases - list all packages and their latest release versions
package.search - search all packages for a match
Channels can also implement channel.listAll, but we recommend that this only be implemented by pear.php.net and pecl.php.net channels, as the command is utilized by the update-channels command to retrieve an official list of channels.
The logintest xml-rpc function is called by the login command, and should return a boolean TRUE
an array of format:
array( 'channel' => channel name, 'package' => package name, ['version' => specific version to retrieve,] ['state' => specific state to retrieve,] ) |
if both version and state are set, the version index should be ignored.
The client-side preferred_state. This should be used to exclude releases that are too unstable.
The current installed version of the package on the client-side. This will either be a version string, or false if the package is not installed. Use this to ensure that older versions are never returned (as defined by version_compare(possible_version, installed_version, "<")).
The package.getDownloadURL function should return an array with either two or three indices.
"version" => version of the release returned
"info" => the complete package.xml contents from the release
"url" => a URL from which to download this release. If no releases exist that fit the constraints defined by preferred_state, installed_version, and the version/state indices of packageinfo, then do not return this index, and instead return the version and package.xml of the latest release.
The url entry should NOT append .tgz or .tar, but should be something like "http://pear.php.net/get/PEAR-1.4.0" instead of "http://pear.php.net/get/PEAR-1.4.0.tgz"
Note that version 1.0 of package.getDownloadURL did not have the installed_version parameter. Version 1.1 of package.getDownloadURL does - that is the only difference between the two versions.
This should be either '1.0' or '2.0', and should match the version attribute from the top-level <package version="X.0"> tag. This should be used to determine how to process the second parameter.
if the first parameter xsdversion is '1.0', this should be an array of format:
array( 'name' => package name 'type' => 'pkg' - anything else is an error 'rel' => 'has', 'ge', 'le', 'lt', 'le', 'not', 'ne' ['version' => specific version to retrieve,] ) |
if xsdversion is '2.0', this should be an array of format:
array( 'name' => package name 'channel' => package channel - see notes below ['min' => minimum version (inclusive),] ['max' => maximum version (inclusive),] ['exclude' => single version to exclude (string), or array of versions to exclude,] ) |
Note that you must always verify that the channel matches your channel. If your channel server is not at pear.php.net or pecl.php.net, you must reject all xsdversion='1.0' requests, and all xsdversion='2.0' requests where the channel is not your channel.
This is information on the parent package, and is an array of format:
array( 'channel' => channel name, 'package' => package name, 'version' => specific version to retrieve, ) |
The client-side preferred_state. This should be used to exclude releases that are too unstable.
The current installed version of the dependency on the client-side. This will either be a version string, or false if the package is not installed. Use this to ensure that older versions are never returned (as defined by version_compare(possible_version, installed_version, "<")).
Like package.getDownloadURL, package.getDepDownloadURL should return an array with either two or three indices.
"version" => version of the release returned
"info" => the complete package.xml contents from the release
"url" => a URL from which to download this release. If no releases exist that fit the constraints defined by preferred_state, installed_version, and the version/state indices of packageinfo, then do not return this index, and instead return the version and package.xml of the latest release.
The url entry should NOT append .tgz or .tar, but should be something like "http://pear.php.net/get/PEAR-1.4.0" instead of "http://pear.php.net/get/PEAR-1.4.0.tgz"
Note that version 1.0 of package.getDepDownloadURL did not have the installed_version parameter. Version 1.1 of package.getDepDownloadURL does - that is the only difference between the two versions.
Package name to retrieve information about
specific field to retrieve information about. If null, this should return an array with this indices, although others could be set as well:
<?php array( 'name' => 'package name', 'category' => 'category name', 'license' => 'package license', 'summary' => 'package summary', 'description' => 'package description', 'releases' => array( // all releases indexed by version '0.1' => array( 'license' => 'release license', 'summary' => 'release summary', 'description' => 'release description', 'releasedate' => 'date of release', 'releasenotes' => 'release notes', 'state' => 'release stability', // the next index is optional 'deps' => array( array( // release dependencies of latest release 'type' => 'dep type from package.xml <dep>', 'relation' => 'rel from package.xml <dep>', 'version' => 'version from package.xml <dep>, or empty string', 'name' => 'name from package.xml <dep>', 'optional' => 'yes or no', ), // and so on with all deps ), ), // and so on with all releases // releases should be ordered by releasedate DESC ), ); ?> |
The second parameter, if set, must be one of these choices:
authors - a current list of package maintainers in format:
<?php array( 'handle1' => array( 'name' => 'Maintainer Name', 'email' => 'maintainer@example.com', 'role' => 'role from package.xml (lead, developer, contributor, helper)', ), 'handle2' => array( 'name' => 'Maintainer Name 2', 'email' => 'maintainer2@example.com', 'role' => 'role from package.xml (lead, developer, contributor, helper)', ), // etc. ); ?> |
category - the category this package is in
description - the description of the latest release
license - package license of latest release
notes - release notes of the latest release
releases - an array of the format documented above, containing information on all releases
summary - summary from latest release
If TRUE, then packages that have no releases should not be returned in the listing of available packages
If TRUE, then packages that have no stable releases should not be returned in the listing of available packages
This function should return an array of this format for all packages that match the constraints defined above:
array( array( 'name' => 'packagename', 'category' => 'category name', 'license' => 'release license', 'summary' => 'package summary', 'description' => 'package description', 'stable' => 'latest release version that matches constraints', 'unstable' => 'latest unstable release version or false if stable_only', 'state' => 'release state of latest release that matches constraints', 'deps' => array( // same format as for package.info ) ), // etc. ); |
If '', then the newest release will be returned for all packages. Otherwise, it must be one of 'snapshot', 'devel', 'alpha', 'beta', or 'stable', and the function should return the newest release that is more stable than state.
If state is 'beta', then the function should return the latest release that is beta or stable. If state is 'devel', the function should return the latest release that is devel, alpha, beta, or stable, and so on.
This function should return an array of this format for all packages that have a release within the constraint defined by the "state" parameter:
array( array( 'package' => 'packagename', 'version' => 'release version', 'state' => 'release stability', 'filesize' => 'size of the .tgz file to download', ), // etc. ); |
A text fragment to use when searching for packages by name
If set to false, this should be ignored. Otherwise, this should be used to search through the summaries of packages that match the first parameter to limit the list of returned packages.
If TRUE, then packages that have no releases should not be returned in the listing of available packages
If TRUE, then packages that have no stable releases should not be returned in the listing of available packages
This function should return an array of this format for all packages that match the constraints defined above:
array( array( 'name' => 'packagename', 'category' => 'category name', 'license' => 'release license', 'summary' => 'package summary', 'description' => 'package description', 'stable' => 'latest release version that matches constraints', 'unstable' => 'latest unstable release version or false if stable_only', 'state' => 'release state of latest release that matches constraints', 'deps' => array( // same format as for package.info ) ), // etc. ); |
Внимание |
As of PEAR version 1.4.3, the required format for custom file roles has been changed due to a minor security vulnerability. All custom file roles must now define a Role.xml file in order to properly declare a custom file role. See the example below for more information. |
One of the programming features that the PEAR installer enforces is the separation of files into separate categories, and the important idea that files of a similar category are always installed into the same location, or at least handled the same way, as in the case of role="src" for PECL packages.
This has been quite successful for smaller library-style packages, but complete applications cannot function without customized installation locations. For instance, some files may be intended for use in a public web frontend, others for library location. PEAR 1.4 introduces the possibility of defining custom installation roles to fill this void.
To use a custom installation role that another programmer has written, there are three steps that are necessary. First, the <usesrole> tag should be used to define each custom role that is used in the package.xml. Next, the role should simply be used for the files it pertains to. Finally, a dependency on the package that provides the custom role should be added to the package.xml, just for completeness.
Pretty simple!
To define a custom role, you need to create a package containing a single file. Here is a sample package.xml that could be a custom role:
<?xml version="1.0"?> <package version="2.0" xmlns="http://pear.php.net/dtd/package-2.0" xmlns:tasks="http://pear.php.net/dtd/tasks-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0 http://pear.php.net/dtd/tasks-1.0.xsd http://pear.php.net/dtd/package-2.0 http://pear.php.net/dtd/package-2.0.xsd"> <name>Chiarafoo</name> <channel>pear.chiaraquartet.net</channel> <summary>Chiarafoo role</summary> <description> The chiarafoo role installs files into your customized Foo directory </description> <lead> <name>Greg Beaver</name> <user>cellog</user> <email>cellog@php.net</email> <active>yes</active> </lead> <date>2005-03-21</date> <version> <release>1.0.0</release> <api>1.0.0</api> </version> <stability> <release>stable</release> <api>stable</api> </stability> <license uri="http://www.php.net/license">PHP License</license> <notes> Provides the chiarafoo file role </notes> <contents> <dir name="/" baseinstalldir="PEAR/Installer/Role"> <file name="Chiarafoo.xml" role="php"/> <file name="Chiarafoo.php" role="php"> <tasks:replace from="@package_version@" to="version" type="package-info"/> </file> </dir> <!-- / --> </contents> <dependencies> <required> <php> <min>4.2.0</min> </php> <pearinstaller> <min>1.4.3</min> </pearinstaller> </required> </dependencies> <phprelease/> </package> |
The XML file Chiarafoo.xml should be similar to this file:
<role version="1.0"> <releasetypes>php</releasetypes> <installable>1</installable> <locationconfig>foo_dir</locationconfig> <honorsbaseinstall>1</honorsbaseinstall> <unusualbaseinstall /> <phpfile>1</phpfile> <executable /> <phpextension /> <config_vars> <foo_dir> <type>directory</type> <default><php_dir/><constant>DIRECTORY_SEPARATOR</constant><text>Foo</text></default> <doc>directory where foo files are installed</doc> <prompt>PHP foo directory</prompt> <group>File Locations</group> </foo_dir> </config_vars> </role> |
The script in Chiarafoo.php is incredibly simple:
<?php /** * PEAR_Installer_Role_Chiarafoo * * PHP versions 4 and 5 * * LICENSE: This source file is subject to version 3.0 of the PHP license * that is available through the world-wide-web at the following URI: * http://www.php.net/license/3_0.txt. If you did not receive a copy of * the PHP License and are unable to obtain it through the web, please * send a note to license@php.net so we can mail you a copy immediately. * * @category pear * @package Chiarafoo * @author Greg Beaver <cellog@php.net> * @copyright 2005 Greg Beaver * @license http://www.php.net/license/3_0.txt PHP License 3.0 * @version CVS: $Id: customroles.xml,v 1.4 2005/11/03 05:06:52 cellog Exp $ * @link http://pear.chiaraquartet.net/index.php?package=Chiarafoo * @since File available since Release 0.1.0 */ /** * @category pear * @package Chiarafoo * @author Greg Beaver <cellog@php.net> * @copyright 2005 Greg Beaver * @license http://www.php.net/license/3_0.txt PHP License 3.0 * @version Release: @package_version@ * @link http://pear.chiaraquartet.net/index.php?package=Chiarafoo * @since Class available since Release 0.1.0 */ class PEAR_Installer_Role_Chiarafoo extends PEAR_Installer_Role_Common { /** * @param PEAR_Installer * @param PEAR_PackageFile_v2 * @param array file attributes * @param string relative path to file in package.xml */ function setup(&$installer, $pkg, $atts, $file) { // do something special with the installer } } ?> |
Since PEAR 1.4.3, nothing else is necessary for a successful implementation of a file role.
The contents of the role's XML file must contain these tags:
This tag can only contain one of the following values:
php
extsrc
extbin
In order to specify compatibility with multiple release types, use multiple <releasetypes> tags as in:
<releasetypes>php</releasetypes> <releasetypes>extsrc</releasetypes> <releasetypes>extbin</releasetypes> |
releasetypes defines the kind of releases that this role can be used in. For instance, the "src" role is reserved for extsrc packages, and cannot be used in regular PEAR-style php releases. The "data" role can be used in any release, and would define <releasetypes> as:
<releasetypes>php</releasetypes> <releasetypes>extsrc</releasetypes> <releasetypes>extbin</releasetypes> |
This tag must be either <installable>1</installable> or empty (<installable/>) and determines whether files utilizing this custom role can be installed. Any file that should be installed must set this to 1. Only roles such as the "src" role that is processed and used to create the files that are eventually installed should set this to an empty tag.
This tag is used for all installable files to determine which configuration variable contains the directory in which the file should be installed. For instance, the php role uses the "php_dir" locationconfig, the data role uses "data_dir".
Our example role, chiarafoo, uses the "foo_dir" configuration variable, and then through the definition of <config_vars> tells the installer what foo_dir means. Note that once a custom role is installed, the user can config-set/ config-get/config-show the variable just like any other configuration variable!
<config_vars> can define more than one configuration variable, but note that more than 3 variables will trigger an error, disallowing any of them, as a security precaution.
This tag controls whether a role reacts to the "baseinstalldir" attribute of a <file> or <dir> tag. Any role that honors baseinstalldir can potentially allow conflicting files from different packages, and so a check has to be made. A file role that does not honor baseinstalldir is always installed into:
Packagename/full/path/from/contents/file.ext
To specify this value, use <honorsbaseinstall>1</honorsbaseinstall> For all other cases, it should be an empty tag (<honorsbaseinstall/>)
This tag controls whether a role that would normally ignore the "baseinstalldir" attribute of a <file> or <dir> tag would honor it, but still use the Packagename/baseinstalldir/full/path/from/contents/file.ext instead of baseinstalldir/full/path/from/contents/file.ext. Any role that supports the unusual baseinstalldir type cannot conflict with other files because the package name is always the parent directory. To specify this value, use <unusualbaseinstall>1</unusualbaseinstall> For all other cases, it should be an empty tag (<unusualbaseinstall/>)
This tag should be set to 1 (<phpfile>1</phpfile>) for any roles that contain php script files. These files are analyzed at package time, possibly catching errors before release. For all other cases, it should be an empty tag (<phpfile/>)
This tag should be set to 1 (<executable>1</executable>) for roles like the "script" role that should have their executable attribute set via chmod() on install. For all other cases, it should be an empty tag (<executable/>)
This tag should be used for roles like the "ext" role that provide a binary PHP extension. To specify this value, use <phpextension>1</phpextension> For all other cases, it should be an empty tag (<phpextension/>)
This tag is used to define configuration variables that should be added to the installer by this custom file role. Note that the installer will not allow a custom file role to create more than 3 configuration variables. To define configuration variables, create tags with the name of the configuration variable, and then sub-tags defining information about the configuration variable.
These tags are transformed into the PHP array format expected by the PEAR_Config class using an adapted version of Stephan Schmidt's excellent XML_Unserializer class (from the XML_Serializer package). As such, it is easiest to understand the XML format by examining existing configuration variables.
array( 'password' => array( 'type' => 'password', 'default' => '', 'doc' => '(maintainers) your PEAR account password', 'prompt' => 'PEAR password (for maintainers)', 'group' => 'Maintainers', ), // Advanced 'verbose' => array( 'type' => 'integer', 'default' => PEAR_CONFIG_DEFAULT_VERBOSE, 'doc' => 'verbosity level 0: really quiet 1: somewhat quiet 2: verbose 3: debug', 'prompt' => 'Debug Log Level', 'group' => 'Advanced', ), 'preferred_state' => array( 'type' => 'set', 'default' => PEAR_CONFIG_DEFAULT_PREFERRED_STATE, 'doc' => 'the installer will prefer releases with this state when installing packages without a version or state specified', 'valid_set' => array( 'stable', 'beta', 'alpha', 'devel', 'snapshot'), 'prompt' => 'Preferred Package State', 'group' => 'Advanced', ), ); |
These sample configuration values from the actual PEAR_Config class would translate into this XML:
<config_vars> <password> <type>password</type> <default /> <doc>(maintainers) your PEAR account password'</doc> <prompt>PEAR password (for maintainers)</prompt> <group>Maintainers</group> </password> <verbose> <type>integer</type> <default><constant>PEAR_CONFIG_DEFAULT_VERBOSE</constant></default> <doc>verbosity level 0: really quiet 1: somewhat quiet 2: verbose 3: debug</doc> <prompt>Debug Log Level</prompt> <group>Advanced</group> </verbose> <preferred_state> <type>set</type> <default><constant>PEAR_CONFIG_DEFAULT_PREFERRED_STATE</constant></default> <doc>the installer will prefer releases with this state when installing packages without a version or state specified</doc> <valid_set>stable</valid_set> <valid_set>beta</valid_set> <valid_set>alpha</valid_set> <valid_set>devel</valid_set> <valid_set>snapshot</valid_set> <prompt>Preferred Package State</prompt> <group>Advanced</group> </preferred_state> </config_vars> |
Note that the simple array defining the set converts each value into a separate <valid_set> tag for the preferred_state configuration variable.
The <default> tag's value can accept either a simple string, or three different kinds of tags:
<text> - this will be converted into a PHP string
<constant> - the contents of this sub-tag will be used to retrieve the value of a pre-defined PHP constant, or a pre-defined PEAR constant (as defined in PEAR_Config or PEAR_Common) and substitute the value for the <constant> tag.
any default configuration variable. These include default_channel, preferred_mirror, remote_config, auto_discover, master_server, http_proxy, php_dir, ext_dir, doc_dir, bin_dir, data_dir, test_dir, cache_dir, php_bin, username, password, verbose, preferred_state, umask, cache_ttl, sig_type, sig_bin, sig_keyid, and sig_keydir.
when used, the configuration variable should simply be an empty tag like <php_dir/>. The tag will be replaced with the default value of the configuration variable, not the currently assigned value.
For instance, this example default value:
<default><text0>hi there </text0><constant>PHP_OS</constant><text1> user, your default php_dir is </text1><php_dir/></default> |
might convert into something like "hi there Linux user, your default php_dir is /usr/local/lib/php/pear".
Our example Chiarafoo role's foo_dir default value:
<default><php_dir/><constant>DIRECTORY_SEPARATOR</constant><text>Foo</text></default> |
might convert into something like "/usr/local/lib/php/Foo" or "C:\php5\pear\Foo".
Note that in order to use multiple <constant> or <text> tags, you must append a numbered suffix as in the <text0> <text1> example above. Only one PEAR configuration variable may be used per default value.
Note that if you use <type>integer</type>, no matter what default value is specified, it will be casted into an integer by PEAR_Config.
For many small library packages, very little customization is needed. Just install and go. package.xml 1.0 is very good at this task. As packages grow in size and complexity, it is often necessary to make slight changes to the contents of files, and occasionally to external components such as databases.
package.xml 1.0 provides a single undocumented system of customizing file contents through the <replace> tag, like so:
<file name="blah.php" role="php"> <replace from="@token@" to="version" type="package-info"/> <replace from="@anothertoken@" to="php_dir" type="pear-config"/> </file> |
This example above would scan the blah.php file at installation, and then use str_replace() to replace all occurences of the string @token@ with the package's version number. Then, it would replace all occurences of the string @anothertoken@ with the value of the user's php_dir configuration variable.
Although powerful, the replace tag is the only customization tag available in package.xml version 1.0. When developing package.xml version 2.0, the replace tag and innovative work of other projects such as Phing became the inspiration for an expanded kind customization called a "task".
Tasks are defined by xml children of a <file> tag. Tasks are implemented by extending the PEAR_Task_Common task.
Tasks are defined in package.xml through the tasks namespace, which is currently http://pear.php.net/dtd/tasks-1.0. The current tasks namespace is defined by http://pear.php.net/dtd/tasks-1.0.xsd. Custom tasks bundled with PEAR include:
The xml for each of these tasks is documented here.
Creating a custom task involves creating a class that validates xml, and performs the task when called upon. Tasks can be invoked in two situations: at package-time and at install-time. Each task can control whether it should be called at package-time, install-time, or at both times.
There are two kinds of tasks: simple and multiple. Most tasks are simple tasks. Simple tasks are self-contained: all customization is limited to that file. Multiple tasks are collected during installation and processed fully as a unit after files have been committed to disk, allowing more complex processing.
All simple tasks must define 3 methods, all multiple task must define 4 methods. These are:
run() (multiple tasks only)
This method is called upon package.xml validation and should be used to validate the task's xml content. Upon error, a simple array of format array(CODE, message) must be returned. The code must be one of the following constants, as defined in PEAR/Task/Common.php:
PEAR_TASK_ERROR_NOATTRIBS - Attributes were expected, but none were present.
PEAR_TASK_ERROR_MISSING_ATTRIB - A specific attribute is not present.
PEAR_TASK_ERROR_WRONG_ATTRIB_VALUE - The value of an attribute is incorrect.
PEAR_TASK_ERROR_INVALID - Any other error in validation.
The error message should include the file name as defined by $fileAttributes['name'], and include as much useful information about the location of the validation error as possible.
This is the package.xml object that contains the task.
The raw parsed content of the task's xml as parsed from package.xml. Tags like <tasks:windowseol> that have no attributes or child elements will be passed an empty string ''. Otherwise, simple text content will be a string, and nested tags/attributes will be passed in as an array. Here is a list of sample xml and their parsed values:
<tasks:blah/> |
string("");
<tasks:blah>hello </tasks:blah> |
string("hello");
<tasks:blah>hello <tasks:boo/> </tasks:blah> |
array('_content' => 'hello', 'tasks:boo' => string(''))
<tasks:blah foo="one"> <tasks:boo/> </tasks:blah> |
array('attribs' => array('foo' => 'one'), 'tasks:boo' => string(''))
This is the current configuration object
The parsed attributes of the <file> tag that encloses this tag. This is guaranteed to contain indices name, specifying the file name, and role, specifying the file role. Other attributes like baseinstalldir may be present but are not required, and so will not be guaranteed to be present for every file.
The init() function is called immediately prior to the startSession() method, and should be used for initialization that is not directly related to file modification. This method may move to another location in the installation process at any time. The logical separation of initialization from task action is important and the order of execution can be depended upon.
The raw parsed content of the task's xml as parsed from package.xml. Tags like <tasks:windowseol> that have no attributes or child elements will be passed an empty string ''. Otherwise, simple text content will be a string, and nested tags/attributes will be passed in as an array. Here is a list of sample xml and their parsed values:
<tasks:blah/> |
string("");
<tasks:blah>hello </tasks:blah> |
string("hello");
<tasks:blah>hello <tasks:boo/> </tasks:blah> |
array('_content' => 'hello', 'tasks:boo' => string(''))
<tasks:blah foo="one"> <tasks:boo/> </tasks:blah> |
array('attribs' => array('foo' => 'one'), 'tasks:boo' => string(''))
The parsed attributes of the <file> tag that encloses this tag. This is guaranteed to contain indices name, specifying the file name, and role, specifying the file role. Other attributes like baseinstalldir may be present but are not required, and so will not be guaranteed to be present for every file.
This will be set to the string representing the version of the last installed version of this package. This is useful for determining whether the package is being upgraded or is a fresh installation. If the package is being installed for the first time, NULL will be passed in.
For non-script tasks, startSession() is called to actually execute a task. The task should perform all needed operations on the file contents, and on success return the file contents regardless of any modification. These contents will be written to disk, so it is imperative that they be the full, original file contents if no modification is made to them.
For script tasks, startSession() is called to determine whether the script can be safely executed. For both task types, script and non-script, a return value of FALSE will cause the task to be silently skipped. A return value of a PEAR_Error will cause processing of all operations to stop, and an error message to be displayed by the installer prior to exiting. Any other return value will cause the script to be processed normally by the frontend as a post-installation script.
The original contents of the file whose <file> tag in package.xml contains the task tag.
The full path to the final installed file location. This is strictly informational, as the file does not yet exist, and should only be used for error messages or other processing that does not attempt to modify the file.
The run() method should return FALSE on success, and an error message if there is a problem. This method is called only for tasks that define $this->type as multiple. For each task within package.xml that has this task, the run() method will be called with an array containing all of the task objects from the package.xml.
An array of task objects.
Incomplete documentation |
Documentation is not yet complete |
The XML format for defining a post-install script in package.xml is documented here. This document describes the required elements for the PHP post-install script itself.
Post-install script files can be named anything one desires, but the class within the file must be the same name as the file with all path separators replaced by underscores. In other words, this postinstall script:
Path/To/Script.php
Must contain a class named Path_To_Script. Due to casing differences between operating systems, it is recommended to always use lowercased file names.
The post-install script class must contain two methods, one named init(), and the other named run(). The init() method is called at the same time as all other post-install scripts. The run() method is called at the conclusion of each parameter group in order to process the user's responses to queries.
The current configuration used for installation.
The package.xml contents as abstracted by this object.
The last version of this package that was installed. This is a very important parameter, as it is the only way to determine whether a package is being installed from scratch, or upgraded from a previous version. Using this parameter, it is possible to determine what incremental changes, if any, need to be performed.
if $paramGroupId is _undoOnError, then $infoArray will contain a list of successfully completed parameter group sections. This can be used to restore any system changes made by the installation script.
Otherwise, $infoArray contains the results of the user input from the most recent <paramgroup> section.
This variable either contains _undoOnError or the contents of the most recent <paramgroup>'s <id> tag. Note that paramgroup id cannot begin with an underscore (_), and so _undoOnError can only be triggered by the PEAR installer.
Центральная часть руководства рассказывает о базовых классах PEAR.
PEAR предоставляет функции для обработки ошибок и варианты поведения в случае ошибки. Все это дает возможность разработчикам пакетов значительно упростить свою жизнь.
Базовый класс PEAR предоставляет стандартную функциональность, которая может быть использована большинством классов PEAR. Обычно не требуется создавать объект этого класса, для этого используется наследование от него.
Главные особенности базового класса PEAR:
"деструкторы" объектов, срабатывающие при завершении обработки запроса
обработка ошибок
Если ваш класс ClassName наследует класс PEAR, то вы можете объявить метод _ClassName (имя класса с префиксом в виде подчеркивания), которые будет вызван по окончанию обработки запроса. Этот метод не является деструктором в том смысле, что вы можете "удалить" объект с его помощью, это метод объекта, который вызывается при завершении работы РНР. См. пример.
Важно! | |
Для того, чтобы обеспечить работу деструкторов, вы должны создавать объект вашего класса с помощью оператора "=& new". Вот так: this:
Если вы будете использовать "= new", то объект, который будет зарегистрирован - будет его копией на тот момент, когда будет вызван конструктор. Соответственно, "деструктор" будет вызван именно у копии вашего объекта. |
Базовый класс PEAR также предоставляет инструмент для обработки ошибок более сложных, чем возврат значений true/false или числовых кодов. Ошибка в PEAR - это объект, который является экземпляром класса PEAR_Error или класса, который наследует PEAR_Error.
Один из основных принципов обработки ошибок в PEAR гласит, что ошибки не должны автоматически приводить к выводу на экран пользователя, ошибки должны обрабатываться вообще без какого-либо вывода на экран, если это требуется. Это позволяет обрабатывать ошибки "вежливо", кроме того, это позволяет избежать нежелательного вывода тогда, когда вы используете не HTML, а, например, XML или WML.
Класс ошибок позволяет настроить себя так, что при возникновении ошибки (т.е. при создании экземпляра этого класса) могут выполняться различные действия. Например, вывод сообщения об ошибке, вывод сообщения и прекращение выполнения программы, вывод сообщения с помощью функции trigger_error(), вызов заранее назначенной функции или ничего из вышеперечисленного. Обычно эти параметры указываются в конструкторе PEAR_Error, но все эти параметры являются опциональными и вы можете использовать установки по умолчанию для ошибок, которые используются в классах, наследующих класс PEAR. См. примеры ошибок PEAR и документацию по PEAR_Error для более полной информации.
Пример, приведенный ниже, показывает как использовать "деструкторы для бедных" PEAR для того, чтобы создать объект, содержимым которого является файл; объект позволяет добавлять данные в конец и записывает их при окончании обработки запроса:
Пример 27-1. Эмулируемые деструкторы PEAR
|
Замечание: "Деструкторы" PEAR используют функцию register_shutdown_function() в PHP, и в PHP < 4.1 вы не можете выводить ничего в этот момент, если PHP работает с веб-сервером. Поэтому любой вывод в деструкторе будет просто потерян, если PHP используется не в командной строке. В PHP 4.1 и выше уже возможен вывод в деструкторе.
Кроме этого, обратите внимаение на предупреждение о том как следует создавать экземпляр объекта, если вы хотите использовать деструктор.
Следующие примеры иллюстрируют различные пути использования механизма обработки ошибок PEAR.
Пример 27-2. Пример обработки ошибок в PEAR (1)
|
В примере используется враппер для fsockopen(), который при возникновении ошибки возвращает её код и текст в виде объекта PEAR_Error. Заметьте, что PEAR::isError() используется для того, чтобы определить является ли ошибкой возвращаемое значение.
PEAR_Error в этом примере работает в режиме, при котором ошибка просто возвращается, а её обработка ложится на плечи программиста. Это поведение является поведением по умолчанию.
В следующем примере мы покажем вам как использовать поведение по умолчанию:
Пример 27-3. PEAR error example (2)
|
Здесь мы сначала меняем поведение по умолчанию на PEAR_ERROR_DIE, а потом, т.к. мы не указываем режим работы в raiseError() (это должно было бы быть 3-м параметром), raiseError() использует поведение по умолчанию и прекращает выполнение скрипта при завершении fsockopen() с ошибкой.
Класс PEAR использует несколько глобальных переменных для установок по умолчанию, а список объектов используется для работы "деструкторов". Все глобальные переменные, которые использует класс PEAR носят имя с префиксом _PEAR_.
Если не установлен режим по умолчанию, то этот режим будет использован. Должен быть равен PEAR_ERROR_RETURN, PEAR_ERROR_PRINT, PEAR_ERROR_TRIGGER, PEAR_ERROR_DIE или PEAR_ERROR_CALLBACK.
Не меняйте значение это переменной напрямую, используйте PEAR::setErrorHandling()для этого:
Если используется режим работы PEAR_ERROR_TRIGGER, то должна иметь значение E_USER_NOTICE, E_USER_WARNING или E_USER_ERROR.
Не меняйте значение это переменной напрямую, используйте PEAR::setErrorHandling() для этого:
Если при возврате ошибки не был указан параметр options и используется режим обработки ошибок PEAR_ERROR_CALLBACK, то значение этой переменной используется как имя функции, которая будет вызвана при появлении ошибки. Это означает, что вы можете временно переключить режим обработки ошибок без повторного указания имени функции-обработчика. Может иметь ст Here is an example of how you can switch back and forth without specifying the callback function again: роковое значение с именем функции или двухэлементный массив с объектом по индексу 0 и с именем метода по индексу 1.
Еще раз повторим: не меняйте значение этой переменной напрямую, используйте PEAR::setErrorHandling() для этого:
Следующий пример показывает как можно переключаться между режимами обработки ошибок без повторного указания функции-обработчика:
Если вы хотите использовать функциональность деструкторов PEAR, то вам необходимо вызвать метод $this->PEAR() в конструкторе вашего класса.
Does nothing right now, but is included for forward compatibility, so subclass destructors should always call it.
Если ваш класс является статическим, то вам, вероятно, понадобятся статические атрибуты. Вы можете эмулировать их с помощью этого метода примерно так:
$myVar = &PEAR::getStaticProperty('myVar'); |
string $class - имя вашего класса, в котором вы вызываете getStaticProperty()
string $var - имя статического атрибута
mixed - ссылку на атрибут. Если атрибут не был инициализирован, то ему автоматически будет присвоено значение NULL.
Пример 27-1. Использование getStaticProperty()
Этот пример выведет:
|
array $func - имя класса и его метод.
array $var - аргументы вызываемой функции. Параметры передаются функции в том порядке, в котором они входят в массив.
Пример 27-1. Использование registerShutdownFunc()
|
Error message string or PEAR_Error object. The default message is unknown error if left blank.
Error code. It is recommended to use an error code for even the simplest errors, in order to simplify error handling and processing.
Error mode. This is one of PEAR_ERROR_RETURN, PEAR_ERROR_PRINT, PEAR_ERROR_TRIGGER, PEAR_ERROR_DIE, PEAR_ERROR_CALLBACK, or PEAR_ERROR_EXCEPTION. See setErrorHandling() for detailed information and examples of the meaning of these constants.
Error options. This depends on the value of $mode, and is documented in setErrorHandling().
Optional user information. This can be used to store any error-specific information, and has an unspecified format.
Error class name to use as the error object. The default error class is PEAR_Error. Use this parameter to specify another class to use, such as a custom class extending PEAR_Error
Use this parameter if you are using a custom class that does not accept an error message in its constructor. Never use this parameter without the $error_class parameter - it will not work.
A PEAR_Error object is returned, unless PEAR_ERROR_DIE terminates execution or a PEAR_ERROR_EXCEPTION is never handled.
setErrorHandling() может быть вызвана статически и как метод объекта. При статическом вызове setErrorHandling() устанавливает поведение по умолчанию для всех объектов PEAR. При вызове метода объекта setErrorHandling() устанавливает поведение по умолчанию только для этого объекта.
integer $mode - имеет значение, равное одной из следующих констант:
PEAR_ERROR_RETURN если происходит ошибка, то возвращается объект PEAR_Error.
PEAR_ERROR_PRINT похожа на PEAR_ERROR_RETURN, но при этом выводится сообщение об ошибке.
PEAR_ERROR_TRIGGER похожа на PEAR_ERROR_RETURN, но при этом дополнительно вызывается функция trigger_error().
PEAR_ERROR_DIE - выполнение прерывается и выводится сообщение об ошибке.
PEAR_ERROR_CALLBACK - при возникновении ошибки вызывается указанная функция-обработчик. Функция должна принимать объект класса PEAR_Error в качестве параметра.
mixed $options - значения опций зависят от параметра $mode
PEAR_ERROR_PRINT и PEAR_ERROR_DIE поддерживают опциональный параметр - строку для функции printf(), для форматирования вывода ошибки.
PEAR_ERROR_TRIGGER требует указания уровня ошибки: ( E_USER_NOTICE, E_USER_WARNING или E_USER_ERROR).
PEAR_ERROR_CALLBACK требует указания имени функции, которая будет вызвана.
Этот метод используется для того, чтобы указать какие ошибки вы ожидаете получить. Ожидаемые ошибки всегда возвращаются в режиме PEAR_ERROR_RETURN. Ожидаемые коды ошибок хранятся в стеке, а этот метод заносит в него новый элемент. Список ожидаемых ошибок используется до тех пор, пока они не извлечены из стека методом popExpect().
mixed $errorCode - ожидаемый код ошибки PEAR_Error или массив кодов. Если указано значение '*' - ожидается любая ошибка.
mixed - код ошибки, который был извлечен или массив кодов, которые были извлечены
The case-sensitive name of the PHP extension without filename suffix or php_ prefix.
Пример 27-1. Loading the domxml-extension
|
PEAR_Error - это объект, которые создается каждой функцией PEAR в случае возникновения ошибки. Он предоставляется информацию о том, почему функция завершилась с ошибкой.
Как именно вы получаете объект - зависит от PEAR::SetErrorHandling()
string $message - текст ошибки. Короткое описание возникшей проблемы.
string $code - код ошибки.
integer $mode - режим обработки ошибок.
mixed $options - дополнительные опции режима обработки ошибок
string $userinfo - строка с дополнительной инфорамацией об ошибке
PEAR_ErrorStack is an experimental error raising and handling implementation for PEAR that is designed to replace PEAR_Error when it has stabilized. PEAR_ErrorStack is both backwards compatible with PEAR_Error and forward compatible with PHP 5's PEAR_Exception class. There are many other features, all described in the Introduction.
Usage:
1 // global error stack 2 $global_stack = &PEAR_ErrorStack::singleton('MyPackage'); 3 // local error stack 4 $local_stack = new PEAR_ErrorStack('MyPackage'); |
This class is available as part of the PEAR package. Features include:
Fully unit-tested and documented
blazingly fast - blows PEAR_Error out of the water
Package-specific errors
Error levels (notice/warning/error/exception)
Error context data is saved separate from error message
Error cascading - parent errors can be specified
Dynamic error message generation allows generation of multiple and distinct error messages from the same error object
Sophisticated callbacks are available for error message generation, error context generation, and error handling functionality, see Error Context Display, Custom Error Message Generation, and controlling error generation
PEAR_ErrorStack implements error raising and handling using a stack pattern. This has tremendous advantages over the PEAR_Error Implementation. PEAR_Error centralizes all error creation and handling in the constructor of the PEAR_Error object. Once an object has been created, all handling must have been completed, either through checking the return value of a method, or through a single global callback. In addition, it is nearly impossible to determine the source of an error, and the baggage of all of the PEAR base class's bulky, slow methods accompanies every error creation.
<?php // traditional PEAR_Error usage require_once 'PEAR.php'; class myobj { // there is no way to know where $err comes from function errorCallback($err) { $this->display($err->getMessage()); $this->log($err->getMessage()); } function log($msg) { error_log($msg, 3, 'somefile.log') } function display($msg) { echo $msg . '<br />'; } } $myobj = new myobj; // using a callback PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, array(&$myobj, 'errorCallback')); $ret = SomePackage::doSomething(); if (PEAR::isError($ret)) { // do some handling - this error is also displayed and logged } PEAR::pushErrorHandling(PEAR_ERROR_RETURN); $ret = SomePackage::doSomething(); if (PEAR::isError($ret)) { // do some handling - this error is not displayed or logged } PEAR::popErrorHandling(); ?> |
The PEAR_ErrorStack class has built in knowledge of the Log package, can easily differentiate and even automatically re-package errors with little to no difficulty.
<?php // PEAR_ErrorStack error handling require_once 'PEAR/ErrorStack.php'; require_once 'Log.php'; define('MYPACKAGE_ERROR_DBERROR', 1); class myobj { var $_stack; function myobj() { $this->_stack = &PEAR_ErrorStack::singleton('MyPackage'); } function errorCallback($err) { switch($err['package']){ case 'MyPackage': // tell the error stack to log the error only // it will not be pushed onto the stack return PEAR_ERRORSTACK_LOG; break; case 'InternalDbPackage': // re-package these errors as a mypackage error fit // for enduser consumption $this->_stack->push(MYPACKAGE_ERROR_DBERROR, 'error', array('dbmessage' => $err['message'], 'dbcode' => $err['code'], 'We are having Connection problems, please' . 'try again in a few moments'), '', $err); // include the error as re-packaged // tell the internal DB error stack to ignore this error, // as if it never happened return PEAR_ERRORSTACK_IGNORE; break; } // switch } } $myobj = &new myobj; // separate error stacks for my package, and the internal DB package $dbstack = &PEAR_ErrorStack::singleton('InternalDbPackage'); $mystack = &PEAR_ErrorStack::singleton('MyPackage'); // set up a file log using PEAR::Log $log = &Log::Factory('file', 'somefile.log', 'MyPackage error log'); $mystack->setLogger($log); // set up a default log to use for all error stacks PEAR_ErrorStack::setDefaultLogger($log); // any errors returned by MyPackage are logged $ret = SomePackage::doSomething(); // Note that $ret need not be checked for any error condition - errors are // totally separate from code if ($dbstack->hasErrors()) { var_dump($dbstack->getErrors(); } // sets a default callback for all errors PEAR_ErrorStack::setDefaultCallback(array(&$myobj, 'errorCallback')); // any db errors are transparently repackaged as // user-friendly MyPackage errors now $ret = SomePackage::doSomething(); ?> |
Why write a new error-handling routine when PEAR_Error already exists? There are several problems with PEAR_Error. Although an error message is present in an error class, processing this error message automatically is excessively difficult for computers. In addition, the error message cannot easily be translated once it has been placed into the PEAR_Error. There is also no standard facility for storing error-related data in the error class. On top of error message-related issues, there is no way to automatically determine which package a PEAR_Error object comes from, or the severity of an error. Fatal errors look exactly the same as non-fatal errors.
The largest flaw with PEAR_Error object is the single-error type design. Every PEAR_Error object is just a PEAR_Error object. There is no differentiating between the severity of an error, or its origin. The only way to determine the severity is to use PEAR_ERROR_TRIGGER and E_USER_NOTICE/E_USER_WARNING/E_USER_ERROR constants from php's trigger_error. But using this functionality does not justify 900 lines of code, simply because trigger_error() is built into PHP itself!
Now, to start using your newly created error objects, change all of your PEAR::raiseError() or PEAR::throwError() calls from this...
<?php require_once 'PEAR.php'; // old way: $error_specific_info = 'bad'; $e = PEAR::raiseError("error message - very " . $error_specific_info . " way to do things", MYPACKAGE_ERROR_FOO); // another old way: $e = PEAR::throwError("error message - very " . $error_specific_info . " way to do things", MYPACKAGE_ERROR_FOO); ?> |
...to something like this:
<?php require_once 'PEAR/ErrorStack.php'; // new way // version 1: stack instance access $stack = &PEAR_ErrorStack::singleton('MyPackage'); $stack->push(MYPACKAGE_ERROR_DBERROR, 'error', array('query' => $query, 'dsn' => $dsn), 'Critical Database Error: Contact Administrator immediately'); // version 2: static singleton access (slightly slower) PEAR_ErrorStack::staticPush('MyPackage', MYPACKAGE_ERROR_DBERROR, 'error', array('query' => $query, 'dsn' => $dsn), 'Critical Database Error: Contact Administrator immediately'); ?> |
For basic use, this is all that is needed to use the PEAR_ErrorStack package in place of PEAR_Error.
In some cases, you may want to customize error generation. For instance, for many exceptions, it is useful to include file, line number, and class/function context information in order to trace an error. A default option is available which will be sufficient for most cases, and that is PEAR_ErrorStack::getFileLine().
Not all package errors occur in the PHP source file. For instance, compiling template engines errors can occur in the template source files. Database errors can occur in the text of a query, or internal to the database server. Internet package errors can occur on another server. All of this information can be included in an error message using a context grabbing callback.
<?php require_once 'PEAR/ErrorStack.php'; class DatabaseClass { var $_dbError; var $_dbErrorMsg; var $_dbQuery; var $_dbPos; /** * Context grabber for the Database package * @param integer Error Code * @param array Error parameters passed into {@link PEAR_ErrorStack::push()} * @param array Output of debug_backtrace() (not used in this callback) */ function getErrorContext($code, $params, $backtrace) { $context = array( 'errorcode' => $this->_dbError, 'errormsg' => $this->_dbErrorMsg, 'query' => $this->_dbQuery, 'pos' => $this->_dbPos, ); return $context; } } $db = new DatabaseClass; PEAR_ErrorStack::staticSetContextCallback('Database', array(&$db, 'getErrorContext')); ?> |
The context information is formatted to be easily processed by an external application. If you wish context information to be in the error message, the error message callback should be used to add the information in a human-readable format to the error message, as described in the next section.
There are three methods of PEAR_ErrorStack designed for use with generating error messages efficiently. To use them, you must do one of three things:
Call PEAR_ErrorStack::setErrorMessageTemplate(), and set an array mapping error codes to error message templates, like so:
<?php define('ERROR_ONE', 1); define('ERROR_TWO', 2); define('ERROR_THREE', 3); define('ERROR_FOUR', 4); require_once 'PEAR/ErrorStack.php'; $stack = &PEAR_ErrorStack::singleton('mypackage'); $messages = array( ERROR_ONE => 'The gronk number %num% dropped a %thing%', ERROR_TWO => 'The %list% items were missing', ERROR_THREE => 'I like chocolate, how about %you%?', ERROR_FOUR => 'and a %partridge% in a pear %tree%', ); $stack->setErrorMessageTemplate($messages); ?> |
Substitution is done using str_replace, and is very simple. Basically, if a variable name is enclosed in percent signs (%), it will be replaced with the value passed in the associative array. If an array
array('varname' => 'value'); |
In addition, if values are objects, the methods will search for a method named "__toString()" and if found, will use that to convert the object to a string. If an array of strings is passed in, they will be joined by commas.
<?php array('varname' => array('first', 'second', 'third')); // this will become 'first, second, third' ?> |
Call PEAR_ErrorStack::setMessageCallback(), and set a custom error message generating function or method. This is probably the best option for the majority of complex situations, as it allows users to override or even extend the existing error message callback using PEAR_ErrorStack::getMessageCallback(). For example:
<?php require_once 'PEAR/ErrorStack.php'; class foo { var $_oldcallback; function callback(&$stack, $err) { $message = call_user_func_array($this->_oldcallback, array(&$stack, $err)); $message .= "File " . $err['context']['file']; return $message; } } $a = new foo; $stack = &PEAR_ErrorStack::singleton('otherpackage'); $a->_oldcallback = $stack->getMessageCallback('otherpackage'); $stack->setMessageCallback(array(&$a, 'callback')); ?> |
Extend PEAR_ErrorStack with your own class, and override PEAR_ErrorStack::getErrorMessageTemplate() or PEAR_ErrorStack::getErrorMessage(). To guarantee that this class will be used by other packages/applications, use this code right after the class declaration:
<?php PEAR_ErrorStack::singleton('mypackage', false, null, 'MyPEAR_ErrorStack'); ?> |
There are many scenarios in which fine-grained control over error raising is absolutely necessary. A generic error handling callback means that every single error raised will be handled in the same error callback. Although PEAR_ErrorStack is designed to operate with independent callbacks for each package, generic error handling is possible through the PEAR_ErrorStack::staticPushCallback() method. This is no different from PEAR_Error's PEAR_ERROR_CALLBACK error handling mode.
PEAR_ErrorStack's real strength comes from the callback itself. PEAR_Error's callback has no actual effect on the error message - all error handling must happen in the callback method or function itself. PEAR_ErrorStack's callback can influence the error through the use of three constants:
PEAR_ERRORSTACK_IGNORE informs the stack to ignore the error, as if it never occurred. The error will be neither logged, nor pushed on the stack. It will, however, be returned from PEAR_ErrorStack::push()
PEAR_ERRORSTACK_PUSH informs the stack to push the error onto the error stack, but not to log the error.
PEAR_ERRORSTACK_LOG informs the stack not to push the error onto the error stack, but only to log the error.
<?php define('ERROR_CODE_ONE',1); define('ERROR_CODE_TWO',2); define('ERROR_CODE_THREE',3); require_once 'PEAR/ErrorStack.php'; require_once 'Log.php'; function somecallback($err) { switch($err['code']){ case ERROR_CODE_ONE: return PEAR_ERRORSTACK_IGNORE; break; case ERROR_CODE_TWO: return PEAR_ERRORSTACK_PUSH; break; case ERROR_CODE_THREE: return PEAR_ERRORSTACK_LOG; break; } // switch } $log = &Log::factory('display'); $stack = &PEAR_ErrorStack::singleton('mypackage'); $stack->setLogger($log); $stack->pushCallback('somecallback'); $stack->push(ERROR_CODE_ONE); $stack->push(ERROR_CODE_TWO); $stack->push(ERROR_CODE_THREE); var_dump(PEAR_ErrorStack::staticGetErrors()); // simulate PEAR_ERROR_CALLBACK, with specific callback for mypackage // every other package will only log errors, only mypackage's errors // are pushed on the stack, conditionally class myclass { function acallback($err) { return PEAR_ERRORSTACK_LOG; } } $stack2 = PEAR_ErrorStack::singleton('anotherpackage'); $stack3 = &PEAR_ErrorStack::singleton('thirdpackage'); PEAR_ErrorStack::setDefaultCallback(array('myclass', 'acallback')); ?> |
The most obvious usage for an error callback involves a common scenario in many user-level applications that use system-level packages. If you write a Content Management System (CMS) with the PEAR DB package, it is usually a bad idea to display database-level errors when a user clicks on a link to add a message to a forum. PEAR_ErrorStack can be used to repackage this error as a MyPackage error.
<?php define('MYPACKAGE_ERROR_DBDOWN',1); require_once 'PEAR/ErrorStack.php'; function repackage($err) { if ($err['package'] == 'DB') { $mystack = &PEAR_ErrorStack::singleton('mypackage'); $mystack->push(MYPACKAGE_ERROR_DBDOWN, 'error', array('olderror' => $err)); // ignore the DB error, but save it in the mypackage error, for logging return PEAR_ERRORSTACK_IGNORE; } } ?> |
One of the difficult-to-use strengths of PEAR_Error involves the PEAR::expectError() method. With regular PHP errors, it is possible to silence them using the @ operator like so:
<?php @file_get_contents(); ?> |
Emulating this behavior with PEAR_ErrorStack is simple.
<?php define('ERROR_CODE_SOMETHING', 1); require_once 'PEAR/ErrorStack.php'; function silence($err) { // ignore all errors return PEAR_ERRORSTACK_IGNORE; } $stack = &PEAR_ErrorStack::singleton('mypackage'); $stack->pushCallback('silence'); $stack->push(ERROR_CODE_SOMETHING); ?> |
PEAR_ErrorStack can take this one step further, and only log errors or only put errors on the error stack, using the other two constants. Finally, particular errors can be singled out, and all others ignored.
<?php define('SOMEPACKAGE_ERROR_THING', 1); require_once 'PEAR/ErrorStack.php'; function silenceSome($err) { if ($err['package'] != 'somepackage') { // ignore all errors from other packages return PEAR_ERROR_IGNORE; } if ($err['code'] != SOMEPACKAGE_ERROR_THING) { // ignore all other error codes return PEAR_ERRORSTACK_IGNORE; } } $stack = &PEAR_ErrorStack::singleton('mypackage'); $stack->pushCallback('silenceSome'); $stack->push(ERROR_CODE_SOMETHING); ?> |
PEAR_ErrorStack can also be programmed to automatically raise a PEAR_Error using PEAR::raiseError(), simply pass in true to the PEAR_Error compatibility like so:
<?php require_once 'PEAR/ErrorStack.php'; $stack = &PEAR_ErrorStack::singleton('mypackage', false, false, true); ?> |
PEAR_ErrorStack can coordinate with the new PEAR_Exception class to convert into an exception with this code: You can set the exception class name that will be returned using the following code:
<?php require_once 'PEAR/ErrorStack.php'; require_once 'PEAR/Exception.php'; $stack = &PEAR_ErrorStack::singleton('mypackage'); $stack->push(1, 'test error'); throw new PEAR_Exception('did not work', $stack->pop()); ?> |
Внимание |
As of PEAR 1.3.2, PEAR_ErrorStack no longer instantiates and returns an Exception object in PHP5, and the last parameter has been removed. Code that relies upon this behavior will break. |
Creates a new private PEAR_ErrorStack. To access a universal stack, use PEAR_ErrorStack::singleton()
name of the package this error stack represents
callback used for error message generation
callback used for context generation, defaults to getFileLine()
exception class to instantiate if in PHP 5
This method may also be called by a custom error message generator to fill in template values from the params array, simply set the third parameter to the error message template string to use
The special variable %__msg% is reserved: use it only to specify where a message passed in by the user should be placed in the template, like so:
Error message: %msg% - internal error
If the message passed like so:
<?php $stack->push(ERROR_CODE, 'error', array(), 'server error 500'); ?> |
The returned error message will be "Error message: server error 500 - internal error"
Pre-generated error message template
Retrieve all errors since last purge, or filter all errors and only return errors of a particular error level, leaving the rest on the stack.
set in order to empty the error stack
Level name to check for a particular severity. Use this to determine whether only a particular class of errors has occurred, such as whether any warnings have occurred (errors will be ignored)
This function uses a backtrace generated from debug_backtrace and so will not work at all in PHP < 4.3.0. The frame should reference the frame that contains the source of the error.
Results of debug_backtrace()
backtrace frame.
returns either array('file' => file, 'line' => line, 'function' => function name, 'class' => class name) or if this doesn't work, then false
Level name to check for a particular severity. Use this to determine whether only a particular class of errors has occurred, such as whether any warnings have occurred (errors will be ignored)
since 0.4alpha it is no longer possible to specify a specific error level to return - the last error pushed will be returned instead.
Внимание |
As of PEAR 1.3.2, PEAR_ErrorStack no longer instantiates and returns an Exception object in PHP5. Code that relies upon this behavior will break. |
If the message generator exists, it is called with 2 parameters.
the current Error Stack object
an array that is in the same format as an error. Available indices are 'code', 'package', 'time', 'params', 'level', and 'context'
Package-specific error code
Error level. This is NOT spell-checked
associative array of error parameters
Error message, or a portion of it if the message is to be generated
If this error re-packages an error pushed by another package, place the array returned from pop() in this parameter
Protected parameter: use this to pass in the http://www.php.net/manual-lookup.php?pattern=debug_backtrace that should be used to find error context.
returns if compatibility mode is on, a PEAR_Error is also thrown. If the class Exception exists, then one is returned to allow code like:
<?php 1 throw ($stack->push(MY_ERROR_CODE, 'error', array('username' => 'grob'))); ?> |
The errorData property of the exception class will be set to the array that would normally be returned. If a PEAR_Error is returned, the userinfo property is set to the array
Otherwise, an array is returned in this format:
<?php 1 array( 2 'code' => $code, 3 'params' => $params, 4 'package' => $this->_package, 5 'level' => $level, 6 'time' => time(), 7 'context' => $context, 8 'message' => $msg, 9 //['repackage' => $err] repackaged error array 10 ); ?> |
The return value must be one of the PEAR_ERRORSTACK_* constants.
This functionality can be used to emulate PEAR's pushErrorHandling, and the PEAR_ERROR_CALLBACK mode, without affecting the integrity of the error stack or logging
see PEAR_ErrorStack::popCallback()
see PEAR_ERRORSTACK_PUSHANDLOG, PEAR_ERRORSTACK_PUSH, PEAR_ERRORSTACK_LOG
This method sets the callback that can be used to generate context information for an error. Passing in NULL will disable context generation and remove the expensive call to debug_backtrace()
The array format must be: array(error code => 'message template',...)
Error message parameters passed into push() will be used as input for the error message. If the template is 'message %foo% was %bar%', and the parameters are array('foo' => 'one', 'bar' => 'six'), the error message returned will be 'message one was six'
This method sets the callback that can be used to generate error messages for any PEAR_ErrorStack instance
require_once 'PEAR/ErrorStack.php'; |
PEAR_ErrorStack
&
PEAR_ErrorStack::singleton
(string
$package [, callback
$msgCallback = FALSE [, callback
$contextCallback = FALSE [, boolean
$throwPEAR_Error = FALSE, string
[$stackClass = 'PEAR_ErrorStack']]]])
Внимание |
As of PEAR 1.3.2, PEAR_ErrorStack no longer instantiates and returns an Exception object in PHP5, and the second-to-last parameter has been removed. Code that relies upon this behavior will break. |
Note that all parameters are ignored if the stack for package $package has already been instantiated
name of the package this error stack represents
callback used for error message generation
callback used for context generation, defaults to getFileLine()
If TRUE, then PEAR::raiseError() will be called and a PEAR_Error object will be returned from calls to PEAR_ErrorStack::push()
class to instantiate
Внимание |
As of PEAR 1.3.2, the second parameter is a new parameter $level. Any code that relies on $merge being the second parameter will break. |
Static version of PEAR_ErrorStack::getErrors() , returns all errors from all singleton stacks.
Set to purge the error stack of existing errors
Level name to check for a particular severity. Use this to determine whether only a particular class of errors has occurred, such as whether any warnings have occurred (errors will be ignored)
Set to return a flat array, not organized by package
Function used to sort a merged array - default sorts by time, and should be good for most cases
Static version of PEAR_ErrorStack::hasErrors(). Returns TRUE if any singleton stack has any errors pending. Since PEAR 1.3.2, If $package is specified, it will call PEAR_ErrorStack::hasErrors for the singleton error stack of that package. If level is specified, hasErrors will ignore any errors not conforming to the error level specified. Use this to simulate error_reporting(E_NOTICE), for example
Package name to retrieve error information from, or false to retrieve error information from all singleton stacks
Level name to check for a particular severity. Use this to determine whether only a particular class of errors has occurred, such as whether any warnings have occurred (errors will be ignored)
Pop a callback from every Error Stack. No check is made to determine whether this is a good idea, so use with discretion.
Package name this error belongs to
Package-specific error code
Error level. This is NOT spell-checked
associative array of error parameters
Error message, or a portion of it if the message is to be generated
If this error re-packages an error pushed by another package, place the array returned from pop() in this parameter
Protected parameter: use this to pass in the debug_backtrace that should be used to find error context
see PEAR_ErrorStack::staticPopCallback() , PEAR_ErrorStack::pushCallback()
see PEAR_ERRORSTACK_PUSHANDLOG , PEAR_ERRORSTACK_PUSH , PEAR_ERRORSTACK_LOG
require_once 'PEAR/ErrorStack.php'; |
void PEAR_ErrorStack::_log
(array $err [, array $levels = array(
'exception' => PEAR_LOG_CRIT,
'alert' => PEAR_LOG_ALERT,
'critical' => PEAR_LOG_CRIT,
'error' => PEAR_LOG_ERR,
'warning' => PEAR_LOG_WARNING,
'notice' => PEAR_LOG_NOTICE,
'info' => PEAR_LOG_INFO,
'debug' => PEAR_LOG_DEBUG)])
This is a protected function, and should only be called by child classes that extend PEAR_ErrorStack
Таблица 27-1. Constants defined in ErrorStack.php
Name | Value | Line Number |
---|---|---|
PEAR_ERRORSTACK_ERR_NONCLASS | 1 | 110 |
PEAR_ERRORSTACK_ERR_OBJTOSTRING | 2 | 116 |
PEAR_ERRORSTACK_IGNORE | 4 | 103 |
PEAR_ERRORSTACK_LOG | 3 | 99 |
PEAR_ERRORSTACK_PUSH | 2 | 94 |
PEAR_ERRORSTACK_PUSHANDLOG | 1 | 89 |
Функции для работы с комадной строкой
System предоставляет API для написания кроссплатформенных программ, работающих с командной строкой.
Функции класса System называются так же, как и утилиты командной строки
if (!System::rm('-r file1 dir1')) { print "Could not delete all the files"; } |
System::rm(array('-r', 'file1', 'dir1')); |
Ошибки будут выведены с помощью функции trigger_error()(), для их отключения следует использовать префикс '@' (например: @System::mkdir('-p dir1/dir2/dir3');).
Класс System предоставляет интерфейс к функциям файловой системы. Они носят те же имена, что и утилиты для работы с файловой системой в Unix и поддерживают те же опции независимо от вашей операционной системы.
На данный момент функции были протестированы под Linux и Windows. Сообщения о поддержке других систем приветствуются.
Внимание |
На ранних версиях PHP 4 unlink() может завершаться с ошибкой на Windows. Эта ошибка уже исправлена в новых версиях. |
Это справочное руководство описывает параметры функций класса System, обычно представляющие из себя строки. Аргументы и опции конкретных команд не описываются здесь. Подробности ищите в мануале по конкретной команде на системах *nix:
man имякоманды |
Команда rm удаляет файлы. Поддерживается удаление нескольких файлов и рекурсивное удаление директорий.
Пример 27-1. Использование &cat()
|
Создает временные файлы и директории. Эта функция удалит все созданные ей файлы во время завершения работы скрипта.
string $args - Аргументы
prefix - строка, которой будут префиксированы имена временных файлов (по умолчанию - tmp).
-d - будет создана директория, а не файл.
-t - директория, в которой будет создан временный файл или директория. Если этот параметр не указан, то используется переменная окружения TMP на Windows или TMPDIR на Unix. Если эти переменные тоже отсутствуют, то используются c:\windows\temp или /tmp соответственно.
mixed - полный путь к создаваемому файлу или директории; или FALSE в случае неудачи.
Пример 27-1. Использование mktemp()
|
Получает из переменных окружения путь к директории для временных файлов, установленный в системе.
Эта функция может быть вызвана статически.
В php.ini-recommended убран по умолчанию параметр E из директивы variables_order, что делает недоступным массив $_ENV.
Классы PPM предоставляют интерфейс для администрирования и управления пакетами PEAR.
Этот класс предназначен для объектов, из которых вы хотите вынести часть кода в отдельные классы. Это может быть полезно в том случае, если у вас есть класс, который не очень часто используется и вы бы не хотели, чтобы он парсился при каждом запросе.
Дерево классов для PEAR_Autoloader
PEAR
PEAR_Autoloader
Add an aggregate object to this object. If the specified class is not defined, loading it will be attempted following PEAR's file naming scheme. All the methods in the class will be aggregated, except private ones (name starting with an underscore) and constructors.
which method to autoload
which class to find the method in. If the $method parameter is an array, this parameter may be omitted (and will be ignored if not), and the $method parameter will be treated as an associative array with method names as keys and class names as values.
Overloaded object call handler, called each time an undefined/aggregated method is invoked. This method repeats the call in the right aggregate object and passes on the return value.
which method that was called
An array of the parameters passed in the original call
Класс для создания (компиляции) модулей
Дерево классов для PEAR_Builder
PEAR_Common
PEAR_Builder
Build an extension from source. Runs phpize in the source directory, but compiles in a temporary directory (/var/tmp/pear-build-USER/PACKAGE-VERSION).
path to XML package description file
callback function used to report output
array - an array of associative arrays with built files, format:
array( array( 'file' => '/path/to/ext.so', 'php_api' => YYYYMMDD, 'zend_mod_api' => YYYYMMDD, 'zend_ext_api' =>; YYYYMMDD ), ... ) |
Командный класс PEAR, простейшая фабрика для административных команд
command to get optstring for
(reference) short getopt format
(reference) long getopt format
Scan through the Command directory looking for classes and see what commands they implement.
if FALSE (default), the new list of commands should replace the current one. If TRUE, new entries will be merged with old.
where (what directory) to look for classes, defaults to the Command subdirectory of the directory from where this file (__FILE__) is included.
Класс, предоставляющий основную функциональность для административных классов PEAR
Дерево классов для PEAR_Common()
PEAR
PEAR_Common
Register a temporary file or directory. When the destructor is executed, all registered temporary files and directories are removed.
array - hash list of declared_classes, declared_methods, declared_functions and used_classes
Build a "provides" array from data returned by analyzeSourceCode(). The format of the built array is like this:
array( 'class;MyClass' => array( 'type' => 'class', 'name' => 'MyClass' ), ... ) |
array with information about a source file as returned by the analyzeSourceCode() method.
Download a file through HTTP. Considers suggested file name in Content-disposition: header and can run a callback function for different events. The callback will be called with two parameters: the callback type, and parameters. The implemented callback types are:
'setup' - called at the very beginning, parameter is a UI object that should be used for all output
'message' - the parameter is a string with an informational message
'saveas' - may be used to save with a different file name, the parameter is the filename that is about to be used. If a 'saveas' callback returns a non-empty string, that file name will be used as the filename instead. Note that $save_dir will not be affected by this, only the basename of the file.
'start' - download is starting, parameter is number of bytes that are expected, or -1 if unknown
'bytesread' - parameter is the number of bytes read so far
'done' - download is complete, parameter is the total number of bytes read
'connfailed' - if the TCP connection fails, this callback is called with
array(host,port,errno,errmsg) |
'writefailed' - if writing to disk fails, this callback is called with
array(destfile,errmsg) |
the URL to download
PEAR_Frontend_* instance
directory to save file in
function/method to call for status updates
PEAR_Config instance
string - Returns the full path of the downloaded file or a PEAR error on failure. If the error is caused by socket-related errors, the error object will have the fsockopen error code available through getCode().
Returns package information from different sources. This method is able to extract information about a package from a .tgz archive or from a XML package definition file.
Returns information about a package file. Expects the contents of a package xml file as input.
log level (0 is quiet, higher is noisier)
message to write to the log
Wrapper to System::mkDir(), creates a directory as well as any necessary parent directories.
Directory to use as tmpdir. Will use system defaults (for example /tmp or c:\windows\temp) if not specified.
Filename of the package archive or of the package definition file
Array that will contain the errors
Array that will contain the warnings
directory where source files may be found, or empty if they are not available
Дерево классов для PEAR_Config()
PEAR
PEAR_Config
file to read user-defined options from
file to read system-wide defaults from
Get the list of allowed set values for a config value. Returns NULL for config values that are not sets.
array - enumerated array of set values, or NULL if the config key is unknown or not a set
string - type, one of "string", "integer", "file", "directory", "set" or "password".
Merges data into a config layer from a file. Does the same thing as readConfigFile(), except it does not replace all existing values in the config layer.
file to read from
whether to overwrite existing data
config layer to insert data into ('user' or 'system')
Reads configuration data from a file. All existing values in the config layer are discarded and replaced with data from the file.
file to read from, if NULL or not specified, the last-used file for the same layer (second param) is used
config layer to insert data into ('user' or 'system')
Set a config value in a specific layer (defaults to 'user'). Enforces the types defined in the configuration_info array. An integer config variable will be cast to int, and a set config variable will be validated against its legal values.
If you want to keep only one instance of this class in use, this method will give you a reference to the last created PEAR_Config object if one exists, or create a new object.
file to read user-defined options from
file to read system-wide defaults from
Unset the user-defined value of a config key, reverting the value to the system-defined one.
Контролирует зависимости между классами
this variable will contains an error message, if check fail
An Array with all Dependency entries from the parsed XML package definition, ie:
$opts => Array ( ['type'] => 'pkg', ['rel'] => 'ge', ['version'] => '3.4', ['name'] => 'HTML_Common' ); |
mixed - FALSE if all dependencies could be resolved successfully(!); or an PEAR_DEPENDENCY_* constant in case of unresolved dependencies.
this variable will contains an error message, if check fail
Name of the extension to test
Required extension version to compare with
How to compare versions with eachother
mixed - FALSE if dependency could be resolved successfully(!); or an PEAR_DEPENDENCY_* constant in case of an unresolved dependency.
this variable will contains an error message, if check fail
Name of the operating system
mixed - FALSE if dependency could be resolved successfully(!); or an PEAR_DEPENDENCY_* constant in case of unresolved dependency.
this variable will contains an error message, if check fail
Name of the package to test
Required package version to compare with
How to compare versions with eachother
mixed - FALSE if dependency could be resolved successfully(!); or an PEAR_DEPENDENCY_* constant in case of unresolved dependency.
this variable will contains an error message, if check fail
which version to compare
how to compare the version
mixed - FALSE if dependency could be resolved successfully(!); or an PEAR_DEPENDENCY_* constant in case of unresolved dependency.
External program check method. Looks for executable files in directories listed in the PATH environment variable.
this variable will contains an error message, if check fail
which program to look for
mixed - FALSE if dependency could be resolved successfully(!); or an PEAR_DEPENDENCY_* constant in case of unresolved dependency.
this variable will contains an error message, if check fail
name of SAPI backend
which version to compare (currently unused)
how to compare versions (currently hardcoded to 'has')
mixed - FALSE if dependency could be resolved successfully(!); or an PEAR_DEPENDENCY_* constant in case of unresolved dependency.
this variable will contains an error message, if check fail
which version to compare
how to compare the version
Административный класс, используемый для установки пакетов PEAR и поддержания базы установленных пакетов.
Дерево классов для PEAR_Installer()
PEAR_Common
PEAR_Installer
path to the package file
installating options, to enable an option use the option name as array key and TRUE or 1 as value.
$options['force'] = 1 - force installation
$options['register-only'] = 1 - update registry but don't install files
$options['upgrade'] = 1 - upgrade existing install
$options['soft'] = 1 - fail silently
Административный класс, используемый для создания релизов пакетов PEAR.
Дерево классов для PEAR_Packager
PEAR_Common
PEAR_Packager
Административный класс, используемый для поддержания базы установленных пакетов.
Дерево классов для PEAR_Registry
PEAR
PEAR_Registry
string - name of the package the file belongs to, or an empty string if the file does not belong to an installed package
mixed - an array with all information, or a key specific information, if $key was used; NULL if Package or specific information does not exist
Rebuilds the dependencies file of the registry. Use this function if had trouble while installing Packages or a damaged registry.
Rebuilds the registry filemap. Use this function if had trouble while installing Packages or a damaged registry.
mixed - TRUE if successful; or an array with a list of Packages depending on this Package
Update or insert a the dependencies of a package, prechecking that the package won't break any dependency in the process. (Dependencies of type 'pkg' only.
Package name
Version of the Package
Package dependencies
mixed - TRUE if no dependencies found; or array with names of missing or outdated Packages
Класс для осуществления удаленных операция с сервером пакетов PEAR.
Дерево классов для PEAR_Remote()
PEAR
PEAR_Remote
Предоставляет пакеты, позволяющие сделать свою систему аутентификации.
Provides a framework for user authentication.
Our goal during this "mini tutorial" is to set up a system that secures your site with an easy to use authentication mechanism.
At the top of the site to secured, place the following code snippet:
Пример 29-1. Typical usage example for PEAR::Auth
This few lines of code instantiate the authentication system. The first line in the above script includes the file from your PEAR directory. It contains all the necessary code to run PEAR::Auth. Next, we define a function to display the login form which the visitor of your page has to use to enter his login data. You can change all the HTML formatting in this function.
Since we want to use a database to verify the login data, we now create the variable $dsn, it contains a valid DSN string that will be used to connect to the database via PEAR::DB. For the default database table schema or to use a different storage container, please see below for more information. After that we create the authentication object. The first parameter defines the name of the storage container. Because we want to use a database driven storage container, we pass "DB" here. The second parameter is the connection parameter for the container driver. We use the previously defined DSN string. The third parameter is the name of our function that we defined at the beginning of the script. It prints the login form. Now our authentication object is initialized and we need to check if the user is logged in. This is done via the method checkAuth(). If it returns TRUE, we can pass the content of our page to the user. |
Пример 29-2. Using optional authentication
This is a pretty nice example for the optional login feature: The last parameter $optional can be either TRUE or FALSE. If it is FALSE, the login form is not shown and the user only sees the text "Everybody can see this text!". If he clicks on the link above this text, he gets the same page but with the GET parameter "login=1". Now he can enter his login information in the login form. If he successfully logs in, he can then see the text "Everybody can see this text!" and the text "One can only see this if he is logged in!". |
Пример 29-3. Logout functionality The following example performs a "logout" for the current user and displays the login form again.
|
In the following passages we cover more detailed information about the functions of PEAR::Auth.
This SQL statement creates a table usable under the default database authentication scheme using MySQL:
CREATE TABLE auth ( username VARCHAR(50) default '' NOT NULL, password VARCHAR(32) default '' NOT NULL, PRIMARY KEY (username), KEY (password) ); |
These are the table and field names necessary for working authentication. When hashing the passwords with the MD5 algorithm, which is the default encryption method in PEAR::Auth, the password column must be at least 32 characters long. When using another encryption method like DES ("UNIX crypt"), the column size has to be changed correspondingly.
PEAR::Auth uses a number of so called storage containers to store the login data. The following passages describe all of them. If the containers that come with the package don't fit your needs, it is easy to create custom ones, also.
Storage container using a PHP Array.
Storage container using PEAR DB.
A simplified version of the DB container that only provides user authentication. No user management functions are provided.
Storage container using PEAR File_Passwd.
Storage container for use against IMAP servers.
Storage container for use against Kerberos V servers.
Storage container for use against LDAP servers.
Storage container using PEAR MDB.
Storage container using PEAR MDB2.
Storage container for using multiple Auth_Containers in a fall through manner.
Storage container for use against the PEAR website.
Storage container for use against a POP3 server.
Storage container for use against a RADIUS server.
Storage container for use against a SAP server.
Storage container using PEAR File_SMBPasswd.
Storage container for use against a SOAP service using PEAR SOAP as the client.
Storage container for use against a SOAP service using PHP5 SOAP as the client.
Storage container using vpopmail.
Instructions on creating a custom storage container.
Since version 1.5.0 PEAR::Auth provides a facility for retrieving logs of its internal behaviour. This is implemented using PEAR::Log and its log observer components.
Auth provides two levels of log messages which map to the Log priority levels PEAR_LOG_INFO and PEAR_LOG_DEBUG.
PEAR_LOG_INFO messages provide basic information about Auth's decisions, for example user authentication successful/failed, rendering login screen.
PEAR_LOG_DEBUG messages provide detailed information about what is happening within the internals of Auth, for example which functions are called, logic tracking for the Authentication method, what SQL queries are being run against the database backends.
Пример 29-1. Typical usage example for accessing the logs from PEAR::Auth
To enable logging pass the option "enableLogging" with the value TRUE in the options array in the second parameter to the Auth constructor. To retrieve the log messages from Auth create a new subclass of Log_Observer that implements a notify() function to perform whatever actions you want on the log messages. Once defined pass an instance of your new Log_Observer instance to Auth::attachLogObserver(). To limit the types of messages you receive in the Log_Observer pass either PEAR_LOG_INFO or PEAR_LOG_DEBUG as the first parameter to the Log_Observer. The default is PEAR_LOG_INFO. For more information on this filtering see the Log Documentation.
|
This storage container provides a simple way to store a limited number of username/password pairs within the source code of the script.
The storage-specific argument for the Auth constructor() is an array of options.
Таблица 29-1. Available Options
Option | Data Type | Default value | Description | |
---|---|---|---|---|
"cryptType" | string | "none" | The encryption type the password is stored in. | |
"users" | array | array() |
Named array of usernames and password hashes.
|
This container makes use of PEAR::DB abstraction layer for database access. That means that you can use all databases that are supported by the DB abstraction layer to store the login data.
The storage-specific argument for the Auth constructor() is an array of options.
Таблица 29-1. Available Options
Option | Data Type | Default value | Description |
---|---|---|---|
"dsn" | string | "" | A valid and well-formed DSN . |
"table" | string | "auth" | The name of the database table, where the authorization data is stored. |
"usernamecol" | string | "username" | The name of the colunm, where the username is stored |
"passwordcol" | string | "password" | The name of the colunm, where the crypted password is stored. |
"db_fields" | array | array() | An array of extra fields to retrieve when loading the user details. |
"cryptType" | string | "md5" | The encryption type the password is stored in. |
"auto_quote" | boolean | TRUE | Whether to enable automatic quoting of database table and field names. |
"db_options" | array | array() | An array of options to be passed to the PEAR::DB constructor. See PEAR::DB::setOption() for more information. |
"db_where" | string | "" | A string to be appened to the WHERE clause of queries against the database. It is appended to the queries used in fetchData(), listUsers(), removeUser() and changePassword(). Available since Auth 1.5.0. |
The DBLite container is a simplified version of the DB container. It does away with all the code related to user management and simply provides user authentication.
The storage-specific argument for the Auth constructor() is an array of options.
Таблица 29-1. Available Options
Option | Data Type | Default value | Description |
---|---|---|---|
"dsn" | string | "" | A valid and well-formed DSN . |
"table" | string | "auth" | The name of the database table, where the authorization data is stored. |
"usernamecol" | string | "username" | The name of the colunm, where the username is stored |
"passwordcol" | string | "password" | The name of the colunm, where the crypted password is stored. |
"db_fields" | array | array() | An array of extra fields to retrieve when loading the user details. |
"cryptType" | string | "md5" | The encryption type the password is stored in. |
"auto_quote" | boolean | TRUE | Whether to enable automatic quoting of database table and field names. |
"db_options" | array | array() | An array of options to be passed to the PEAR::DB constructor. See PEAR::DB::setOption() for more information. |
"db_where" | string | "" | A string to be appened to the WHERE clause of queries against the database. It is appended to the queries used in fetchData(). Available since Auth 1.5.0. |
description
The storage-specific argument for the Auth constructor() is an array of options.
Таблица 29-1. Available Options
Option | Data Type | Default value | Description |
---|---|---|---|
"type" | string | "Cvs" | The format of the file we are authenticating against. For a list of available types see the PEAR::File_Passwd documentation. |
"file" | string | "" | The filename of the file to use. |
This storage container connects to the specified IMAP server and tries to login there with the specified username/password.
The storage-specific argument for the Auth constructor() is an array of options.
Таблица 29-1. Available Options
Option | Data Type | Default value | Description |
---|---|---|---|
"host" | string | "localhost" | The hostname or the IP address of the IMAP server |
"port" | integer | 143 | The port where the IMAP server is listening |
"baseDSN" | string | "" |
This controls the methods used to connect. Like SSL, TLS and certificate validation. To connect to an SSL IMAP server: "/imap/ssl" To connect to an SSL IMAP server with a self-signed certificate: "'/imap/ssl/novalidate-cert'" Further options may be available and can be found on the php site at http://www.php.net/manual/function.imap-open.php. |
"timeout" | integer | 20 | Timeout in seconds for connecting to the server. |
"checkServer" | boolean | TRUE | Whether to check if we can connect to the server when starting container. |
This storage driver makes use of the PECL kadm5 extension to provide authentication services against a Kerberos V.
The storage-specific argument for the Auth constructor() is an array of options.
Таблица 29-1. Available Options
Option | Data Type | Default value | Description |
---|---|---|---|
"hostname" | string | "localhost" | The hostname or IP address of the Kerberos V server. |
"realm" | string | "" | The Kerberos V realm to authenticate in. |
"timeout" | integer | 10 | Timeout in seconds for connecting to the server. |
"checkServer" | boolean | FALSE | Whether to check if we can connect to the server when starting container. |
This storage container makes use of the ldap extension to load user data from an LDAP server.
The storage-specific argument for the Auth constructor() is an array of options.
Таблица 29-1. Available Options
Option | Data Type | Default value | Description |
---|---|---|---|
"host" | string | "localhost" | The host name or IP-adress to access |
"port" | integer | 389 | The port of the LDAP server to access |
"url" | string | "" | A fully qualified URL for specifying the protocol, url and port to connect to. It is useful for specifying ldaps://. Takes precedence over "host" and "port" options. Only works if PHP has been compiled against OpenLDAP 2+ libraries. |
"version" | integer | 2 | LDAP version to use, ususally 2 (default) or 3, must be an integer! |
"referrals" | boolean | TRUE | If set, determines whether the LDAP library automatically follows referrals returned by LDAP servers or not. |
"binddn" | string | "" | If set, searching for user will be done after binding as this user, if not set the bind will be anonymous. This is reported to make the container work with MS Active Directory, but should work with any server that is configured this way. This has to be a complete dn for now (basedn and userdn will not be appended). |
"bindpw" | string | "" | The password to use for binding with binddn. |
"basedn" | string | "" | The base DN of your server. |
"userdn" | string | "" | Gets prepended to basedn when searching for users. |
"userscope" | string | "sub" | Scope for user searching: one, sub (default), or base. |
"userattr" | string | "uid" | Defines the attribute to search for. |
"userfilter" | string | "(objectClass=posixAccount)" | Filter that will be added to the search filter this way: (&(userattr=username)(userfilter)). |
"attributes" | array | array('') | Array of additional attributes to fetch from entry. These will added to auth data and can be retrieved via Auth::getAuthData() . An empty array will fetch all attributes, array('') will fetch no attributes at all (default). If you add 'dn' as a value to this array, the user's DN that was used for binding will be added to auth data as well. |
"attrformat" | string | "AUTH" |
The returned format of the additional data defined in the 'attributes' option. Two formats are available. LDAP returns data formatted in a multidimensional array where each array starts with a 'count' element providing the number of attributes in the entry, or the number of values for attributes. When set to this format, the only way to retrieve data from the Auth object is by calling getAuthData('attributes'). This was the default format before version 1.3.0. AUTH returns data formatted in a structure more compliant with other Auth Containers, where each attribute element can be directly called by getAuthData() method from Auth. This became the default as of 1.3.0. |
"groupdn" | string | "" | Gets prepended to basedn when searching for group. |
"groupattr" | string | "cn" | The group attribute to search for. |
"groupfilter" | string | "(objectClass=groupOfUniqueNames)" | Filter that will be added to the search filter when searching for a group: (&(groupattr=group)(memberattr=username)(groupfilter)). |
"memberattr" | string | "uniqueMember" | The attribute of the group object where the user dn may be found. |
"memberisdn" | boolean | TRUE | Whether the memberattr is the dn of the user (default) or the value of userattr (usually uid). |
"group" | string | "" | The name of the group users have to be a member of to authenticate successfully. |
"groupscope" | string | "sub" | Scope for group searching: one, sub (default), or base. |
"start_tls" | boolean | "false" | Enable/disable the use of START_TLS encrypted connection. |
"try_all" | boolean | FALSE | If multiple entries are returned by the search attempt to authenticate against each entry in order or just the first one (default). |
"debug" | boolean | FALSE | Enable debug output. |
Пример 29-1. Authenticating against a LDAP server
|
Пример 29-2. Requiring users to be within specific groups
|
Пример 29-3. Authenticating against a Microsoft Active Directory server
|
When talking to a Microsoft ActiveDirectory server you have to use 'samaccountname' as the 'userattr' and follow special rules to translate the ActiveDirectory directory names into 'basedn'. The 'basedn' for the default 'Users' folder on an ActiveDirectory server for the ActiveDirectory Domain (which is not related to its DNS name) "win2000.example.org" would be: "CN=Users, DC=win2000, DC=example, DC=org" where every component of the domain name becomes a DC attribute of its own. If you want to use a custom users folder you have to replace "CN=Users" with a sequence of "OU" attributes that specify the path to your custom folder in reverse order. So the ActiveDirectory folder "win2000.example.org\Custom\Accounts" would become "OU=Accounts, OU=Custom, DC=win2000, DC=example, DC=org"
It seems that binding anonymously to an Active Directory is not allowed, so you have to set binddn and bindpw for user searching.
LDAP Referrals need to be set to false for AD to work sometimes.
Note also that if you want an encrypted connection to an MS LDAP server, then, on your webserver, you must specify "TLS_REQCERT never" in /etc/ldap/ldap.conf or in the webserver user's ~/.ldaprc (which may or may not be read depending on your configuration).
This container makes use of PEAR::MDB abstraction layer for database access. That means that you can use all databases that are supported by the MDB abstraction layer to store the login data.
The storage-specific argument for the Auth constructor() is an array of options.
Таблица 29-1. Available Options
Option | Data Type | Default value | Description |
---|---|---|---|
"dsn" | string | "" | A valid and well-formed DSN . |
"table" | string | "auth" | The name of the database table, where the authorization data is stored. |
"usernamecol" | string | "username" | The name of the colunm, where the username is stored |
"passwordcol" | string | "password" | The name of the colunm, where the crypted password is stored. |
"db_fields" | array | array() | An array of extra fields to retrieve when loading the user details. |
"cryptType" | string | "md5" | The encryption type the password is stored in. |
"auto_quote" | boolean | TRUE | Whether to enable automatic quoting of database table and field names. |
"db_options" | array | array() | An array of options to be passed to the PEAR::MDB constructor. See PEAR::MDB for more information. |
"db_where" | string | "" | A string to be appened to the WHERE clause of queries against the database. It is appended to the queries used in fetchData(), listUsers(), removeUser() and changePassword(). Available since Auth 1.5.0. |
This container makes use of PEAR::MDB2 abstraction layer for database access. That means that you can use all databases that are supported by the MDB2 abstraction layer to store the login data.
The storage-specific argument for the Auth constructor() is an array of options.
Таблица 29-1. Available Options
Option | Data Type | Default value | Description |
---|---|---|---|
"dsn" | string | "" | A valid and well-formed DSN . |
"table" | string | "auth" | The name of the database table, where the authorization data is stored. |
"usernamecol" | string | "username" | The name of the colunm, where the username is stored |
"passwordcol" | string | "password" | The name of the colunm, where the crypted password is stored. |
"db_fields" | array | array() | An array of extra fields to retrieve when loading the user details. |
"cryptType" | string | "md5" | The encryption type the password is stored in. |
"auto_quote" | boolean | TRUE | Whether to enable automatic quoting of database table and field names. |
"db_options" | array | array() | An array of options to be passed to the PEAR::MDB2 constructor. See PEAR::MDB2 for more information. |
"db_where" | string | "" | A string to be appened to the WHERE clause of queries against the database. It is appended to the queries used in fetchData(), listUsers(), removeUser() and changePassword(). Available since Auth 1.5.0. |
By default, MDB2's default portability setting of MDB2_PORTABILITY_ALL is used. This setting may cause unexpected behaviour, such as field names being converted to lowercase regardless of their definition in the database schema. The "db_options" option can be used to override this, as shown in the following example.
Пример 29-1. Example overriding MDB2's default portability
|
This container provides a facility to attempt to authenticate against multiple Auth_Containers in order.
If a container's getAuthData() returns true Auth_Container_Multiple will return true.
When a container's getAuthData() returns false Auth_Container_Multiple will continue on through the list of available containers until a successful login is found or the list of containers is expired.
On receipt of an error from getAuthData() Auth_Container_Multiple will abort checking further containers and return the error.
The storage-specific argument for the Auth constructor() is an array of container configurations. Each container configuration has the following options:
Таблица 29-1. Available Options
Option | Data Type | Default value | Description |
---|---|---|---|
"type" | string | "" | The type of container to instanciate. This is the same value as used in the first parameter of the Auth constructor() . |
"options" | array | array() | This is the standard array of options required for the container. |
Пример 29-1. Example usage of Auth_Container_Multiple
|
This container provides authentication services against the PEAR website (http://pear.php.net/) and it's developer accounts.
This container does not take an storage specific options.
This storage container connects to the specified POP3 server and tries to login there with the specified username/password.
The storage-specific argument for the Auth constructor() is an array of options.
Таблица 29-1. Available Options
Option | Data Type | Default value | Description |
---|---|---|---|
"host" | string | "localhost" | The hostname or IP address of the POP3 server. |
"port" | integer | "110" | The port number the POP3 server is listening on. |
"method" | boolean or string | TRUE |
The authentication method to use with the POP3 server. Available options:
|
You need Auth_RADIUS and the PECL radius in order to get this container to work.
The storage-specific argument for the Auth constructor() is an array of options.
Таблица 29-1. Available Options
Option | Data Type | Default value | Description |
---|---|---|---|
"servers" | array | array("localhost", 0, "testing123", 3, 3) |
Array of RADIUS servers, containing: host, port, shared secret, timeout, maxtries. The host parameter specifies the server host, either as a fully qualified domain name or as a dotted-quad IP address in text form. The port parameter specifies the UDP port to contact on the server. If port is given as 0, the library looks up the radius/udp entry in the network services database, and uses the port found there. If no entry is found, the library uses the standard RADIUS port for authentication (1812). The shared secret for the server host is passed to the secret parameter. The RADIUS protocol ignores all but the leading 128 bytes of the shared secret. The timeout for receiving replies from the server is passed to the timeout parameter, in units of seconds. The maximum number of repeated requests to make before giving up is passed into the maxtries parameter. At most 10 servers may be specified. When multiple servers are given, they are tried in round-robin fashion until a valid response is received, or until each server's maxtries limit has been reached. |
"authtype" | string | "PAP" |
The authentication method for validating the request. Possible values are: PAP, CHAP_MD5, MSCHAPv1, MSCHAPv2. There are dependencies for the different methods. For all authentication methods except PAP you need the Crypt_CHAP package, when you are using MS-CHAP you need also the mhash extension. |
This container allows authentication against a SAP server using the SAPRFC extension available at http://saprfc.sourceforge.net/.
The storage-specific argument for the Auth constructor() is an array of options which are passed directly to the SAPRFC extension. None of the options are used internally, for more details see the SAPRFC's documentation.
This storage container provides authentication against SAMBA smbpasswd files. It makes use of the PEAR File_SMBPasswd package.
The storage-specific argument for the Auth constructor() is a string containing the filename of the SAMBA smbpasswd file to use.
This container makes use of the PEAR SOAP client to provide authentication against a SOAP service.
The storage-specific argument for the Auth constructor() is an array of options.
Таблица 29-1. Available Options
Option | Data Type | Default value | Description | |
---|---|---|---|---|
"endpoint" | string | The URI where the service is located. | ||
"namespace" | string | The namespace of the web service. | ||
"method" | string | The SOAP method you wish to call. | ||
"encoding" | string | The content encoding that should be used (e.g. UTF-8). | ||
"usernamefield" | string | The name of the field where the username is stored. | ||
"passwordfield" | string | The name of the field where the password is stored. | ||
"matchpasswords" | boolean | TRUE |
If TRUE then the container will look for the password field in the returned result from the soap call and try to match that value with the one supplied from the end user. If FALSE then it is assumed that the soap call will return an error if the user does not authenticate properly. If no error is returned than the user is assumed to valid and allowed to proceed. | |
"_features" | array |
A named array of extra parameters that are to be passed to the soap call in addition to the username and password fields. These are passed to the soap call as named parameters.
|
This container makes use of the PHP SOAP extension's client to provide authentication against a SOAP service.
The storage-specific argument for the Auth constructor() is an array of options. In addition to the below options all options for the PHP SOAP Client can be passed in this array and they will be passed onto the client.
Таблица 29-1. Available Options
Option | Data Type | Default value | Description | |
---|---|---|---|---|
"wsdl" | string | The location of the WSDL file describing the SOAP service you wish to authenticate against. The WSDL file takes priority over a specified "location" and "uri". | ||
"location" | string | The URI where the service is located, when not making use of a WSDL file. | ||
"uri" | string | The namespace of the web service, when not making use of a WSDL file. | ||
"method" | string | The SOAP method you wish to call. | ||
"usernamefield" | string | "username" | The name of the field where the username is stored. | |
"passwordfield" | string | "password" | The name of the field where the password is stored. | |
"matchpasswords" | boolean | TRUE |
If TRUE then the container will look for the password field in the returned result from the soap call and try to match that value with the one supplied from the end user. If FALSE then it is assumed that the soap call will return an error if the user does not authenticate properly. If no error is returned than the user is assumed to valid and allowed to proceed. | |
"_features" | array |
A named array of extra parameters that are to be passed to the soap call in addition to the username and password fields. These are passed to the soap call as named parameters.
|
This container uses an existing vpopmail service to validate the username and the password.
It does not require any storage-specific argument.
Here is a skeleton for a custom Auth storage container
Пример 29-1. CustomAuthContainer.php
|
And here is how to use it.
Пример 29-2. authcustom.php
|
PEAR::Auth_Frontend_HTML provides a generic default login page for use with PEAR::Auth. When building your own login page it is a reasonable place to start as it includes all the required elements of the login form.
-3
Returned if the Auth Container in use is unable to validate the username/password pair supplied.
-4
Returned if the requested function is not implemented by the Auth Container in use.
Constructor for the authentication system.
The constructor will ensure that the PHP session management is started by calling session_start(). This is done as Auth requires a session to be active to operate correctly.
Name of the storage driver that should be used, alternatively you can pass a custom Auth_Container object.
The options that are passed to the storage container.
The name of a user-defined function that prints the login screen. This function is passed three parameters when called $username, $status, &$auth. These are in order the previously attempted username, the status code that caused the previous auth attempt to fail and a reference to the Auth object itself.
Defines if the login is optional or not.
Пример 29-1. Using different DB parameters
|
This example shows you how you can specifiy alternative names for the database table and the column names. In our example, we use the table myAuth, select the username from the field myUserColumn and the password from the field myPasswordColumn. The default values for this fields are auth, username and password. Note that you can also specify an existing DB object with the dsn parameter instead of a DSN.
This feature is necessary if you want to use PEAR::Auth with a database layout that is different from the one PEAR::Auth uses by default.
Пример 29-2. Using different DB parameters
|
This example shows you how you can pass your own storage container to Auth.
If the storage containers supplied with Auth are not capable of fulfilling your requirements, you can easliy create your own storage container. Read the storage containers section for more info Introduction - The storage drivers
the username of the new user
the password of the new user
additional options to be passed to the creation of the new user. Each Auth_Container has different options for these, please see the containers documentation for what is supported.
Эта функция не должна вызываться статически.
Not all Auth Containers implement this functionality.
Attach an instance of a Log_Observer to the internal Log object. This allows the internal logs to be accessed and used as you wish within your application.
Эта функция не должна вызываться статически.
This function has only been available since version 1.5.0.
Эта функция не должна вызываться статически.
Not all Auth Containers implement this functionality.
boolean - If a session with valid authentication information exists, the function return TRUE. Otherwise it returns FALSE.
boolean - If the user has already been authenticated, the function returns TRUE. Otherwise it returns FALSE.
array - An array of user details. Currently no consistency, see each Auth Container for details on how and what they return.
Эта функция не должна вызываться статически.
Not all Auth Containers implement this functionality.
Эта функция не должна вызываться статически.
Not all Auth Containers implement this functionality.
Enables advanced security features to make man in the middle attacks and session hijacking much harder. Cookies and java script must be enabled on the client browser for some of these features to function correctly.
Enables the following security features of auth
Detection of client ip address change or User-Agent header change if such a change is detected the user will be logged out
Each client request a special unique cookie is given to the client. He must present this cookie on his next request. This cookie changes on every request. If client does not present the valid cookie he will be logged out.
Enables challenge responce for the default login screen of auth. The user password will be hashed with javascript before sent back to the server. Prevents the user password being stolen using password sniffing tools. Password is hashed with a random key so the md5 hash is not subject to brute force password cracking. This will only work for storage containers which support challenge responce password authenthication. Currently only the DB, MDB and MDB2 containers support this for md5 and clear text passwords
Замечание: This method is available since 1.3.0
TRUE if you want to enable advanced security features FALSE if you want to disable them.
Controls if auth will process the post variables and attempt to login the user from those pages. For better security of your application it is recomended to disable login in all pages except your login page.
Mark the session up to indicate that the username supplied has successfully logged in. Although normally used for internal purposes this function can be used to fake a login.
Эта функция не должна вызываться статически.
This function will also call session_regenerate_id() so as to prevent session fixation attacks.
This function allows the registration of extra information to be stored allowing with the authentication data.
the name of the data field
the value of the data field
whether to overwrite the value of the data field if it already exists.
This function sets a callback function which is called whenever the validity of a logged in session is checked. This callback can be used to perform actions like checking the authentication source to see if the logged in user is still enabled.
The callback function will be passed two parameters, the username that successfully logged in and a reference to the Auth object. The callback function should return a boolean depending upon whether the session should continue or not. TRUE to allow the session to continue, FALSE to abort the session.
If the session is aborted by this callback the status will be set to AUTH_CALLBACK_ABORT.
With this function you can set the maximum expire time that is used by auth to a new value.
expiration time, number of seconds
if TRUE $time is added to the existing expiration time, if FALSE the exitsing time value will be replaced.
Эта функция не должна вызываться статически.
Auth uses PHP's session mechanism to recognize users between http calls. Setting Auth's expiry time larger than the session timeout will still expire the session to the time the php session expires.
This function sets a callback function which is called upon failed login of a user account.
The callback function will be passed two parameters, the username that failed to login and a reference to the Auth object.
With this function one can set the maximum idle time to a new value. The term "idle time" describes the maximum time interval (in seconds) between two actions by the user. If the maximum idle time is reached, the user will be automatically logged out. If on the other hand the user performs any action within the maximum idle time interval, the idle time is reset.
idle time in seconds
if TRUE $time is added to the existing idle time, if FALSE the existing time value will be replaced.
This function sets a callback function which is called upon successful login of a user account.
The callback function will be passed two parameters, the username that successfully logged in and a reference to the Auth object.
This function sets a callback function which is called upon successful logout of a user account.
The callback function will be passed two parameters, the username that successfully logged out and a reference to the Auth object.
This function can set a customized name for the session that is created during the login process. The default for this session name is "PHPSESSID".
Эта функция не должна вызываться статически.
You have to use setSessionName(), if you are running two or more different applications with Auth on the same domain. If you don't use this function, a user who has once logged in at one of the applications can also use the other applications without logging in again!
Controls if the login page will be displayed to the user. Normally you might need to display the login form only on a certain page of your web application.
true if you want to display the login form and false if you want to hide it.
Эта функция не должна вызываться статически.
This is equivalent to the 4th paramether of Auth::Auth()
This method returns the time in seconds after which the idle time of the current authentication session has reached its limit, which will cause the user to be logged out automatically. If no maximum idle time is set, which is the default configuration of PEAR::Auth, this method will return 0.
Start the authentication process. To do this Auth checks for an existing session and checks it's validity. If there is no existing session or the previous session has been ended for some reason then the login form is generated either via the specified callback or using the default form implemented in Auth_Frontend_HTML.
Provides a framework for user authentication (aka an "User-Login") based on the HTTP
Instead of generating an HTML driven form like PEAR::Auth does, this class sends header commands to the clients which cause them to present a login box like they are e.g. used in Apache's .htaccess mechanism.
Starting with Auth_HTTP 2.1.0, HTTP Digest Authentication (RFC2617) is experimentally supported.
name of the storage driver that should be used
a string containing some login information or an array containing a bunch of options for the storage driver
Пример 29-1. Using different DB parameters
|
<?php // example of Auth_HTTP basic implementation require_once("Auth/HTTP.php"); // setting the database connection options $AuthOptions = array( 'dsn'=>"pgsql://test:test@localhost/testdb", 'table'=>"testable", // your table name 'usernamecol'=>"username", // the table username column 'passwordcol'=>"password", // the table password column 'cryptType'=>"none", // password encryption type in your db ); $a = new Auth_HTTP("DB", $AuthOptions); $a->setRealm('yourrealm'); // realm name $a->setCancelText('<h2>Error 401</h2>'); // error message if authentication fails $a->start(); // starting the authentication process if($a->getAuth()) // checking for autenticated user { echo "Hello $a->username welcome to my secret page"; }; ?> |
<?php // example of Auth_HTTP implementation with encrypted password and multiple columns fetch require_once("Auth/HTTP.php"); // setting the database connection options $AuthOptions = array( 'dsn'=>"pgsql://test:test@localhost/testdb", 'table'=>"testable", // your table name 'usernamecol'=>"username", // the table username column 'passwordcol'=>"password", // the table password column 'cryptType'=>"md5", // password encryption type in your db 'db_fields'=>"*", // enabling fetch for other db columns ); $a = new Auth_HTTP("DB", $AuthOptions); $a->setRealm('yourrealm'); // realm name $a->setCancelText('<h2>Error 401</h2>'); // error message if authentication fails $a->start(); // starting the authentication process if($a->getAuth()) // checking for autenticated user { echo "Hello $a->username welcome to my secret page <BR>"; echo "Your details on file are: <BR>"; echo $a->getAuthData('userid'); // retriving other details from the database row echo $a->getAuthData('telephone'); // in this example the user id, telephone number echo $a->getAuthData('email'); // and email address }; ?> |
boolean - If the user has already been authenticated, the function returns TRUE. Otherwise it returns FALSE.
This function returns the current status of PEAR::Auth. The return values are constants that are defined by PEAR Auth.
Предоставляет пакеты для создания кэширования.
Cache_Lite provides a fast, light and safe cache system. It's optimized for file containers and protected against cache corruptions (because it uses file locking and/or hash tests).
PEAR::Cache_Lite is a little cache system. It's optimized for high traffic websites so it is really fast and safe (because it uses file locking and/or anti-corruption tests).
Note : An independant documentation of Cache_Lite is available in chinese on this page.
Before all, PEAR::Cache_Lite has to be extremely fast. That returns the use of PEAR possible on sites with high traffic without falling in hi-level hardware solutions.
You can find more details about cache_lite technical choices on the this document. but the main idea is to include PEAR.php file ONLY when an error occurs (very rare).
Because the cache system is often embedded in the application layer, PEAR::Cache_Lite kernel has to be small and flexible with an adapted licence (LGPL). Advanced functionnalities can be found in files that extends the core.
On high traffic websites, the cache system has to be really protected against cache files corruptions (because of concurrent accesses in read/write mode). Very few cache systems offer a protection against this problem.
File locking is not a perfect solution because it is useless with NFS or multithreaded servers. So in addition to it, PEAR::Cache_Lite offers two fully transparent mechanisms (based on hash keys) to guarantee the security of the data in all circumstances. Just have a look at the link given in the previous paragraph for more details.
Every module of Cache_Lite follows the same philosophy.
Parameters (others than default ones) are passed to the constructor by using an associative array.
A cache file is identified by a cache ID (and eventually a group). For obvious flexibility reasons, the logic of IDs choice is left to the developer.
In the following, we will use the term "group" as a pool of cache files and the term "block" as a piece of an HTML page.
Let's start with a simple example : the page is built then recovered in an unique variable (string):
<?php // Include the package require_once('Cache/Lite.php'); // Set a id for this cache $id = '123'; // Set a few options $options = array( 'cacheDir' => '/tmp/', 'lifeTime' => 3600 ); // Create a Cache_Lite object $Cache_Lite = new Cache_Lite($options); // Test if thereis a valide cache for this id if ($data = $Cache_Lite->get($id)) { // Cache hit ! // Content is in $data // (...) } else { // No valid cache found (you have to make the page) // Cache miss ! // Put in $data datas to put in cache // (...) $Cache_Lite->save($data); } ?> |
If you wish use a cache per block and not a global cache, take as example the following script:
<?php require_once('Cache/Lite.php'); $options = array( 'cacheDir' => '/tmp/', 'lifeTime' => 3600 ); // Create a Cache_Lite object $Cache_Lite = new Cache_Lite($options); if ($data = $Cache_Lite->get('block1')) { echo($data); } else { $data = 'Data of the block 1'; $Cache_Lite->save($data); } echo('<br><br>Non cached line !<br><br>'); if ($data = $Cache_Lite->get('block2')) { echo($data); } else { $data = 'Data of the block 2'; $Cache_Lite->save($data); } ?> |
However, it is not always possible to recover all the contents of a page in a single string variable. Thus Cache_Lite_Output comes to our help :
<?php require_once('Cache/Lite/Output.php'); $options = array( 'cacheDir' => '/tmp/', 'lifeTime' => 10 ); $cache = new Cache_Lite_Output($options); if (!($cache->start('123'))) { // Cache missed... for($i=0;$i<1000;$i++) { // Making of the page... echo('0123456789'); } $cache->end(); } ?> |
The idea is the same for a per block usage :
<?php require_once('Cache/Lite/Output.php'); $options = array( 'cacheDir' => '/tmp/', 'lifeTime' => 10 ); $cache = new Cache_Lite_Output($options); if (!($cache->start('block1'))) { // Cache missed... echo('Data of the block 1 !'); $cache->end(); } echo('Non cached line !'); if (!($cache->start('block2'))) { // Cache missed... echo('Data of the block 2 !'); $cache->end(); } ?> |
For a maximum efficiency with Cache_Lite, do not systematically include every package the page needs. ONLY load the modules you need when the page is not in the cache (and has to be recomputed) by using a conditionnal inclusion.
The BAD way :
<?php require_once("Cache/Lite.php"); require_once("...") require_once("...") // (...) $cache = new Cache_Lite(); if ($data = $Cache_Lite->get($id)) { // cache hit ! echo($data); } else { // page has to be (re)constructed in $data // (...) $Cache_Lite->save($data); } ?> |
Here is the good way (often more than twice faster) :
<?php require_once("Cache/Lite.php"); // (...) $cache = new Cache_Lite(); if ($data = $Cache_Lite->get($id)) { // cache hit ! echo($data); } else { // page has to be (re)constructed in $data require_once("...") require_once("...") // (...) $Cache_Lite->save($data); } ?> |
To go further with Cache_Lite, have a look at examples and technical details bundled with the package.
The constructor of the Cache_Lite core class. You can give an associative array as an argument to set a lot of options.
associative array to set a lot of options
Таблица 31-1.
Option | Data Type | Default Value | Description |
---|---|---|---|
cacheDir | string | /tmp/ | directory where to put the cache file (with a trailing slash at the end) |
caching | boolean | TRUE | enable / disable caching |
lifeTime | integer | 3600 | cache lifetime in seconds (since 1.6.0beta 1, you can use a null value for an eternal cache lifetime) |
fileLocking | boolean | TRUE | enable / disable fileLocking. Can avoid cache corruption under bad circumstances. |
writeControl | boolean | TRUE | enable / disable write control. Enable write control will lightly slow the cache writing but not the cache reading. Write control can detect some corrupt cache files but maybe it's not a perfect control. |
readControl | boolean | TRUE | enable / disable read control. If enabled, a control key is embeded in cache file and this key is compared with the one calculated after the reading |
readControlType | string | crc32 | Type of read control (only if read control is enabled). Must be 'md5' (for a md5 hash control (best but slowest)), 'crc32' (for a crc32 hash control (lightly less safe but faster)) or 'strlen' (for a length only test (fastest)) |
pearErrorMode | integer | CACHE_LITE_ERROR_RETURN | pear error mode (when raiseError is called) (CACHE_LITE_ERROR_RETURN for just returning a PEAR_Error object or CACHE_LITE_ERROR_DIE for immediate stop of the script (good for debug) ) |
fileNameProtection | boolean | TRUE | file Name protection (if set to true, you can use any cache id or group name, if set to false, it can be faster but cache ids and group names will be used directly in cache file names so be carefull with special characters...) |
automaticSerialization | boolean | FALSE | enable / disable automatic serialization (it can be used to save directly datas which aren't strings but it's slower) |
memoryCaching | boolean | FALSE | enable / disable "Memory Caching" (NB : there is no lifetime for memory caching, only the end of the script) |
onlyMemoryCaching | boolean | FALSE | enable / disable "Only Memory Caching" (if enabled, files are not used anymore) |
memoryCachingLimit | integer | 1000 | max number of records to store into memory caching |
automaticCleaningFactor | integer | 0 | Disable / Tune the automatic cleaning process. The automatic cleaning process destroy too old (for the given life time) cache files when a new cache file is written. 0 means "no automatic cache cleaning", 1 means "systematic cache cleaning" (slow), x>1 means "automatic cleaning randomly 1 times on x cache writes". A value between 20 and 200 is maybe a good start. |
hashedDirectoryLevel | integer | 0 | Set the hashed directory structure level. 0 means "no hashed directory structure", 1 means "one level of directory", 2 means "two levels"... This option can speed up Cache_Lite only when you have many thousands of cache file. Only specific benchs can help you to choose the perfect value for you. Maybe, 1 or 2 is a good start. |
errorHandlingAPIBreak | boolean | FALSE | If set to true, it introduces a little API break but the error handling is better in CACHE_LITE_ERROR_RETURN mode (specially with the save() method which can return a PEAR_Error object). |
Пример 31-1. Using most common options
|
One of the main method of Cache_Lite : test the validity of a cache file and return it if it's available (FALSE else)
cache id
name of the cache group
if set to TRUE, the cache validity won't be tested
Пример 31-1. Usage
|
save the given data (which has to be a string if automaticSerialization is set to FALSE (default)).
data to put in a cache file (can be another type than strings if automaticSerialization is TRUE).
cache id
name of the cache group
Пример 31-1. Usage
|
Пример 31-1. Usage
|
This is a dummy example because the cache is destroyed at the beginning of the script ! So the first case of the if statement is impossible.
if no group is specified all cache files will be destroyed ; else only cache files of the specified group will be destroyed
name of the cache group
flush cache mode : 'old' (clean too old cache files for the current lifetime), 'ingroup' (clean all cache files for the given group), 'notingroup' (clean all the cache files except for the given group), [since 1.5.0 beta] 'callback_myFunc' (call the function 'myFunc' with the complete path file and the group in parameters, if the callback return 'true', the cache file is deleted).
Пример 31-1. Usage
|
This example cleans all of the cache files.
when an error is found, the script will stop and the message will be displayed (in debug mode only) ; same effect than pearErrorMode option in the constructor
cache id
name of the cache group
if set to TRUE, the cache validity won't be tested
include dynamically the PEAR.php file and trigger a PEAR error
To improve performances, the PEAR.php file is included dynamically. The file is so included only when an error is triggered. So, in most cases, the file isn't included and perfs are much better.
[since Cache_Lite-1.7.0beta2] Extend the life of an existent cache file. The cache file is "touched", so it starts a new lifetime period. See this feature request for more details.
Пример 31-1. Classical use
|
The constructor of the Cache_Lite_Output class. You can give an associative array as an argument to set a lot of options.
associative array to set a lot of options (see Cache_Lite constructor for details)
Test if a cache is available and (if yes) return it to the browser. Else, the output buffering is activated.
cache id
name of the cache group
if set to TRUE, the cache validity won't be tested
Пример 31-1. classical using
|
Stop the output buffering started by the start() method and store the output to a cache file
Пример 31-1. Usage
|
The constructor of the Cache_Lite_Output class. You can give an associative array as an argument to set a lot of options.
associative array to set a lot of options (see Cache_Lite constructor for details). Be carefull, with Cache_Lite_Function, additional options are available (comparatively to Cache_Lite). There are described on the following table.
Таблица 31-1.
Option | Data Type | Default Value | Description |
---|---|---|---|
[...] | [...] | [...] | See Cache_Lite constructor for more options |
defaultGroup | string | Cache_Lite_Function | default cache group for function caching |
debugCacheLiteFunction | boolean | FALSE | debug the caching process |
dontCacheWhenTheOutputContainsNOCACHE | boolean | FALSE | Don't cache the method call when its output contains the string "NOCACHE". If set to true, the output of the method will never be displayed (because the output is used to control the cache) |
dontCacheWhenTheResultIsFalse | boolean | FALSE | Don't cache the method call when its result is false |
dontCacheWhenTheResultIsNull | boolean | FALSE | Don't cache the method call when its result is null |
call the given function with given arguments only if there is no cache about it ; else, the output of the function is read from the cache then send to the browser and the return value if read also from the cache and returned.
Пример 31-1. classical using with a function
|
Пример 31-2. classical using with a method
|
If you try to use Cache_Lite_Function with $this object ($cache->call('this->method',...) for example), have a look first at the last example of this page.
Пример 31-3. classical using with a static method
|
Пример 31-4. another using with a method (how to use cache $this->method() calls)
|
So, for method calls, the best way is to use array(&$object, 'nameOfTheMethod') as first argument instead of '$object->nameOfTheMethod' which doesn't work with "$this" for example.
[since Cache_Lite 1.6.0beta1] Drop the cache file of the corresponding function call with given arguments.
Пример 31-1. classical using with a function
|
The constructor of the Cache_Lite_File class. You can give an associative array as an argument to set a lot of options.
associative array to set a lot of options (see Cache_Lite constructor for details). Be carefull, with Cache_Lite_File, there is an additional "mandatory option" described on the following table.
Таблица 31-1.
Option | Data Type | Default Value | Description |
---|---|---|---|
[...] | [...] | [...] | See Cache_Lite constructor for more options |
masterFile [REQUIRED] | string | '' | complete path of the file used for controlling the cache lifetime |
Пример 31-1. Usage
|
Предоставляет пакеты для управления конфигурациямию
The Config package provides methods for configuration manipulation.
Config helps you manipulate your configuration whether they are stored in XML files, PHP arrays or other kind of datasources. It supports these features:
Parse different configuration formats.
Manipulate sections, directives, comments, blanks the way you want.
Write them back to a datasource in your preferred format.
The Config object acts as a container for other Config_Container objects. It doesn't do much but makes handling IO operations easier. It contains the root Config_Container object which in turn contains a child Config_Container object. Config_Container objects store references to their parent and have an array of children. This structure makes it easy to access the different containers and their contents.
A Config_Container object can be of different type:
Section: a section contains other Config_Container objects.
Directive: a directive does not contain any other object but has content and a name. See them as key-value pairs.
Comment: just like directives, comments have content but they don't have a name. They are rendered in a special way according to the configuration type you choosed.
Blank: they don't have neither content or name but are used to indicate blank lines if your renderer uses them.
When using the Config package, most of the work is done with Config_Container objects.
Пример 32-1. An example that will create a new Config_Container
|
The above example illustrates how Config and Config_Container can interact. There are other ways. You could have for example first created the Config object and then used $config->getRoot() to add sections and directives to the returned object reference.
Пример 32-2. Reading configuration from an XML file
In this example the XML file config.xml looks like this:
|
For more information, You can read API doc, sample of package, tests of package, and a great tutorial of DevShed about the Config package.
There are many ways to create content in your Config object. You can simply pass it an array like it is shown in the example below:
Пример 32-1. Create configuration with array
|
You can also ask Config to look for a file on your filesystem and try to parse it. You would then do it like this. This example assumes you have a valid XML file:
Пример 32-2. Create configuration with a file
|
Of course, it is also possible to create the configuration from scratch as shown in the previous section example.
Parses and saves Apache configuration files. No options are provided by this container.
Generic configuration files. The equals, comment start and new line characters in the parser can be customised to match your prefered configuration format.
Таблица 32-1. Available Options
Option | Data Type | Default value | Description |
---|---|---|---|
"comment" | string | "#" | The character that signifies the start of a comment. |
"equals" | string | ":" | The character that separates keys from values. |
"newline" | string | "\" | The character that signifies that a value continues across multiple lines. |
Parses standard INI files, maintaining comments within the file. No options are available for this container.
Parse standard INI files using PHP's in built parse_ini_file(). Does not read in comments. No options are available for this container.
Parses PHP Array structures. Can read from a PHP Source file or from an in memory array. Due to technical limitations, this container does not parse blank lines or comments when reading from a configuration file, therefore any information contained within PHP comments will be lost.
Таблица 32-2. Available Options
Option | Data Type | Default value | Description |
---|---|---|---|
"name" | string | "conf" | The name to use for the root configuration variable, both when parsing and writing PHP source files. |
"useAttr" | boolean | TRUE | Controls whether attributes are parsed and saved. |
Внимание |
Since config files containing php arrays are just included using the standard php methods, code comments and structure will be lost when saving. |
Parses a set of PHP define() from a PHP source file. Comments are maintained by this container, although blank lines will be lost. There are no options for this container.
Parses a XML file using XML_Parser.
Таблица 32-3. Available Options
Option | Data Type | Default value | Description |
---|---|---|---|
"version" | string | "1.0" | The XML version to use. |
"encoding" | string | "ISO-8859-1" | The content encoding to use when parsing and storing data. |
"name" | string | "conf" | As with PHPArray, this defines the name of the global configuration root. |
"indent" | string | " " | The character used for indentation when writing the XML document, if any. By default, two spaces are used. |
"linebreak" | string | "\n" | The line-breaking character(s) to use when writing the XML document. |
"addDecl" | boolean | TRUE | Controls whether the XML declaration is added to the start of the XML document. |
"useAttr" | boolean | TRUE | Controls whether attributes are parsed and saved. |
"isFile" | boolean | TRUE | If TRUE, the first argument to parseConfig() will be taken as the file name for the XML file to load. If FALSE, the argument will be taken as the XML data itself and parsed accordingly. |
"useCData" | boolean | FALSE | Controls whether data is enclosed in CDATA blocks. |
This method returns a reference to the root Config_Container object in the Config object. Use the returned Config_Container object reference to manipulate your configuration data.
This method will parse the datasource given and fill the root Config_Container object with other Config_Container objects. It will return a reference to the root Config_Container object or a PEAR_Error if something went wrong.
Datasource to parse. For most containers, it is a file path. For the PHP array parser, it can be an array too.
Type of configuration to parse
Options for the parser
Пример 32-1. Using parseConfig()
|
The name of the configuration type.
An array defining the file containing the container's class definition and the class name. The format for this array is as follows:
$configInfo = array('path/to/Name.php', // The path to the source file for the class. 'Config_Container_Class_Name' // The name of the container class. ); |
If omitted, the default values are:
$configInfo = array("Config/Container/$configType.php", "Config_Container_$configType" ); |
This method will replace the current child of the root Config_Container object by the given object.
Пример 32-1. Using setRoot()
|
This method will call the root Config_Container::writeDatasrc() method which in turn will try to write the Config contents to the datasource.
Datasource to write to
Type of configuration for writer
Options for writer
This example shows how to convert a configuration from a php file which contains a php array to an xml file.
Пример 32-1. Using writeConfig()
|
Type of container object, should be something among 'section', 'comment', 'directive', 'blank'.
Name of container object. The name is required for sections and directives, not for blanks or comments.
Content of container object. The content is used in directives and comments.
Array of attributes for container object. Optionally, you can add attributes to your container. These can be used by the chosen parser.
This method will add a Config_Container child to the current container children. Thus, addItem() can only be called one a section type container. If a position is specified, the object will be added at this position. If 'before' or 'after' are specified as position, a target object is required. The object will then be added before or after the target object position in the current container.
a container object
choose a position 'bottom', 'top', 'after', 'before'
needed if you choose 'before' or 'after' in $where. $target must be one of this container's children. ZendEngine2 will accept references with default. It will then be possible to have &$target instead.
Пример 32-1. Adding an item using addItem()
|
Пример 32-2. Adding an item using addItem() and a position relative to another item
|
This method will return the number of children this container has. If either $name or $type, it will affine its search just to return the number of children corresponding to these parameters.
Where to create the new item ('top', 'bottom', 'before', 'after')
Required only if 'before' or 'after' is used for $where
Пример 32-1. Create a new directive using createBlank()
|
Comment content
Where to create the new item ('top', 'bottom', 'before', 'after')
Required only if 'before' or 'after' is used for $where
Пример 32-1. Create a new directive using createComment()
|
Name of new directive
Content of new directive
Directive attributes
Where to create the new item ('top', 'bottom', 'before', 'after')
Required only if 'before' or 'after' is used for $where
Пример 32-1. Create a new directive using createDirective()
|
This method must be called on a section, the created item can be anything. It adds a new child to the current item. If a position is specified, the child will be created at there. It is recommended to use the helper methods instead of calling this method directly.
type of item: directive, section, comment, blank...
item name
item content
item attributes
choose a position 'bottom', 'top', 'after', 'before'
needed if you choose 'before' or 'after' for $where
Пример 32-1. Create some new items using createItem()
|
Name of new section
Section attributes
Where to create the new item ('top', 'bottom', 'before', 'after')
Required only if 'before' or 'after' is used for $where
Пример 32-1. Create a new section using createSection()
|
This method returns the value associated with the key attribute. To get all attributes, see method getAttributes().
Пример 32-1. Using attribute
|
Пример 32-2. Attributes are set for '@' key with php array type
|
Пример 32-3. Attributes are set the usual way with xml type
|
Children are stored in an array. This method returns the Config_Container object at the specified index.
This method tries to find the items that respond to the specified parameters.
This method can only be called on an object of type 'section'. Note that root is a section. This method is not recursive and tries to keep the current structure.
type of item: directive, section, comment, blank...
item name
find item with this content
find item with attribute set to the given value
index of the item in the returned object list. If it is not set, will try to return the last item with this name.
Пример 32-1. A few examples on how to find items using getItem()
|
Children Config_Container objects are stored in an array. This method will return the index of this item in its parent array.
Returns the item rank in its parent children array according to other items with same type and name.
There is only one root item. It has no parent, no name, no content and is of type 'section'. The root item is not used in the parsers, only its children.
This method removes the current item. References to its children are removed as well. This method does not accept parameters yet.
This method tries to find an item by following a given path from the current container.
This method can only be called on an object of type 'section'. Note that root is a section. This method is recursive.
This method takes as many parameters as is needed to define your path to the requested item. The format is array (item1, item2, ..., itemN). Items can be strings or arrays. Strings will match the item name, while arrays will match 'name' and/or 'attributes' properties of the requested item.
Strings or arrays of item to match in the order they will be matched, separated by commas
Пример 32-1. Example for searchPath() usage
|
Пример 32-2. More complex example with attributes for searchPath()
|
Attributes are stored in an array. They are used in some containers like PHP Array, XML, Apache. In IniFile or IniCommented containers, attributes are not used. See examples in getAttributes() method to have an idea of the attributes output. This method will replace existing attributes. Use updateAttributes() if you just want to change some of them.
This is an helper method that will first try to find the item with the desired name using getItem(). If the item is found, it will call its setContent() method. If not, it will just create a new directive at the bottom with the given name and content.
Name of the directive to look for
New content, usually a string
Index of the directive to set, in case there are more than one directive with the same name
This method returns an array representation of the Config tree. The format is
$section[directive][index] = value |
Пример 32-1. Using toArray()()
|
Пример 32-2. Resulting array with attributes and directives with same name or not
|
This method will call the toString() method in the choosen config type. It will return a string representation of the Config_Container and its children.
Type of configuration used to generate the string
Specify special options used by the parser
If the specified attributes are already set, they are overwritten. New attributes are set. The ones that are not set in the given parameter array are left untouched.
By default, this method will write a new string generated with the toString() method to a file. If a writeDatasrc() method exists in the chosen config type, this method will be called instead. This allows for more flexibility and makes it possible to add your own save handlers.
Представляет пакеты для приложений, использующих консоль, как pear инсталятор.
Console_Getopt provides functions for easily fetching and processing command-line arguments.
Getopt() supports two types of options: short options and long options
Пример 33-1. Calling a script with short and long options
The long options work equally, but they have to be defined in an array:
|
The return value is an array of two elements: the list of parsed options and the list of non-option command-line arguments. Each entry in the list of parsed options is a pair of elements - the first one specifies the option, and the second one specifies the option argument, if there was one, else the value is NULL.
array $args - an array of command-line arguments
string $shortoptions - specifies the list of allowed short options. See the "Options" section for more information.
array $longoptions - specifies the list of allowed long options. Default is NULL. See the "Options" section for more information.
array - two-element array containing the list of parsed options and the non-option arguments or a PEAR_Error.
Таблица 33-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
NULL | "Console_Getopt: option --$opt is ambiguous" | Two or more long options starts with the same character. | Change the naming of the options. It is also possible that the error is caused by a typing mistake. |
NULL | "Console_Getopt: option --$opt requires an argument" | No parameter for a option was given. | Normally this is a user mistake. If the parameter is optional, you have to markup the parameter as optional in the option definitions. |
NULL | "Console_Getopt: option --$opt doesn't allow an argument" | A parameter for a option was given. | Normally this is a user mistake. If the option requires a (optional) parameter, you have to markup it in the options definition. |
NULL | "Console_Getopt: unrecognized option --$opt" | Unknown option. | Normally this is a user mistake. If the option exists, you have to define them in the options definition. |
Reads the $argv PHP array across different PHP configurations. Will take care of the register_globals and register_argc_argv ini directives.
Таблица 33-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
NULL | "Console_Getopt: Could not read cmd args (register_argc_argv=Off?)" | PHP does not provide the command-line arguments for the script. | Check "register_argc_argv" in your php.ini |
Пример 33-1. Using readPHPArgv()
|
Предоставляет пакеты для работы с базами данных.
A unified API for accessing SQL databases
To connect to a database through PEAR::DB, you have to create a valid DSN - data source name. This DSN consists in the following parts:
phptype: Database backend used in PHP (i.e. mysql , odbc etc.) |
dbsyntax: Database used with regards to SQL syntax etc. When using ODBC as the phptype, set this to the DBMS type the ODBC driver is connecting to. Examples: access, db2, mssql, navision, solid, etc. |
protocol: Communication protocol to use ( i.e. tcp, unix etc.) |
hostspec: Host specification (hostname[:port]) |
database: Database to use on the DBMS server |
username: User name for login |
password: Password for login |
proto_opts: Maybe used with protocol |
option: Additional connection options in URI query string format. options get separated by & |
The format of the supplied DSN is in its fullest form:
phptype(dbsyntax)://username:password@protocol+hostspec/database?option=value |
Most variations are allowed:
phptype://username:password@protocol+hostspec:110//usr/db_file.db phptype://username:password@hostspec/database phptype://username:password@hostspec phptype://username@hostspec phptype://hostspec/database phptype://hostspec phptype:///database phptype:///database?option=value&anotheroption=anothervalue phptype(dbsyntax) phptype |
The currently supported database backends are:
dbase -> dBase fbsql -> FrontBase (functional since DB 1.7.0) ibase -> InterBase (functional since DB 1.7.0) ifx -> Informix msql -> Mini SQL (functional since DB 1.7.0) mssql -> Microsoft SQL Server (NOT for Sybase. Compile PHP --with-mssql) mysql -> MySQL (for MySQL <= 4.0) mysqli -> MySQL (for MySQL >= 4.1) (requires PHP 5) (since DB 1.6.3) oci8 -> Oracle 7/8/9 odbc -> ODBC (Open Database Connectivity) pgsql -> PostgreSQL sqlite -> SQLite sybase -> Sybase |
With an up-to-date version of DB, you can use a second DSN format
phptype(syntax)://user:pass@protocol(proto_opts)/database |
If your database, option values, username or password contain characters used to delineate DSN parts, you can escape them via URI hex encodings:
: = %3a / = %2f @ = %40 + = %2b ( = %28 ) = %29 ? = %3f = = %3d & = %26 |
Внимание |
Please note, that some features may be not supported by all database backends. Please refer to the PEAR DB extensions status document located at: /pear/base/dir/DB/doc/STATUS to get a detailed list about what features are supported by which backend. |
Пример 34-1. Connect to database through a socket
|
Пример 34-2. Connect to database on a non standard port
|
Пример 34-3. Connect to SQLite on a Unix machine using options
|
Пример 34-4. Connect to SQLite on a Windows machine using options
|
Пример 34-5. Connect to MySQLi using SSL
|
Пример 34-6. Connecting to MS Access sometimes requires admin as the user name
|
Пример 34-7. Connecting to ODBC with a specific cursor
|
To connect to a database you have to use the function connect(), which requires a valid DSN as the first parameter. This parameter can either be a string or an array. If using an array, the array used gets merged with the default information:
$dsn = array( 'phptype' => false, 'dbsyntax' => false, 'username' => false, 'password' => false, 'protocol' => false, 'hostspec' => false, 'port' => false, 'socket' => false, 'database' => false, ); |
The second parameter is the optional $options array that can contain runtime configuration settings for this package. See setOption() for more information on the available settings.
In case of success you get a new instance of the database class. It is strongly recommened to check this return value with isError().
To disconnect use the method disconnect() from your database class instance.
Пример 34-1. Connect and disconnect
|
Пример 34-2. Connect using an array for the DSN information
When connecting to SQLite using a DSN array, the value of the mode element must be a string:
|
Пример 34-3. Connect to MySQLi via SSL using an array for the DSN information The ssl element of the $options array must be set to TRUE in order for SSL to work. Each of the extra elements in the $dsn array (key through cipher in the example below) are optional.
|
Пример 34-4. Connect to a PostgreSQL database via a socket
|
PEAR DB provides several methods for querying databases. The most direct method is query(). It takes a SQL query string as an argument. There are three possible returns: a new DB_result object for queries that return results (such as SELECT queries), DB_OK for queries that manipulate data (such as INSERT queries) or a DB_Error object on failure.
Пример 34-1. Doing a query
|
query() can be used instead of prepare() and execute(), if you set the $params parameter and your query uses placeholders.
Пример 34-2. Using query in prepare/execute mode with a scalar parameter
|
Пример 34-3. Using query in prepare/execute mode with an array parameter
|
The DB_result object provides two methods for fetching data from rows of a result set: fetchRow() and fetchInto().
fetchRow() returns the row's data. fetchInto() assigns the row's data to a variable you provide and returns DB_OK.
The result pointer gets moved to the next row each time these methods are called. NULL is returned when the end of the result set is reached.
DB_Error is returned if an error is encountered.
Пример 34-1. Fetching a result set
|
The data from the row of a query result can be placed into one of three constructs: an ordered array (with column numbers as keys), an associative array (with column names as keys) or an object (with column names as properties).
DB_FETCHMODE_ORDERED (default)
Array ( [0] => 28 [1] => hi ) |
DB_FETCHMODE_ASSOC
Array ( [a] => 28 [b] => hi ) |
DB_FETCHMODE_OBJECT
stdClass Object ( [a] => 28 [b] => hi ) |
NOTE: When a query contains the same column name more than once (such as when joining tables which have duplicate column names) and the fetch mode is DB_FETCHMODE_ASSOC or DB_FETCHMODE_OBJECT, the data from the last column with a given name will be the one returned. There are two immediate options to work around this issue:
Use aliases in your query, for example People.Name AS PersonName |
Change the fetch mode to DB_FETCHMODE_ORDERED |
TIP: If you are running into this issue, it likely indicates poor planning of the database schema. Either data is needlessly being duplicated or the same names are being used for different kinds of data.
You can set the fetch mode each time you call a fetch method and/or you can set the default fetch mode for the whole DB instance by using the setFetchMode() method.
Пример 34-2. Determining fetch mode per call
|
Пример 34-3. Changing default fetch mode
|
The PEAR DB fetch system also supports an extra parameter to the fetch statement. So you can fetch rows from a result by number. This is especially helpful if you only want to show sets of an entire result (for example in building paginated HTML lists), fetch rows in an special order, etc.
Пример 34-4. Fetching by number
|
The DB_common object provides several methods that make data retrieval easy by combining the processes of running of the query string you provide, putting the returned information into a PHP data structure and freeing the results. These methods include getOne(), getRow(), getCol(), getAssoc() and getAll().
Once you finish using a result set, if your script continues for a while, it's a good idea to save memory by freeing the result set via Use free().
Пример 34-5. Freeing
|
With DB there are four ways to retrieve useful information about the query result sets themselves:
Пример 34-6. numRows() tells how many rows are in a SELECT query result
|
Пример 34-7. numCols() tells how many columns are in a SELECT query result
|
Пример 34-8. affectedRows() tells how many rows were altered by a data change query (INSERT, UPDATE or DELETE)
|
Пример 34-9. tableInfo() returns an associative array with information about the columns in a SELECT query result
|
prepare() and execute*() give you more power and flexibilty for query execution. Prepare/execute mode is helpful when you have to run the same query several times but with different values in it, such as adding a list of addresses into a database.
Another place prepare/execute is useful is supporting databases which have different SQL syntaxes. Imagine you want to support two databases with different INSERT syntax:
db1: INSERT INTO tbl_name (col1, col2) VALUES (expr1, expr2) db2: INSERT INTO tbl_name SET col1=expr1, col2=expr2 |
$statement['db1']['INSERT_PERSON'] = 'INSERT INTO person (surname, name, age) VALUES (?, ?, ?)'; $statement['db2']['INSERT_PERSON'] = 'INSERT INTO person SET surname=?, name=?, age=?'; |
To use the features above, you have to do two steps. Step one is to prepare the statement and the second is to execute it.
To start out, you need to prepare() a generic SQL statment. Create a generic statment by writing the SQL query as usual:
SELECT surname, name, age FROM person WHERE name = 'name_to_find' AND age < age_limit |
SELECT surname, name, age FROM person WHERE name = ? AND age < ? |
prepare() can handle different types of placeholders (a.k.a. wildcards).
? - (recommended) stands for a scalar value like strings or numbers. The value will be automatically escaped and quoted according to the current DBMS's requirements. |
! - stands for a scalar value and will inserted into the statement "as is". |
& - requires an existing filename, the content of this file will be included into the statment (i.e. for saving binary data of a graphic file in a database) |
Use backslashes to escape placeholder characters if you don't want them to be interpreted as placeholders:
UPDATE foo SET col=? WHERE col='over \& under' |
After preparing the statement, you can execute the query. This means to assign the variables to the prepared statement. To do this, execute() requires two arguments: the statement handle returned by prepare() and a scalar or array with the values to assign.
Пример 34-1. Passing scalars to execute()
|
When a prepared statement has multiple placeholders, you must use an array to pass the values to execute(). The first entry of the array represents the first placeholder, the second the second placeholder, etc. The order is independent of the type of placeholder used.
Пример 34-2. Passing an array to execute()
|
Внимание |
The values passed in $data must be literals. Do not submit SQL functions (for example CURDATE()). SQL functions that should be performed at execution time need to be put in the prepared statement. Similarly, identifiers (i.e. table names and column names) can not be used because the names get validated during the prepare phase. |
DB contains a process for executing several queries at once. So, rather than having to execute them manually, like this:
Пример 34-3. Passing arrays to execute()
|
INSERT INTO numbers VALUES ('1', 'one', 'en') INSERT INTO numbers VALUES ('2', 'two', 'to') INSERT INTO numbers VALUES ('3', 'three', 'tre') INSERT INTO numbers VALUES ('4', 'four', 'fire') |
Пример 34-4. Using executeMultiple() instead of execute()
|
The result is the same. If one of the records failed, the unfinished records will not be executed.
execute*() has three possible returns: a new DB_result object for queries that return results (such as SELECT queries), DB_OK for queries that manipulate data (such as INSERT queries) or a DB_Error object on failure
autoPrepare() and autoExecute() reduce the need to write boring INSERT or UPDATE SQL queries which are difficult to maintain when you add a field for instance.
Imagine you have a 'user' table with 3 fields (id, name and country). You have to write sql queries like:
INSERT INTO table (id, name, country) VALUES (?, ?, ?) UPDATE table SET id=?, name=?, country=? WHERE ... |
With autoPrepare(), you don't have to write your insert or update queries. For example:
<?php // Once you have a valid DB object named $db... $table_name = 'user'; $table_fields = array('id', 'name', 'country'); $sth = $db->autoPrepare($table_name, $table_fields, DB_AUTOQUERY_INSERT); if (PEAR::isError($sth)) { die($sth->getMessage()); } ?> |
INSERT INTO user (id, name, country) VALUES (?, ?, ?) |
To add records, you have to use execute() or executeMultiple() like:
<?php // ... contining from the example above... $table_values = array(1, 'Fabien', 'France'); $res =& $db->execute($sth, $table_values); if (PEAR::isError($res)) { die($res->getMessage()); } ?> |
<?php // Once you have a valid DB object named $db... $table_name = 'user'; $table_fields = array('name', 'country'); $table_values = array('Bob', 'USA'); $sth = $db->autoPrepare($table_name, $table_fields, DB_AUTOQUERY_UPDATE, 'id = 1'); if (PEAR::isError($sth)) { die($sth->getMessage()); } $res =& $db->execute($sth, $table_values); if (PEAR::isError($res)) { die($res->getMessage()); } ?> |
UPDATE user SET name=?, country=? WHERE id=1 |
Be careful, if you don't specify any WHERE clause, all the records of the table will be updated.
Using autoExecute() is the easiest way to do insert or update queries. It is a mix of autoPrepare() and execute().
You only need an associative array (key => value) where keys are fields names and values are corresponding values of these fields. For instance:
<?php // Once you have a valid DB object named $db... $table_name = 'user'; $fields_values = array( 'id' => 1, 'name' => 'Fabien', 'country' => 'France' ); $res = $db->autoExecute($table_name, $fields_values, DB_AUTOQUERY_INSERT); if (PEAR::isError($res)) { die($res->getMessage()); } ?> |
INSERT INTO user (id, name, country) VALUES (1, 'Fabien', 'France') |
And it's the same thing for UPDATE queries:
<?php // Once you have a valid DB object named $db... $table_name = 'user'; $fields_values = array( 'name' => 'Fabien', 'country' => 'France' ); $res = $db->autoExecute($table_name, $fields_values, DB_AUTOQUERY_UPDATE, 'id = 1'); if (PEAR::isError($res)) { die($res->getMessage()); } ?> |
UPDATE user SET name='Fabien', country='France' WHERE id = 1 |
Be careful, if you don't specify any WHERE statement, all the records of the table will be updated.
Внимание |
The values passed in $data must be literals. Do not submit SQL functions (for example CURDATE()). SQL functions that should be performed at execution time need to be put in the prepared statement. |
Each database management system (DBMS) has it's own behaviors. For example, some databases capitalize field names in their output, some lowercase them, while others leave them alone. These quirks make it difficult to port your scripts over to another server type. PEAR DB strives to overcome these differences so your program can switch between DBMS's without any changes.
You control which portability modes are enabled by using the portability configuration option. Configuration options are set via connect() and setOption().
The portability modes are bitwised, so they can be combined using | and removed using ^. See the examples section below on how to do this.
DB_PORTABILITY_ALL
turn on all portability features
DB_PORTABILITY_DELETE_COUNT
force reporting the number of rows deleted. Some DBMS's don't count the number of rows deleted when performing simple DELETE FROM tablename queries. This mode tricks such DBMS's into telling the count by adding WHERE 1=1 to the end of DELETE queries.
DB_PORTABILITY_ERRORS
makes certain error messages in certain drivers compatible with those from other DBMS's
Таблица 34-1. Error Code Re-mappings
Driver | Description | Old Constant | New Constant |
---|---|---|---|
mysql, mysqli | unique and primary key constraints | DB_ERROR_ALREADY_EXISTS | DB_ERROR_CONSTRAINT |
mysql, mysqli | not-null constraints | DB_ERROR_CONSTRAINT | DB_ERROR_CONSTRAINT_NOT_NULL |
odbc(access) | MS's ODBC driver mistakenly reports 'no such field' as code 07001, which means 'too few parameters.' When this option is on, that code gets remapped. | DB_ERROR_MISMATCH | DB_ERROR_NOSUCHFIELD |
DB_PORTABILITY_LOWERCASE
convert names of tables and fields to lower case when using get*(), fetch*() and tableInfo()
DB_PORTABILITY_NONE (default)
turn off all portability features
DB_PORTABILITY_NULL_TO_EMPTY
convert null values to empty strings in data output by get*() and fetch*(). Needed because Oracle considers empty strings to be null, while most other DBMS's know the difference between empty and null.
DB_PORTABILITY_NUMROWS
enable hack that makes numRows() work in Oracle
DB_PORTABILITY_RTRIM
right trim the data output by get*() and fetch*()
Some of this functionality used to be handled by the now deprecated optimize option. For backwards compatibility, when this option is set to portability, the following databases get these portability modes turned on:
oci8: DB_PORTABILITY_LOWERCASE and DB_PORTABILITY_DELETE_COUNT
fbsql, mysql, mysqli, sqlite: DB_PORTABILITY_DELETE_COUNT
When the optimize option gets set to performance the portability mode is switched to DB_PORTABILITY_NONE.
Пример 34-1. Turning on all portability options while connecting
|
Пример 34-2. Using setOption() to enable portability for lowercasing and trimming
|
Пример 34-3. Using setOption() to enable all portability options except trimming
|
Sequences are a way of offering unique IDs for data rows. If you do most of your work with e.g. MySQL, think of sequences as another way of doing AUTO_INCREMENT.
It's quite simple, first you request an ID, and then you insert that value in the ID field of the new row you're creating. You can have more than one sequence for all your tables, just be sure that you always use the same sequence for any particular table. To get the value of this unique ID use nextId(), if a sequence doesn't exists, it will be created automatically.
The sequence is automatically incremented each time nextId() is called.
Пример 34-1. Using a sequence
|
Внимание |
When using PEAR DB's sequence methods, we strongly advise using these methods for all procedures, including the creation of the sequences. Do not use PEAR DB's methods to access sequences that were created directly in the DBMS. If you have a compelling reason to ignore this advice, be aware that the $seq_name argument given to all of PEAR DB's sequence methods are modified before DB calls the underlying DBMS. $seq_name is passed through PHP's sprintf() function using the value from the seqname_format option as sprintf()'s format argument. The default seqname_format is %s_seq. So, for example, if you use person_id_sequence as the $seq_name, PEAR DB will change that name to person_id_sequence_seq when querying the DBMS about creating/accessing/updating the sequence. The seqname_format can be modified when connect()'ing or via setOption(). |
The main DB class is simply a container class with some static methods for creating DB objects.
Data Source Name. String formats are described in the DSN section while array formats are covered in the "Intro - Connect" section.
An optional argument can contain runtime configuration settings for this package. See setOption() for more information on the available settings.
Таблица 34-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
DB_ERROR_NOT_FOUND | not found | The database specific class was not found. | Check the $dsn and make sure to have an complete installation of the DB-package and that you database is supported by DB. |
Checks whether a result code from a DB method is a DB_Error object or not.
You're generally better off using PEAR::isError() instead of the DB specific isError().
Пример 34-1. Using isError()
|
DB_common is an interface class; that provides all methods to query a specific database. An instance of a database specific class will be returned by the connect() method.
Number of rows affected by a data manipulation query (for example INSERT, UPDATE or DELETE). Returns 0 for SELECT queries.
Таблица 34-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
DB_ERROR_NOT_CAPABLE | DB backend not capable | Function is not supported by the database backend | Switch to another database system, if you really need this feature. |
Пример 34-1. Using affectedRows()
|
Таблица 34-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
every other error code | Database specific error | Check the database related section of PHP-Manual to detect the reason for this error. |
Эта функция не должна вызываться статически.
When using MySQL as your DBMS, transactions can only be used when the tables in question use the InnoDB format.
Пример 34-1. Using autocommit()
|
Automatically prepares and executes INSERT or UPDATE queries.
This method builds a SQL statement using autoPrepare() and then executes the statement using execute() with it.
name of the table
assoc (key => value), keys are fields names, values are values of these fields
Values are automatically escaped and quoted according to the current DBMS's requirements.
type of query to make (DB_AUTOQUERY_INSERT or DB_AUTOQUERY_UPDATE)
a string to be used in the WHERE clause. This is only used when $mode is DB_AUTOQUERY_UPDATE. The string is put directly into the query, so you must escape and quote literals according to the DBMS's standards.
Таблица 34-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
DB_ERROR_NEED_MORE_DATA | insufficient data supplied | Your associative array, which has to contain fields names and their values, is empty. | Check and correct your fields_values array. |
DB_ERROR_SYNTAX | syntax error | You use an unknown mode. | Available modes are only DB_AUTOQUERY_INSERT for INSERT queries or DB_AUTOQUERY_UPDATE for UPDATE queries. |
DB_ERROR_NODBSELECTED | no database selected | No database was choosen. | Check the DSN in connect(). |
every other error code | Database specific error | Check the database related section of PHP-Manual to detect the reason for this error. |
Эта функция не должна вызываться статически.
Внимание |
The values passed in $data must be literals. Do not submit SQL functions (for example CURDATE()). SQL functions that should be performed at execution time need to be put in the prepared statement. |
Пример 34-1. Using autoExecute() in insert mode
|
Пример 34-2. Using autoExecute() in update mode
|
"Intro - Prepare & Execute", "Intro - autoPrepare & autoExecute", prepare(), execute(), executeMultiple(), autoPrepare()
Automatically builds an INSERT or UPDATE SQL statement so it can later be used by execute() or executeMultiple().
name of the table
ordered array containing the fields names
Be aware that these fields are assigned ? placeholders, therefore the data you pass to them in the execute() will be automatically escaped and quoted according to the current DBMS's requirements.
type of query to make (DB_AUTOQUERY_INSERT or DB_AUTOQUERY_UPDATE)
a string to be used in the WHERE clause. This is only used when $mode is DB_AUTOQUERY_UPDATE. The string is put directly into the query, so you must escape and quote literals according to the DBMS's standards.
Таблица 34-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
DB_ERROR_NEED_MORE_DATA | insufficient data supplied | The ordered array, which has to contain fields names, is empty. | Check and correct your fields names array. |
DB_ERROR_SYNTAX | syntax error | You use an unknown mode. | Available modes are only DB_AUTOQUERY_INSERT for INSERT queries or DB_AUTOQUERY_UPDATE for UPDATE queries. |
DB_ERROR_NODBSELECTED | no database selected | No database was chosen. | Check the DSN in connect(). |
every other error code | Database specific error | Check the database related section of PHP-Manual to detect the reason for this error. |
Пример 34-1. Using autoPrepare() in insert mode
|
Пример 34-2. Using autoPrepare() in update mode
|
"Intro - Prepare & Execute", "Intro - autoPrepare & autoExecute", prepare(), execute(), executeMultiple(), autoExecute()
Таблица 34-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
every other error code | Database specific error | Check the database related section of PHP-Manual to detect the reason for this error. |
Эта функция не должна вызываться статически.
When using MySQL as your DBMS, transactions can only be used when the tables in question use the InnoDB format.
Пример 34-1. Using commit()
|
name of the new sequence to create
To avoid problems with various database systems, sequence names should start with a letter and only contain letters, numbers and the underscore character.
Таблица 34-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
every error code | Database specific error | Check the name of the sequence. If correct, probably a bug in the sequence implementation |
Эта функция не должна вызываться статически.
Внимание |
When using PEAR DB's sequence methods, we strongly advise using these methods for all procedures, including the creation of the sequences. Do not use PEAR DB's methods to access sequences that were created directly in the DBMS. See the warning on the "Intro - Sequences" page complete information. |
Пример 34-1. Using createSequence()
|
Пример 34-1. Using disconnect()
|
Таблица 34-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
every error code | Database specific error | Check the name of the sequence. If correct, probably a bug in the sequence implementation. |
Эта функция не должна вызываться статически.
Внимание |
When using PEAR DB's sequence methods, we strongly advise using these methods for all procedures, including the creation of the sequences. Do not use PEAR DB's methods to access sequences that were created directly in the DBMS. See the warning on the "Intro - Sequences" page complete information. |
Пример 34-1. Using dropSequence()
|
Пример 34-1. Using escapeSimple()
|
Merges the SQL statment you submitted to prepare() with the information in $data and then sends the query to the database.
query handle from prepare()
array, string or numeric data to be added to the prepared statement. Quantity of items passed must match quantity of placeholders in the prepared statement: meaning 1 placeholder for non-array parameters or 1 placeholder per array element.
mixed - a new DB_result object for queries that return results (such as SELECT queries), DB_OK for queries that manipulate data (such as INSERT queries) or a DB_Error object on failure
Таблица 34-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
DB_ERROR_INVALID | invalid | SQL statment handle is not valid. | Check correct processing of the SQL statment with prepare(). Note that execute() requires a handle to the statement returned by prepare(), not the statment itself. |
DB_ERROR_MISMATCH | mismatch | Quantity of parameters didn't match quantity of placeholders in the prepared statment. | Check that the number of placeholders in the prepare() statement passed to $query equals the count of entries passed to $params. |
DB_ERROR_NODBSELECTED | no database selected | No database was choosen. | Check the DSN in connect(). |
every other error code | Database specific error | Check the database related section of PHP-Manual to detect the reason for this error. In the most cases a misformed SQL statment. Ie. using LIMIT in a SQL-Statment for an Oracle database. |
Эта функция не должна вызываться статически.
Внимание |
The values passed in $data must be literals. Do not submit SQL functions (for example CURDATE()). SQL functions that should be performed at execution time need to be put in the prepared statement. |
Пример 34-1. Passing a scalar to execute()
|
Пример 34-2. Passing an array to execute()
|
"Intro - Prepare & Execute", "Intro - autoPrepare & autoExecute", prepare(), executeMultiple()
Automatically passes the information in $data (a multi-dimensional array) to execute(), which then runs the SQL statment you submitted to prepare().
query handle from prepare()
a numeric array containing the data to insert into the query
Таблица 34-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
DB_ERROR_INVALID | invalid | SQL statment handle is not valid. | Check correct processing of the SQL statment with prepare(). Note that executeMultiple() requires a handle to the statement returned by prepare(), not the statment itself. |
DB_ERROR_MISMATCH | mismatch | Quantity of parameters didn't match quantity of placeholders in the prepared statment. | Check that the number of placeholders in the prepare() statement passed to $query equals the count of entries passed to $params. |
DB_ERROR_NODBSELECTED | no database selected | No database was choosen. | Check the DSN in connect(). |
every other error code | Database specific error | Check the database related section of PHP-Manual to detect the reason for this error. In the most cases a misformed SQL statment. Ie. using LIMIT in a SQL-Statment for an Oracle database. |
Эта функция не должна вызываться статически.
Внимание |
If an error occurs during execution, the function will be stopped. Possible remaining data will be unprocessed. |
Внимание |
The values passed in $data must be literals. Do not submit SQL functions (for example CURDATE()). SQL functions that should be performed at execution time need to be put in the prepared statement. |
Пример 34-1. Using executeMultiple()
|
"Intro - Prepare & Execute", "Intro - autoPrepare & autoExecute", prepare(), execute(), autoPrepare(), autoExecute()
Removes the memory occupied by the internal notations that keep track of prepared SQL statements. Does not delete the DB_result object itself.
statement resource identifier returned from prepare()
should the PHP resource be freed too? Use false if you need to get data from the result set later.
Parameter available since Release 1.7.0.
Пример 34-1. Using freePrepared()
|
Runs the query provided and puts the entire result set into a nested array then frees the result set.
the SQL query or the statement to prepare
array to be used in execution of the statement. Quantity of array elements must match quantity of placeholders in query.
If supplied, prepare()/ execute() is used.
Внимание |
This method does not allow scalars to be used for this argument. |
the fetch mode to use. The default is DB_FETCHMODE_DEFAULT, which tells this method to use DB's current fetch mode. The current fetch mode can be changed using setFetchMode(). Potential values include:
DB_FETCHMODE_ORDERED
DB_FETCHMODE_ASSOC
DB_FETCHMODE_OBJECT
DB_FETCHMODE_ORDERED | DB_FETCHMODE_FLIPPED
DB_FETCHMODE_ASSOC | DB_FETCHMODE_FLIPPED
Таблица 34-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
DB_ERROR_INVALID | invalid | SQL statment for preparing is not valid. | See the prepare() documentation, if you want to use a SQL statemt using placeholders. |
DB_ERROR_MISMATCH | mismatch | Quantity of parameters didn't match quantity of placeholders in the prepared statment. | Check that the number of placeholders in the prepare() statement passed to $query equals the count of entries passed to $params. |
DB_ERROR_NODBSELECTED | no database selected | No database was choosen. | Check the DSN in connect(). |
every other error code | Database specific error | Check the database related section of PHP-Manual to detect the reason for this error. In the most cases a misformed SQL statment. Ie. using LIMIT in a SQL-Statment for an Oracle database. |
Пример 34-1. Using getAll() to return an associative array by setting the default fetch mode first
Output:
|
Пример 34-2. Using getAll() to return an ordered array
Output:
|
Пример 34-3. Using getAll() to return a flipped ordered array
Output:
|
Пример 34-4. Using getAll() to return an associative array
Output:
|
Пример 34-5. Using getAll() to return a flipped associative array
Output:
|
Пример 34-6. Using getAll() to return an array of objects
Output:
|
Пример 34-7. Using getAll() in prepare/execute mode to return an associative array
Output:
|
setFetchMode(), getOne(), getRow(), getCol(), getAssoc(), query(), "Intro - Prepare & Execute"
Runs the query provided and puts the entire result set into an associative array then frees the result set.
If the result set contains more than two columns, the value will be an array of the values from column 2 to n. If the result set contains only two columns, the returned value will be a scalar with the value of the second column (unless forced to an array with the $force_array parameter).
the SQL query or the statement to prepare
used only if the query returns exactly two columns. If TRUE, the values of the returned array will be one-element arrays instead of scalars.
array, string or numeric data to be added to the prepared statement. Quantity of items passed must match quantity of placeholders in the prepared statement: meaning 1 placeholder for non-array parameters or 1 placeholder per array element.
If supplied, prepare()/ execute() is used.
the fetch mode to use. The default is DB_FETCHMODE_DEFAULT, which tells this method to use DB's current fetch mode. DB's current default fetch mode can be changed using setFetchMode(). Potential values include:
DB_FETCHMODE_ORDERED
DB_FETCHMODE_ASSOC
DB_FETCHMODE_OBJECT
if TRUE, the values of the returned array is wrapped in another array. If the same key value (in the first column) repeats itself, the values will be appended to this array instead of overwriting the existing values.
array - associative array with the query results or a DB_Error object on failure
Таблица 34-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
DB_ERROR_INVALID | invalid | SQL statment for preparing is not valid. | See the prepare() documentation, if you want to use a SQL statemt using placeholders. |
DB_ERROR_MISMATCH | mismatch | Quantity of parameters didn't match quantity of placeholders in the prepared statment. | Check that the number of placeholders in the prepare() statement passed to $query equals the count of entries passed to $params. |
DB_ERROR_NODBSELECTED | no database selected | No database was choosen. | Check the DSN in connect(). |
DB_ERROR_TRUNCATED | truncated | The result set contains fewer then two columns | Check the SQL query or choose another get*() function |
every other error code | Database specific error | Check the database related section of PHP-Manual to detect the reason for this error. In the most cases a misformed SQL statment. Ie. using LIMIT in a SQL-Statment for an Oracle database. |
All of the examples use the following data set:
INSERT INTO foo VALUES ('Juan', 5, '1991-01-11 21:31:41'); INSERT INTO foo VALUES ('Kyu', 10, '1992-02-12 22:32:42'); INSERT INTO foo VALUES ('Kyu', 15, '1993-03-13 23:33:43'); |
When using getAssoc() for results which have two columns and $force_array = FALSE (the default) changing $fetchmode has no impact on the format of the resulting array.
Пример 34-1. Using getAssoc() in default mode
Output:
|
Пример 34-2. Using getAssoc() with $group = TRUE
Output:
|
Пример 34-3. Using getAssoc() with $force_array = TRUE and $fetchmode = DB_FETCHMODE_ORDERED
Output:
|
Пример 34-4. Using getAssoc() with $force_array = TRUE and $fetchmode = DB_FETCHMODE_ASSOC
Output:
|
Пример 34-5. Using getAssoc() with $force_array = TRUE and $fetchmode = DB_FETCHMODE_OBJECT
Output:
|
Пример 34-6. Using getAssoc() with $force_array = TRUE, $fetchmode = DB_FETCHMODE_ORDERED and $group = TRUE
Output:
|
Пример 34-7. Using getAssoc() with $force_array = TRUE, $fetchmode = DB_FETCHMODE_ASSOC and $group = TRUE
Output:
|
Пример 34-8. Using getAssoc() with $force_array = TRUE, $fetchmode = DB_FETCHMODE_OBJECT and $group = TRUE
Output:
|
Пример 34-9. Using getAssoc() with $fetchmode = DB_FETCHMODE_ORDERED
Output:
|
Пример 34-10. Using getAssoc() with $fetchmode = DB_FETCHMODE_ASSOC
Output:
|
Пример 34-11. Using getAssoc() with $fetchmode = DB_FETCHMODE_OBJECT
Output:
|
Пример 34-12. Using getAssoc() with $fetchmode = DB_FETCHMODE_ORDERED and $group = TRUE
Output:
|
Пример 34-13. Using getAssoc() with $fetchmode = DB_FETCHMODE_ASSOC and $group = TRUE
Output:
|
Пример 34-14. Using getAssoc() with $fetchmode = DB_FETCHMODE_OBJECT and $group = TRUE
Output:
|
Пример 34-15. Using getAssoc() with one placeholder
|
Пример 34-16. Using getAssoc() with two placeholders
|
setFetchMode(), getOne(), getRow(), getCol(), getAll(), query(), "Intro - Prepare & Execute"
Runs the query provided and puts the first column of data into an array then frees the result set.
the SQL query or the statement to prepare
which column to return (integer [column number, starting at 0] or string [column name])
array, string or numeric data to be added to the prepared statement. Quantity of items passed must match quantity of placeholders in the prepared statement: meaning 1 placeholder for non-array parameters or 1 placeholder per array element.
If supplied, prepare()/ execute() is used.
array - an ordered array containing data from a result set column or a DB_Error object on failure. The array's index starts at 0.
Таблица 34-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
DB_ERROR_INVALID | invalid | SQL statment for preparing is not valid. | See the prepare() documentation, if you want to use a SQL statemt using placeholders. |
DB_ERROR_MISMATCH | mismatch | Quantity of parameters didn't match quantity of placeholders in the prepared statment. | Check that the number of placeholders in the prepare() statement passed to $query equals the count of entries passed to $params. |
DB_ERROR_NOSUCHFIELD | no such field | Invalid column number/name passed to $col | Use a column number or name that exists in the query result. |
DB_ERROR_NODBSELECTED | no database selected | No database was choosen. | Check the DSN in connect(). |
every other error code | Database specific error | Check the database related section of PHP Manual to detect the reason for this error. In most cases a malformed SQL statement is the cause of the error. (Ie. using LIMIT in a SQL-Statment for an Oracle database.) |
Пример 34-1. Using getCol()
Output:
|
Пример 34-2. Using getCol() to retrieve a numerically specified column
Output:
|
Пример 34-3. Using getCol() to retrieve a named column
Output:
|
Пример 34-4. Using getCol() in prepare/execute mode with one placeholder
Output:
|
Пример 34-5. Using getCol() in prepare/execute mode with two placeholders
Output:
|
type of requested info, valid values for $type are database dependent, ie: tables, databases, users, view, functions
array - an ordered array containing the requested data or a DB_Error object on failure
Таблица 34-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
DB_ERROR_UNSUPPORTED | not supported | The requested information is not avaible. | Check your user permissions and the database system for support quering the requested information. |
Пример 34-1. Using getListOf()
|
Runs the query provided and returns the data from the first column of the first row then frees the result set.
the SQL query or the statement to prepare
array, string or numeric data to be added to the prepared statement. Quantity of items passed must match quantity of placeholders in the prepared statement: meaning 1 placeholder for non-array parameters or 1 placeholder per array element.
If supplied, prepare()/ execute() is used.
Таблица 34-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
DB_ERROR_INVALID | invalid | SQL statment for preparing is not valid. | See the prepare() documentation, if you want to use a SQL statemt using placeholders. |
DB_ERROR_MISMATCH | mismatch | Quantity of parameters didn't match quantity of placeholders in the prepared statment. | Check that the number of placeholders in the prepare() statement passed to $query equals the count of entries passed to $params. |
DB_ERROR_NODBSELECTED | no database selected | No database was choosen. | Check the DSN in connect(). |
every other error code | Database specific error | Check the database related section of PHP-Manual to detect the reason for this error. In the most cases a misformed SQL statment. Ie. using LIMIT in a SQL-Statment for an Oracle database. |
Пример 34-1. Using getOne()
|
Пример 34-2. Using getOne() with one placeholder
|
Пример 34-3. Using getOne() with two placeholders
|
Таблица 34-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
NULL | unknown option | The given option does not exist | Check $option for typographical errors |
Пример 34-1. Simple getOption() example
|
Runs the query provided and puts the first row of data into an array then frees the result set.
the SQL query or the statement to prepare
array to be used in execution of the statement. Quantity of array elements must match quantity of placeholders in query.
If supplied, prepare()/ execute() is used.
Внимание |
This method does not allow scalars to be used for this argument. |
the fetch mode to use. The default is DB_FETCHMODE_DEFAULT, which tells this method to use DB's current fetch mode. DB's current default fetch mode can be changed using setFetchMode(). Potential values include:
DB_FETCHMODE_ORDERED
DB_FETCHMODE_ASSOC
DB_FETCHMODE_OBJECT
array - the first row's data in an array or a DB_Error object on failure. The array may be ordered or associative depending on $fetchmode. The column index starts at 0 for orderd arrays.
Таблица 34-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
DB_ERROR_INVALID | invalid | SQL statment for preparing is not valid. | See the prepare() documentation, if you want to use a SQL statemt using placeholders. |
DB_ERROR_MISMATCH | mismatch | Quantity of parameters didn't match quantity of placeholders in the prepared statment. | Check that the number of placeholders in the prepare() statement passed to $query equals the count of entries passed to $params. |
DB_ERROR_NODBSELECTED | no database selected | No database was choosen. | Check the DSN in connect(). |
every other error code | Database specific error | Check the database related section of PHP-Manual to detect the reason for this error. In the most cases a misformed SQL statment. Ie. using LIMIT in a SQL-Statment for an Oracle database. |
Пример 34-1. Using getRow() with $fetchmode = DB_FETCHMODE_ORDERED
Output:
|
Пример 34-2. Using getRow() with $fetchmode = DB_FETCHMODE_ASSOC
Output:
|
Пример 34-3. Using getRow() with $fetchmode = DB_FETCHMODE_OBJECT
Output:
|
Пример 34-4. Using getRow() with one placeholder
|
Пример 34-5. Using getRow() with two placeholders
|
setFetchMode(), getOne(), getCol(), getAssoc(), getAll(), query(), "Intro - Prepare & Execute"
Executes a SQL query, but fetches only the the specificed count of rows. It is an emulation of the MySQL LIMIT option.
the SQL query
the row to start to fetch. Note that 0 returns the first row, 1 returns the second row, etc.
the numbers of rows to fetch
array, string or numeric data to be added to the prepared statement. Quantity of items passed must match quantity of placeholders in the prepared statement: meaning 1 placeholder for non-array parameters or 1 placeholder per array element.
mixed - a new DB_result object for queries that return results (such as SELECT queries), DB_OK for queries that manipulate data (such as INSERT queries) or a DB_Error object on failure
Таблица 34-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
DB_ERROR_NODBSELECTED | no database selected | No database was choosen. | Check the DSN in connect(). |
every other error code | Database specific error | Check the database related section of PHP-Manual to detect the reason for this error. In the most cases a misformed SQL statment. Ie. using LIMIT in a SQL-Statment for an Oracle database. |
Эта функция не должна вызываться статически.
Depending on the database you will not really get more speed compared to query(). The advantage of limitQuery() is the deleting of unneeded rows in the resultset, as early as possible. So this can decrease memory usage.
Пример 34-1. Using limitQuery()
|
Returns the next available number from a sequence. The sequence is automatically incremented each time this method is called.
See "Intro - Sequences" for a more complete discusion.
name of the sequence
To avoid problems with various database systems, sequence names should start with a letter and only contain letters, numbers and the underscore character.
When TRUE, the sequence is automatically created if it does not exist yet.
The on demand creation process necessitates the database user specified in the script having the database permissions needed to create a table or sequence. The exact privileges involved depends on the DBMS being used.
Таблица 34-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
DB_ERROR_NOT_CAPABLE | DB backend not capable | Function is not supported by the database backend | Switch to another database system, if you really need this feature. |
DB_ERROR_NOT_LOCKED | not locked | Locking of sequence table fails | Database specific, check documentation of your database, |
DB_ERROR_NOSUCHTABLE | no such table | Sequence table was not found | Try to create a new sequence or if you are sure, a sequence was already create, check database integrity |
Эта функция не должна вызываться статически.
Внимание |
When using PEAR DB's sequence methods, we strongly advise using these methods for all procedures, including the creation of the sequences. Do not use PEAR DB's methods to access sequences that were created directly in the DBMS. See the warning on the "Intro - Sequences" page complete information. |
Пример 34-1. Using nextId()
|
Informs the DB driver that the next query that is called will manipulate data within the database and will not return a result set, irrespective of the usual detection performed within DB.
When TRUE, the next query will always be treated as not returning a result set. When FALSE, the normal behaviour will be used, which will result in DB attempting to automatically detect whether the query will return a result set or not.
Пример 34-1. Using prepare()
|
"Intro - Prepare & Execute", "Intro - autoPrepare & autoExecute", execute(), executeMultiple()
the feature to check
Таблица 34-1. Possible values are:
$feature value | Meaning |
---|---|
prepare | The database does a pre-check of the SQL statment |
pconnect | The database supports persistent connections |
transactions | The database supports transactions |
limit | The database supports LIMITed SELECT statments |
Эта функция не должна вызываться статически.
Внимание |
The provided information are only hints. Check the documentation of your database system for the real supported features. I.e. MySQL supports transactions, but not for every table type. |
Пример 34-1. Using provides()
|
Runs a query
Can be used instead of prepare() and execute(), if you set the $params parameter and your query uses placeholders. See "Intro - Prepare & Execute" for more information on this mode.
the SQL query or the statement to prepare
array, string or numeric data to be added to the prepared statement. Quantity of items passed must match quantity of placeholders in the prepared statement: meaning 1 placeholder for non-array parameters or 1 placeholder per array element.
mixed - a new DB_result object for queries that return results (such as SELECT queries), DB_OK for queries that manipulate data (such as INSERT queries) or a DB_Error object on failure
Таблица 34-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
DB_ERROR_INVALID | invalid | SQL statment for preparing is not valid. | See the prepare() documentation, if you want to use a SQL statement using placeholders. |
DB_ERROR_MISMATCH | mismatch | Quantity of parameters didn't match quantity of placeholders in the prepared statment. | Check that the number of placeholders in the prepare() statement passed to $query equals the count of entries passed to $params. |
DB_ERROR_NODBSELECTED | no database selected | No database was chosen. | Check the DSN in connect(). |
every other error code | Database specific error | Check the database related section of the PHP-Manual to detect the reason for this error. In the most cases a misformed SQL statement. I.e. using LIMIT in a SQL-Statement for an Oracle database. |
Quotes a string database-dependent, so it can be safely used in a query
This method has been deprecated. Use quoteSmart() or escapeSimple() instead.
Эта функция не должна вызываться статически.
Внимание |
Эта функция объявлена как deprecated. Это означает, что в будущих версиях пакета она может больше не поддерживаться. |
Deprecated in release 1.6.0.
Format input so it can be safely used as a delimited identifier in a query. Identifiers are objects such as table or column names.
The format returned depends on the database type being used.
Delimited identifiers are known to generally work correctly under the following drivers:
mssql |
mysql |
mysqli |
oci8 |
odbc(access) |
odbc(db2) |
pgsql |
sqlite |
sybase |
InterBase doesn't seem to be able to use delimited identifiers via PHP 4. They work fine under PHP 5.
Эта функция не должна вызываться статически.
Function available since: Release 1.6.0
Внимание | |||
Just because you CAN use delimited identifiers doesn't mean you SHOULD use them. In general, they end up causing way more problems than they solve. Portability is broken by using the following characters inside delimited identifiers:
|
Пример 34-1. Using quoteIdentifier()
|
Format input so it can be safely used as a literal in a query. Literals are values such as strings or numbers which get utilized in places like WHERE, SET and VALUES clauses of SQL statements.
The format returned depends on the PHP data type of input and the database type being used.
mixed - the formatted data
The format of the results depends on the input's PHP type:
input -> returns
NULL -> the string NULL
integer or float -> the unquoted number
boolean -> output depends on the driver in use
Most drivers return integers: 1 if true or 0 if false. Some return strings: TRUE if true or FALSE if false. Finally one returns strings: T if true or F if false. Here is a list of each DBMS, the values returned and the suggested column type:
dbase -> T/F (Logical)
fbase -> TRUE/FALSE (BOOLEAN)
ibase -> 1/0 (SMALLINT) [1]
ifx -> 1/0 (SMALLINT) [1]
msql -> 1/0 (INTEGER)
mssql -> 1/0 (TINYINT)
mysql -> 1/0 (TINYINT(1))
mysqli -> 1/0 (TINYINT(1))
oci8 -> 1/0 (NUMBER(1))
odbc -> 1/0 (SMALLINT) [1]
pgsql -> TRUE/FALSE (BOOLEAN)
sqlite -> 1/0 (INTEGER)
sybase -> 1/0 (TINYINT)
[1] Accommodate the lowest common denominator because not all versions of have BOOLEAN.
other (including strings and numeric strings) -> a string which has been escaped in a DBMS specific way (using escapeSimple()) and then surrounded by single quotes
Пример 34-1. Using quoteSmart()
|
Таблица 34-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
every other error code | Database specific error | Check the database related section of PHP-Manual to detect the reason for this error. |
Эта функция не должна вызываться статически.
When using MySQL as your DBMS, transactions can only be used when the tables in question use the InnoDB format.
Пример 34-1. Using rollback()
|
DB_FETCHMODE_ORDERED, DB_FETCHMODE_ASSOC or DB_FETCHMODE_OBJECT.
See the Examples section, below, for more information.
This parameter is for use when $fetchmode is set to DB_FETCHMODE_OBJECT.
You can set this parameter to DB_row, which then causes the resulting data to populate a new instance of a DB_row object.
Таблица 34-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
NULL | invalid fetchmode mode | The given fetch mode does not exists or is not implement in your DB version. | Check writing of the argument and your used version of DB. |
Пример 34-1. DB_FETCHMODE_ORDERED (default) Causes ordered arrays to be returned. The order is taken from the select statement.
Output:
|
Пример 34-2. DB_FETCHMODE_ASSOC Makes associative arrays, with the column names as the array keys.
Output:
|
Пример 34-3. DB_FETCHMODE_OBJECT Returns objects with column names as properties.
Output:
|
Пример 34-4. DB_FETCHMODE_OBJECT and DB_row If setFetchMode()'s optional $object_class parameter is set to DB_row, DB_row objects are returned.
Output:
|
Пример 34-5. DB_FETCHMODE_OBJECT with your own object in PHP 4
Output:
|
Пример 34-6. DB_FETCHMODE_OBJECT with your own object in PHP 5
Output:
|
name of the option to set
value to set the option to
Таблица 34-1.
Option | Data Type | Default Value | Description | |
---|---|---|---|---|
autofree | boolean | FALSE | should results be freed automatically when there are no more rows? | |
debug | integer | 0 | debug level | |
persistent | boolean | FALSE | should the connection be persistent? | |
portability | integer | DB_PORTABILITY_NONE | portability mode constant. These constants are bitwised, so they can be combined using | and removed using ^. See the examples below and the "Intro - Portability" for more information. | |
seqname_format | string | %s_seq | the sprintf() format string used on sequence names. This format is applied to sequence names passed to createSequence(), nextID() and dropSequence(). | |
ssl | boolean | FALSE | use ssl to connect? |
Таблица 34-2. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
NULL | unknown option | The given option does not exist | Check $option for typographical errors |
Пример 34-1. Simple setOption() example
|
Пример 34-2. Portability for lowercasing and trimming
|
Пример 34-3. All portability options except trimming
|
DB_result object from a query or a string containing the name of a table
If the name of the table needs to be delimited (ie: the name is a reserved word or has spaces in it), use the quoteIdentifier() method on the table name when passing it.
This can also be a query result resource identifier, but doing so is deprecated.
one of the tableInfo mode constants
array - an associative array of the table's information or a DB_Error object on failure
The array's contents depends on the $mode parameter.
The names of tables and columns will be lowercased if the DB_PORTABILITY_LOWERCASE portability mode is enabled.
The flags element contains a space separated list of extra information about the column. If the DBMS is able to report a column's default value, the value is passed through rawurlencode() to avoid problems caused by potential spaces in the value.
Most DBMS's only provide the table and flags elements if $result is a table name. Only fbsql and mysql provide full information from queries.
The type element contains the type returned by the DBMS. It varies from DBMS to DBMS.
This section describes the format of the returned array and how it varies depending on which $mode was used when the function was called.
The sample output below is based on this query:
SELECT tblFoo.fldID, tblFoo.fldPhone, tblBar.fldId FROM tblFoo JOIN tblBar ON tblFoo.fldId = tblBar.fldId; |
[0] => Array ( [table] => tblFoo [name] => fldId [type] => int [len] => 11 [flags] => primary_key not_null ) [1] => Array ( [table] => tblFoo [name] => fldPhone [type] => string [len] => 20 [flags] => ) [2] => Array ( [table] => tblBar [name] => fldId [type] => int [len] => 11 [flags] => primary_key not_null ) |
In addition to the information found in the default output, a notation of the number of columns is provided by the num_fields element while the order element provides an array with the column names as the keys and their location index number (corresponding to the keys in the default output) as the values.
If a result set has identical field names, the last one is used.
[num_fields] => 3 [order] => Array ( [fldId] => 2 [fldTrans] => 1 ) |
Similar to DB_TABLEINFO_ORDER but adds more dimensions to the array in which the table names are keys and the field names are sub-keys. This is helpful for queries that join tables which have identical field names.
[num_fields] => 3 [ordertable] => Array ( [tblFoo] => Array ( [fldId] => 0 [fldPhone] => 1 ) [tblBar] => Array ( [fldId] => 2 ) ) |
Contains the information from both DB_TABLEINFO_ORDER and DB_TABLEINFO_ORDERTABLE
The tableInfo mode constants are bitwised, so they can be combined using |.
Таблица 34-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
DB_ERROR_NOT_CAPABLE | DB backend not capable | Driver doesn't support this feature. | Switch to another database system, if you really need this feature. |
DB_ERROR_NEED_MORE_DATA | insufficient data supplied | The data passed in the $result parameter was not a valid table name or result identifier. | Check the table name for typographical errors or that the query ran correctly. |
DB_ERROR_NODBSELECTED | no database selected | No database was chosen. | Check the DSN in connect(). |
can't distinguish duplicate field names | The query result has multiple columns with the same name. PHP's Informix extension deals with columns having the same names by overwriting the prior columns information. Therefore, tableInfo() is unable to properly represent these result sets. | Use aliases for columns that have the same names. |
Эта функция не должна вызываться статически.
tableInfo() is not portable because not all drivers have this method, many DBMS's are unable to determine table names from query results and the metadata returned by each database system varies dramatically.
Пример 34-1. Finding information about a table
|
Пример 34-2. Finding information about a query result
|
DB_result contains the result set of a SQL query. An instance of this class will be returned by a number of DB_common methods.
Places a row of data from a result set into a variable you provide then moves the result pointer to the next row. The data can be formatted as an array or an object.
reference to a variable to contain the row
the fetch mode to use. The default is DB_FETCHMODE_DEFAULT, which tells this method to use DB's current fetch mode. DB's current default fetch mode can be changed using setFetchMode(). Potential values include:
DB_FETCHMODE_ORDERED
DB_FETCHMODE_ASSOC
DB_FETCHMODE_OBJECT
the row number to fetch. Note that 0 returns the first row, 1 returns the second row, etc.
integer - DB_OK if a row is processed, NULL when the end of the result set is reached or a DB_Error object on failure
Пример 34-1. Using fetchInto()
|
Returns a row of data from a result set then moves the result pointer to the next row. The data can be formatted as an array or an object.
the fetch mode to use. The default is DB_FETCHMODE_DEFAULT, which tells this method to use DB's current fetch mode. DB's current default fetch mode can be changed using setFetchMode(). Potential values include:
DB_FETCHMODE_ORDERED
DB_FETCHMODE_ASSOC
DB_FETCHMODE_OBJECT
the row number to fetch
mixed - an array or object containing the row's data, NULL when the end of the result set is reached or a DB_Error object on failure
Пример 34-1. Using fetchRow()
|
Deletes the result set and frees the memory occupied by the result set. Does not delete the DB_result object itself.
Пример 34-1. Using free()
|
Some database backends supports executing more then one query at the same time. With nextResult() you can go through the result sets.
Внимание |
This function has nothing to do with with executeMultiple(). |
boolean - TRUE if DB_result contains the next result set, FALSE if there is no further result set to fetch
Пример 34-1. Using numCols()
|
Get the number of rows in a result set.
Внимание |
For ibase, ifx and oci8, this method only works if the DB_PORTABILITY_NUMROWS portability option is enabled. In addition, for ibase and ifx, PEAR DB must be at version 1.7.0 or greater. Does not work for Microsoft Access. |
Таблица 34-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
DB_ERROR_NOT_CAPABLE | DB backend not capable | Driver doesn't support this feature. | Either switch to another database system or enable the DB_PORTABILITY_NUMROWS portability option. |
Пример 34-1. Using numRows()
|
In case of failure, most of the DB functions return a DB_Error object which contains information about the error. DB_Error offers the same functions as PEAR_Error.
The text messages returned by DB_Error::getMessage() are consistent between each DBMS.
The error code integers returned by DB_Error::getCode() are also consistent between each DBMS. The integers returned are based on the DB_ERROR_* constants defined in DB.php.
DB_Error::getDebugInfo() and DB_Error::getUserInfo() return complete native DBMS error reports.
Пример 34-1. Trapping errors and determining what happened
|
SQL Builder and Data Modeling Layer
This chapter describes how to use the DB_DataObject SQL Builder and Data Modeling layer
Внимание |
Zend Optimizer: due to a bug in the optimizer, you will have to either reduce the optimization level, or define the constant DB_DATAOBJECT_NO_OVERLOAD = 0 otherwise PHP may segfault Pass by Reference, due to a unfixable bug in PHP4, you can not use overload with pass-by-reference arguments (It works OK in PHP5), If you need pass-by-reference, define the constant DB_DATAOBJECT_NO_OVERLOAD = 0 |
DB_DataObject is a SQL Builder and Data Modeling Layer built on top of PEAR::DB. Its main purpose is to
Build SQL and execute statements based on the objects variables.
Group source code around the data that they relate to.
Provide a simple consistent API to access and manipulate that data.
So what does that mean in english? Well, if you look around at some of the better written PHP applications and frameworks out there, you will notice a common approach to using classes to wrap access to database tables or groups. The prime example of this is the person object, which would frequently look something like this.
Пример 34-1. A Classic Data Object or Container
|
The key benifit of this approach is that you are grouping similar actions on a single table in one place, and are more likely to spot duplicated code (eg. two methods that do similar things). You will also notice the global $db variable used here - the fact is that most of the time you will use a common database connection for all your classes, so how should this be dealt with?
The next step on this road is to use the objects variables as a storage mechanism.
Пример 34-2. A Classic Data Object or Container
|
As you can see, the current row of data is now stored in the Data Container, and additional methods can be added to manipulate the data in the object or even call other related objects (eg. tables relationships in databases)
As a next step, why not utilize the member variables to perform searches or gets on the database.
Пример 34-3. A Classic Data Object or Container
|
As you can see, by assigning values to the object before the find method is called, you can set conditions for the query. DB_DataObjects behaves in a similar way to this, however, you can also add more conditions with the whereAdd() method, or restrict the selection using the selectAdd() method.
Obviously you can carry on down this road and create lots of little containers for each table in your database, and all the code will nicely relate to each table. However, you can see from the examples above that all classes are likely to end up with a common set of methods.
to fetch data, like get, find, fetch
to update, insert and delete from the data store
to automate fetching related objects
A common simple configuration method (for setting database connections)
A fast and simple store for database descriptions, so primary keys can be used to locate data quickly
a debugger that enables you to see what exactly it is doing.
basic data validation - so the strings and integers can be checked.
Posibility to build complex joins or get related data by secondary calls (links) .
Ability to create and update your Table specific classes with the current database table variables (see autobuilding)
Simple to integrate with other packages, with setFrom() and toArray() methods
So what do my classes look like?
Пример 34-4. At last some real DataObject Code..
|
The above example illustrates the components of the DB_DataObject, by setting the options, all the core objects will be able to auto load the data definitions from a generated ini file, and know how to access the database. (multiple databases are supported - see section on configuration)
The class definition illustrates how you only need to define the data specific code in your class, ignoring all the common methods, along with showing one of the methods for retrieveing multiple rows of data.
The later half illustrates how to query and get the result for a single row. The $person->get() would connect to the database, perform the query, fetch the result and assign the objects variables to the data returned from the query.
Пример 34-5. In the above example, this query would be performed.
|
Пример 34-6. To make a change to the Database you would just change the value of the objects variables and call the update method.
|
As a general rule of thumb method names are usually the same as the SQL statement they relate to.
DB_DataObject needs to be configured before using it and auto generating classes and definitions. The easiest way to configure DB_DataObject is to use ini files (although you may also like to consider the PEAR::Config class, or your own configuration system)
Пример 34-1. This is a typical configuration file for DB_DataObject
|
To use this ini file with DB_DataObject, (and possibly any other classes that use options like this)
Пример 34-2. Setting the default options
|
This is the default DSN to connect to your database
The directory where the DB_DataObject database schema file is store.
DB_DataObject stores the description of the database (Tables and Columns) in an .ini file, in this directory. This information is used to determine if the column is a string and needs quotes, or should be a number (and is checked) at SQL building time. It is quite common to store the schema in the same directory as your DataObject Classes.
The Path absolute, or relative to your default include path(s), where your extended classes can be found.
This is used by the staticGet() method and the getLinks() method to auto load classes,
All the generated Classes are named {class_prefix}ucfirst($table_name). Use this to alter the prefixed name, this is used by the staticGet() and getLinks() methods
To Hard code the key (autoincrement/nextval() for a table to a specific key ,overriding anything in the keys definition of the file. Normally used on databases that are not able to be queried correctly for their structure
Пример 34-3. using login as the key for the person table
|
If you do not want to use pear's nextval(), for automatically filling in sequences, this can disable it for "ALL", or a list of tables "person,cart,group"
The default debugging level (default 0=off), 1= basic sql logging,2=result logging, 3=everything
default FALSE, if set, then updates on the database are disabled.
default FALSE, The standard behaviour of dataobjects is to issue a PEAR_ERROR_DIE (eg. exiting PHP), when a fatal error occurs, like database connection failure or sending an invalid object type to a method. However if you need to run it on a live server you will probably want to set this to TRUE and define a PEAR error handler to catch these errors and show a nice friendly 'sorry we are down for maintenence' message page.
To force the quotation of identifiers in the SQL statements, set this to 1
Пример 34-4. Statement Generated with and without quote_identifiers
|
This enables the building of classes and ini classes on the fly, rather than forcing you to generate the code forhand. (currently the only value supported is "full", which will generate both schema data and default classes when using factory)
When you have multiple databases you can use the database_* to specify the DSN for each database
Пример 34-5. using multiple databases - database passwords
|
When you have multiple databases you can use the table_* configuration variables to map individual tables to different databases, for example
Пример 34-6. using multiple databases - table settings
|
The Directory where your DataObject extended Classes are.
Used by the Class Auto Builder when updating/writing to your class definitions.
The Name of your Base Class (usually DB_DataObject) is located.
If you wish to add a common layer of useful methods for all classes, you can set the extends_location and extends settings to a different class. the default is 'DB_DataObject'
The Directory where your Base Class (usually DB_DataObject) is located.
If you wish to add a common layer of useful methods for all classes, you can set the extends_location and extends settings to a different class. the default is 'DB/DataObject.php'
Normally when you recreate a class from the database, it will only alter the variables, and staticGet, - with this set, it will also update the extends field
Postgres (and maybe some others), allow you to treat views just like normal tables (eg. insert/update/delete etc. work on them), you can use this option to generate files for all the views in the database.
Note: You will have to specify keys manually in the generated classes (eg. define the methods keys() and sequenceKey(), as the generator can not guess which ones are likely to be the key.
If you only want to generate classes and ini entries for specific tables, you can use this to build a regex, only tables with names matching the regex will be generated, for example /mytables_.*/
If you only want to explicitly prevent the generation of classes and ini entries for specific tables, you can use this to build a regex, any tables that match the regex, will not be generated, for example /private_tables_.*/
postgresql has a wierd concept of schemas which end up prefixed to the list of tables. - this makes a mess of class/schema generation setting this to 1, makes the generator strip the schema from the table name
If True, the generator does not write a private or var's definition for the columns so you can overload get/set.
If True, the generator will insert / (or add to existing files) stubs for validate methods.
One of the essential features of an SQL building tool is to to have some understanding of the database structure, So that Integers can be checked, and strings can be escaped. There a few ways that Querying the database for the table structure could be accomplished
on every SQL query
At the initialization of every web page.
Once, while setting up the application, and store it in a file
The other key concept of DB_DataObject is that you work with extended classes of DB_DataObject, which do all the 'table' related work. Setting up these classes for a large database can be time consuming, so the createTables.php file will automatically build the skeletons for all these class files.
To start the auto builder simply go to the pear/DB/DataObject/ directory, and type c:\php4\php.exe createTables.php myconfig.ini this will read your configuration file and generate all the base classes, along with the data definition file.
As of Version 1.5, you can use the option "proxy = full", which will cause DataObjects to create classes and schema on the fly, rather than using an ini file or prebuilt classes.
The default generated class looks like this.
Пример 34-1. an generated extended class
|
The class defines the table name, and comments some of table columns for your reference, It also adds the staticGet() method, which can be used to quickly get single rows as Objects. You should add your table related code after the ###END_AUTOCODE.
Prior to version 1.6 a method __clone was created, since PHP5 changed to use $x = clone($y);, this method has been removed. DataObjects now creates a dummy function clone (if necessary), to enable forward compatibilty
The default generated database definition file looks like this, it is located in the directory set by the "schema_location" configuration option, and is named the same as the database.
If you rename the database, you will either have to regenerate the file or copy it to match the same name.
If you change the database schema (eg. add a column or change the type), you will have to regenerate the schema file, using createTables.php, At present, this is not done automatically (although this may be added in the future..)
You should not edit this file by hand (as any changes will be lost when regenerating it). You can override the keys of a table by using a configuration option "sequence_{table} = key", or by defining the sequenceKey() method in your extended class.
Пример 34-2. Database configuration file
|
The blocks indicate either tables and the type of field with binary addition (1=integer,2=string,128=not null, so 129=integer and not null), or a list of keys for each table. You should not need to edit file.
It is possible to use DataObjects without a schema file, this can be achieved in 2 ways
by defining the table() and keys() methods in an extended class
by passing an array to table() and keys() when you have an instance of dataobjects
Below is a hand coded class which does not use a schema.ini file.
It was designed to be a return value from a method, rather than an object variable, so that the output of print_r(), would not include extra information (and would be smaller when dumping a large result set.
Пример 34-3. A Hand Coded extended class
|
This is the recommended way to autoload a class, and instantate it. The class is loaded based on the configuration settings (class_location and class_prefix) for table to class naming.
string $table - the table you want to load ([From Version 1.7.2] if blank, and called on an an instance of a dataobject, it will create a new instance of that object)
Таблица 34-1. Возможные значения PEAR_Error
Error code | Error message | Meaning | Solution |
---|---|---|---|
DB_DATAOBJECT_ERROR_NOCLASS | "could not autoload $class" |
Пример 34-1. Simple fetch of data based on Primary Key
|
Get a result using key, value. Returns Number of rows located (usually 1) for success, and puts all the table columns into this classes variables. If only one parameter is used, it is assumed that first parameter is a value and get() will use the primary key.
Таблица 34-1. Возможные значения PEAR_Error
Error code | Error message | Meaning | Solution |
---|---|---|---|
DB_DATAOBJECT_ERROR_INVALIDCONFIG | "No Keys available for $table" | ||
DB_DATAOBJECT_ERROR_INVALIDARGS | "No Value specified for get" |
Эта функция не должна вызываться статически.
You should avoid calling get on the same object instance twice, as this will result in unexpected results.
Пример 34-1. Simple fetch of data based on Primary Key
|
Пример 34-2. Resulting SQL
|
Пример 34-3. Simple fetch of data based on Key and Value
|
Пример 34-4. Resulting SQL
|
Пример 34-5. Results of example code
|
Внимание |
This method is depreciated, it is recommended to use ::factory() and ->get() |
The static method is a combination of factory and get(). staticGet() will cache the returned data in a global variable for quick access within the same request (any data modification query will clear the cache).
string $class - class name
string $key - column (or value if only 2 paramaters are given)
mixed $value - value
Таблица 34-1. Возможные значения PEAR_Error
Error code | Error message | Meaning | Solution |
---|---|---|---|
DB_DATAOBJECT_ERROR_NOCLASS | "could not autoload $class" | ||
DB_DATAOBJECT_ERROR_NOCLASS | "Error creating $newclass" | ||
DB_DATAOBJECT_ERROR_NODATA | "No Data return from get $key $value" |
Пример 34-1. Simple fetch of data based on Primary Key
|
The static method is similar to the get request, however it does not require the initial instantiation of the class. staticGet() can optionally cache the results. (see the configuration section)
Таблица 34-1. Возможные значения PEAR_Error
Error code | Error message | Meaning | Solution |
---|---|---|---|
DB_DATAOBJECT_ERROR_NOCLASS | "could not autoload $class" | ||
DB_DATAOBJECT_ERROR_NOCLASS | "Error creating $newclass" | ||
DB_DATAOBJECT_ERROR_NODATA | "No Data return from get $key $value" |
Пример 34-1. Simple fetch of data based on Primary Key
|
The find method builds and executes the current Query, based on the object variables and any WhereAdd() conditions , If the AutoFetch is TRUE, then it will also call the fetch method automatically.
int - number of rows found, only if the database backend supports the numRows() method. Otherwise 1 (or in versions after 1.7.13, true will returned)
Пример 34-1. Simple find() of data based on Object Vars
|
Пример 34-2. Resulting SQL
|
The fetch method gets the next row and sets the objects variables to the rows data. It returns TRUE if data has been collected, and FALSE when there is no more data.
Эта функция не должна вызываться статически.
Fetch is called by staticGet and get calls, so you can override this method in your classes, to add extra data to your object (like formated dates etc)
Пример 34-1. Simple find and fetch of data based on object Vars
|
Пример 34-2. Overriding fetch to add extra data.
|
It performs a select count() request on the tables key column and returns the number of resulting rows. The default condition applied to the count() is a combination of the object variables and whereAdd settings. If the constant DB_DATAOBJECT_WHEREADD_ONLY is passed in as the first parameter then only the whereAdd settings will be used.
string $countWhat - by default count will count on the primary key, if you need to count something else, if you just say DISTINCT, it will count the primiary key prefixed with distinct, or put your own value in (dont forget to escape it if necessary)
boolean $useWhereAddOnly - use only the whereAdd conditions (by default, count will only use both the object settings and the whereAdd conditions)
Пример 34-1. Various examples of using count()
|
Пример 34-2. Resulting SQL
|
Insert the data into the database, based on the variable values of the current object and returns the ID of the inserted element if sequences or primary keys are being used. The values are correctly quoted, and some limited type checking is done.
With mysql, the mysql_next_id() method is used, on other databases, PEAR DB sequence method is used.
Note, insert() may not return the ID correctly in quite a few situations:
If the database backend does not support it.
The generator did not correctly flag the correct column as autoincrement/nextval
An error occured (turn on debugging to see it)
The insert failed or '0' rows where affected.
Таблица 34-1. Возможные значения PEAR_Error
Error code | Error message | Meaning | Solution |
---|---|---|---|
DB_DATAOBJECT_ERROR_INVALIDCONFIG | "insert:No table definition for $table" | ||
DB_DATAOBJECT_ERROR_NODATA | "insert: No Data specifed for query" | ||
DB_* | * | see PEAR::DB | see PEAR::DB |
Пример 34-1. Simple insert
|
Пример 34-2. Resulting SQL
|
Updates current objects variables into the database. if you supply it with a dataObject, as an argument, it will only update the differences between the new and old.
if called with DB_DATAOBJECT_WHEREADD_ONLY as the argument, the update request is built based on the whereAdd values, rather than the primary key. This enables global updates to be performed, rather than single row ones.
DataObject $original - if provided the update query will be built from the difference between the current and original dataobject.
Таблица 34-1. Возможные значения PEAR_Error
Error code | Error message | Meaning | Solution |
---|---|---|---|
DB_DATAOBJECT_ERROR_INVALIDCONFIG | "update:No table definition for $table" | ||
DB_DATAOBJECT_ERROR_NODATA | "update: No Data specifed for query $settings" |
Пример 34-1. Simple fetch and update
|
Пример 34-2. Resulting SQL
|
Пример 34-3. Simple fetch and update
|
Пример 34-4. Resulting SQL
|
Deletes data from the database, either using primary key or based on a whereAdd() method call. By default the delete will base it's query on the set variables, however if you wish to use the whereAdd() method you should set the $useWhere parameter to DB_DATAOBJECT_WHEREADD_ONLY.
boolean $use_where - use the whereAdd() conditions (by default, delete will only use primary keys)
Таблица 34-1. Возможные значения PEAR_Error
Error code | Error message | Meaning | Solution |
---|---|---|---|
DB_* | "*" | see PEAR::DB | see PEAR::DB |
DB_DATAOBJECT_ERROR_NODATA | "delete: No Data specifed for query $condition" |
Пример 34-1. Simple Delete
|
Пример 34-2. Resulting SQL
|
The basic features allow most simple queries to be done very quickly, however building more complex queries can be done using the methods listed below, which append or set conditions that build the query. You will find that there is a fine balance between using these builder methods and just using raw SQL.
The DB_DataObject can now handle JOIN queries, however please read the introduction to linking and Joining before jumping in and using the Join feature, as you may be trading the use of a cool feature, against the readibility of your code.
Sends a raw query to database. Often you may consider that using a large number of whereAdd's and orderBy method calls are not neccessary, and it would be simpler to just write the query, to make the code clearer and shorter.
Пример 34-1. raw queries on the database
|
DataObjects stores result set's as a private global variable, normally this is free'ed after you have run through the results, or at the end of the request. However in some situations, like running queries directly, inserting data, some data is unnecessarly cached.
Using this method will Free All results sets! (so be carefull) it may break running fetch() loops..
You normally only need to use this if you are doing a large number of inserts or queries.
Пример 34-1. Freeing resources in a loop
|
Adds a selected columns. By default a select query will request all items (eg. SELECT * FROM table), to change this behavior you can first call selectAdd() without any arguments to clear the current request and then add the specific items you require.
You can also set up a default selection query by adding SelectAdd() method calls in the object constructor method (the one with the same name as the class)
Пример 34-1. Using selectAdd()
|
Пример 34-2. Resulting SQL
|
Adds items to the where part of a SQL query. Calling this without any arguments clears the where condition. The default behavior is to add 'AND' to the existing conditions, use the $logic parameter to append OR conditions.
string $cond - condition to add, or blank to reset the conditions
string $logic - optional logic "OR" (defaults to "AND")
Пример 34-1. Using whereAdd()
|
Пример 34-2. Resulting SQL
|
Similar to Pear DB's quote it will escape a value, without the quotes, so it can be used with a LIKE query.
Пример 34-1. Escaping a LIKE string
|
Пример 34-2. Sample SQL
|
Sets the limit for a query. (this only works on databases that support the LIMIT clause), without parameters, it will clear the current limit.
int $from - limit start (or number), or blank to reset
int $number - limit results to number
Эта функция не должна вызываться статически.
Since postgres and mysql only really support limit directly - calling this on an unsupported database will emit a PEAR::Error and die.
Пример 34-1. Setting the Limit
|
Пример 34-2. Resulting SQL
|
Adds a order by condition. Calling this without any arguments clears the current order condition.
Пример 34-1. Setting the order by
|
Пример 34-2. Resulting SQL
|
Пример 34-1. Setting the Group by
|
Пример 34-2. Resulting SQL
|
When designing a database, often some tables are related to others - a membership table would contain a reference to a person's id and the group id that they are a member of. Using the Link methods, you can automatically fetch objects into the parents variables.
Automated links are supported by a databasename.links.ini file. which stores the relations ship between tables, maping one tables column to anothers. This databasename.links.ini file is used by the getLinks() and joinAdd() Method, to either retrieve related information of a primary object, or quickly build complex multitable queries.
The other way of using linking is via the getLink() method, which you can manually use without a database.links.ini file to specify a column, and how it relates to another table and column.
The goal of getlinks and joinAdd is to make connecting two tables as simple and fast as possible, while still ensuring that the code is reasonably comprehensable. In the example below, It is demostrated how getlinks() can be used to fetch more data about an object after the initial fetch, and it can also be used to test the links file prior to building a full blown join Query.
Пример 34-1. A simple introduction to links and joins
|
DB_DataObject Version 0.3 introduced the ability to create link ini files so you can map column to other database columns using an ini file this ini file should have the name 'databasename.links.ini', and be placed in the same folder as the database schema ini file 'databasename.ini' file that is created automatically by createTables.php
The databasename.links.ini file contains a section for each table, then the column that is linked equal to the table and column that it should locate the column from. It assumes the relationships are non-primary id to primary id, as the example below shows, the person.owner is linked to grp.id. This indicates that running getLinks() on the person object, will fetch a single bit of data from 3 tables - colurs,grp,attachments.
If you use a 'full stop' in the key (link from column), getLinks() will look up in the table with the column name matching the string to the left of the 'full stop', and replace the 'full stop' with and underscore and assign the object variable to that name. Or you may wish to use the selectAs() method to decide how you want columns from different objects to be returned (when using joinAdd())
Пример 34-2. An example databasename.links.ini file
|
It is also possible to create joins on keys consisting of more than one column. Use the following syntax:
Пример 34-3. Linking tables on composite keys
|
This will lead to the following select statement (here using the INNER JOIN syntax):
Пример 34-4. Resulting SQL
|
Fetch a related object. This should be used in conjunction with a <dbname>.links.ini file configuration (see the introduction on linking for details on this).
You may also use this with all parameters to specify, the column, and related table and column.
string $column - either column or column.xxxxx
string $table - name of table to look up value in
string $link - name of column in other table to match
Пример 34-1. Getting the related object
|
Пример 34-2. Resulting SQL
|
Loads the all the related objects into the main object, by using the links.ini relationships, and sets the calling objects variables with the row name prefixed with an underscode (_) to the resulting objects.
Using this with the earlier column naming convention is depreciated, and links.ini files should be used.
string $variableFormat - the default behavior is to assign the resulting objects to variables with the row name prefixed with an underscode (_), however, you can use this value to format the variable differently
Пример 34-1. examples of formaters
|
Пример 34-2. Two Example Tables
|
Пример 34-3. Loading all the related objects
|
Пример 34-4. Resulting SQL
|
Пример 34-5. Resulting Output
|
Пример 34-6. Example with three tables join
|
Пример 34-7. databasename.links.ini
|
Auto creates select items based on either the current objects column names, the supplied object, or an array.
This is primarily used in conjunciton with joinAdd, to enable the renaming of columns into a fixed format when they are likely to have naming conflicts (like both tables have an 'id' column).
Sending no arguments to selectAs, will reset the current select (usually removing the default *), and build a select list based on the current objects column names.
object | array $column_or_object - a dataobject or array of column names
string $format - the format the columns will appear, using sprintf format, the %s is replaced with the column name so car_%s would result in the SQL 'car.name as car_name' being generated.
string $tableName - this is used either when use send an array as the first argument, or when you are joining a table 'as' another name,
Пример 34-1. Using selectAs()
|
Builds a Join Query, by adding another dataobject to this one. Be careful when using this, raw queries may be clearer than using joinAdd.
Thanks to Stijn de Reede for the implementation of this.
object $obj - joining object (no value resets the join)
string $joinType - "LEFT" | "INNER " | "RIGHT" | ""
INNER is default, "" indicates just select ... from a,b,c with no join and links are added as where items.
Note: 'LEFT' is the same as LEFT OUTER.
string $joinAs - if you want to select the table as anther name useful when you want to select multiple columns from a secondary table.
string $joinCol - The column on This objects table to match,needed if this table links to the child object in multiple places eg.
Пример 34-1. using specific join Columns
|
Эта функция не должна вызываться статически.
The Examples below are not tested, use DB_DataObject::debugLevel(1), to see what exactly is going on when you use this, and send the author some better examples..
Пример 34-2. Simple simple Join
|
Пример 34-3. Resulting SQL
|
Пример 34-4. More Complex Join query
|
Пример 34-5. Resulting SQL
|
From version PHP 4.3.2RC2 onwards, DB_DataObject is automatically overloaded, providing access to all variables using $object->set{ColumnName}() and $object->set{ColumnName}($value) even if you have not defined the method.
It is assumed that set methods return strings as errors or TRUE, so that it can interact with setFrom and return array's of error strings.
The get Methods are used by toArray(), if defined they can be used to alter the appearance of columns ,like making dates human readable
The logic is very simple, if you call $object->setXXX() and it is not defined, it will just set the value, if you define a method setXXXX, that will be called instead of the default handler, same applies to getXXX().
Due to the naming conflict possiblity of a column named from, the associated method for column 'from' is set_from, rather than setFrom()
mixed $value - on setters only (the value to assign to the column), on getters you may like to implement date formating or sprintf formating as the argument.
mixed - setters will return TRUE from the default method, in your implementations of setters. It is expected that setXXX($value) will return a string (the error) if it is invalid or TRUE on success. getXXX may return the value or a formated value, remember though it affects $object->toArray().
Эта функция не должна вызываться статически.
Warning: This is experimental, its behavour may change slightly in the future.
Пример 34-1. Simple find and fetch of data based on Object Vars
|
Пример 34-2. Resulting Output
|
Copies items that are in the table definitions from an array or object into the current object (It will not override key values). This can be used to process form posts (if the field names match the database), or cloning similar objects.
you can not set the value of a key column using setFrom, It is silently ignored for security reasons. (you can still assign it manually)
setFrom will attempt to call the setters set{columnname} methods if they exist, It will also call fromValue(), which formats dates correctly.
You may realize that this method overlaps the overloaded method for the column name from, due to this, the associated methods for the column name 'from' are set_from and getFrom.
array or Object $from - what to copy from
string $format - the format of the array or object variables and how they relate to this object. for example if your input array is in the format prefix_COLNAME, then you can use 'prefix_%s'.
array or boolean - TRUE on success or an array of set*() return values in PHP4.3.2 upwards
Пример 34-1. Using setFrom()
|
Allows the fetching of an associate array (with optional key formating) for use with other packages, like HTML_QuickForms.
From PHP4.2.3RC2 onwards, The values of each column are retrieved using getXXXX() methods so you can change the formating of a row by defining a getter method.
Пример 34-1. getting arrays
|
Пример 34-2. Sample Output
|
Check all the objects variables to see if they are valid, by default this means is a column an integer or string, if you define methods like validateEmail(), in your extended class then it will be called to validate the row called 'email'. This may be useful if called prior to an update or insert.., to generate error messages.
override this to set up your validation rules.
Эта функция не должна вызываться статически.
the examples below utilize the PEAR validation package
Пример 34-1. validate usage
|
Пример 34-2. validate methods
|
Without any argument, it returns the table name that the object deals with. With a string, it will set the table name for the instance of the object.
Пример 34-1. getting and setting the tablename
|
Without any argument, it returns the database that the object deals with. With a string, it will set the database for the instance of the object.
Пример 34-1. Getting the database name
|
Without any argument, it returns the table schema that the object deals with. With an array, it will set the table schema for the instance of the object.
The default schema is normally stored in the database.ini file described in the Autobuilding section.
Пример 34-1. getting the connection
|
Without any argument, it returns the keys used by the object (the generator builds these and guess'es them based on finding things like primary key, unique, or nextval() in the description. Calling it with a value , or mulitple values, sets it for the current instance of the object.
The default keys are is normally stored in the database.ini file described in the Autobuilding section.
Пример 34-1. getting the connection
|
Fetch the pear database connection that the object uses - so you can find information or send queries directly to it.
Пример 34-1. getting the connection
|
Пример 34-2. Sample Output
|
Fetch the pear database result object - so you can use it with things like the Pager or HTML_Select classes
Пример 34-1. getting the result object
|
Sets and returns debug level. So you can see the queries and connections being built and executed.
integer $level - level, without any parameters it will disable the debugging output. 1 give a general output, 5 includes things like passwords for connections.
Пример 34-1. Using debugLevel()
|
Debugger - you can use this in your extended classes to output debugging information. Uses DB_DataObject::DebugLevel(x) to turn it on, and can be completly turned off by using the production setting in the configuration file
string $message - message to output
integer $logtype - A bold prefix string
integer $level - output level, 1 is general, 5 tends to reveal things like database connection passwords..
Эта функция не должна вызываться статически.
Внимание |
In production mode, the debugger is disabled |
Пример 34-1. Setting the debugging level
|
Default error handling is to create a PEAR::Error, but never return it. If you need to handle errors you should look at setting the PEAR_Error callback this is due to the fact it would wreck havoc on the internal methods!
int $message - message
resource $type - type
resource $behaviour - behaviour (die or continue!);
Внимание |
This is experimental!, although it is documented, it currently only supports a limited amount of databases (send me fixes if you want it to support your favorite database), and the internal operations/API may change in the future.. |
DataObjects is a very easy way to work with databases that are focused on numbers and strings. You can also use it on date fields (although you must format your strings correctly), and you can use it with other types by using raw SQL query(), and the string value "null" is automatically converted to NULL in the database.
In an effort to provide a cleaner way to code to the richer database types, the DB_DataObject_Cast object was created. It's purpose is to simply create an object to represent some of the more unusual types. Below is an example of using it to create a few simple types.
Cast Objects can be used in both building queries, and assigning values
Пример 34-1. Cast Objects for building and assigning values
|
As you can see, This component is in it"s infancy, so if you have any feature requests, ideas, please do not hesitate to contact me at alan_k at php dot net.
Blobs are fields which can store large amounts of binary data in the databases.
At present only blobs is only supported in postgres using the bytea type. (please email me with code for other databases.)
Пример 34-2. Inserting a photo and a big text file
|
Most dates are stored in a database in ISO standard format, this method, allows you to create date types, from either Year,month,day, Human readable day/month/year, or standard iso format year-month-day. It fills in the remaining values based on simple rules.
Пример 34-3. Inserting a date in various formats
|
Some types are sql specific, or may even be database specific, you can use the sql type to put raw strings as part of the sql statement.
Пример 34-4. using raw sql
|
A package for building HTML forms from DataObject classes.
For now, detailed documentation is available here.
You can view a presentation about FormBuilder here.
DB_DataObject_FormBuilder will aid you in rapid application development using the packages DB_DataObject and HTML_QuickForm. For having a quick but working prototype of your application, simply model the database, run DataObject createTable script over it and write a script that passes one of the resulting objects to the FormBuilder class. The FormBuilder will automatically generate a simple but working HTML_QuickForm object that you can use to test your application. It also provides a processing method that will automatically detect if an insert() or update( )command has to be executed after the form has been submitted. If you have set up DataObject links.ini file correctly, it will also automatically detect if a table field is a foreign key and will populate a selectbox with the linked tables entries. There are many optional parameters that you can place in your DataObjects.ini or in the properties of your derived classes, that you can use to fine-tune the form-generation, gradually turning the prototypes into fully-featured forms, and you can take control at any stage of the process. Basic usage:
$do =& new MyDataObject(); // Insert "$do->get($some_id);" here to edit an // existing object instead of making a new one $fg =& DB_DataObject_FormBuilder::create($do); $form =& $fg->getForm(); if ($form->validate()) { $form->process(array(&$fg,'processForm'), false); $form->freeze(); } $form->display(); |
This package is an OO-abstraction to the SQL-Query language, it provides methods such as setWhere, setOrder, setGroup, setJoin, etc. to easily build queries.
This package is an OO-abstraction to the SQL-Query language, it provides methods such as setWhere, setOrder, setGroup, setJoin, etc. to easily build queries. It also provides an easy to learn interface that interacts nicely with HTML-forms using arrays that contain the column data, that shall be updated/added in a DB. This package bases on an SQL-Builder which lets you easily build SQL-Statements and execute them.
You can find some useful usage examples and docs in the MDB_QueryTool documentation. Everything there holds true for DB_QueryTool too, except for the class name, of course.
DB_Table is an object-oriented interface to a database table.
A unified API for accessing databases, based on user provided meta data.
To connect to a database through PEAR::MDB, you have to create a valid DSN - data source name. This DSN consists in the following parts:
phptype: Database backend used in PHP (i.e. mysql , odbc etc.) |
dbsyntax: Database used with regards to SQL syntax etc. |
protocol: Communication protocol to use ( i.e. tcp, unix etc.) |
hostspec: Host specification (hostname[:port]) |
database: Database to use on the DBMS server |
username: User name for login |
password: Password for login |
proto_opts: Maybe used with protocol |
The format of the supplied DSN is in its fullest form:
phptype(dbsyntax)://username:password@protocol+hostspec/database |
phptype://username:password@protocol+hostspec:110//usr/db_file.mdb phptype://username:password@hostspec/database_name phptype://username:password@hostspec phptype://username@hostspec phptype://hostspec/database phptype://hostspec phptype(dbsyntax) phptype |
mysql -> MySQL pgsql -> PostgreSQL ibase -> InterBase mssql -> Microsoft SQL Server oci8 -> Oracle 7/8/8i fbsql -> FrontBase |
With an up-to-date version of MDB, you can use a second DSN format
phptype(syntax)://user:pass@protocol(proto_opts)/database |
Пример 34-1. Connect to database through a socket
|
Пример 34-2. Connect to database on a non standard port
|
Внимание |
Please note, that some features may be not supported by all database backends. Please refer to the PEAR MDB extensions status document located at: <pear base dir>/MDB/STATUS to get a detailed list about what features are supported by which backend. |
To connect to a database you have to use the function MDB::connect() , which requires a valid DSN as parameter and optional a boolean value, which determines wether to use a persistent connection or not. In case of success you get a new instance of the database class. It is strongly recommened to check this return value with MDB::isError() . To disconnect use the method disconnect() from your database class instance.
Пример 34-1. Connect and disconnect
|
To perform a query against a database, you have to use the function query(), that takes the query string as an argument. On failure you get a MDB_Error object. Be sure to check it with MDB::isError(). On success, you get MDB_OK or when you set a SELECT-statment a result resource handle
Пример 34-1. A simple MDB query
|
In order to fetch data from a result resource you can use one if the following methods: fetchInto() , fetchOne() . , fetchRow() . , fetchCol() . and fetchAll() . All above mentioned methods except fetchOne() return the requested data encapsuled into a (multi-dimensional-)array, NULL on no more data or a MDB_Error , when an error occurs. All method prefixed with fetch() automatically free the result set.
Пример 34-1. Fetching a result set
|
The fetch modes supported are:
MDB_FETCHMODE_ORDERED (default)
The fetch*() returns an ordered array. The order is taken from the select statment.
Пример 34-2. Fetch a ordered array
|
MDB_FETCHMODE_ASSOC
Returns an associative array with the column names as the array keys
Пример 34-3. Fetch a assoc. array
|
You can set the fetch mode per result call or for your whole MDB instance.
Пример 34-4. Per call
|
Пример 34-5. Once per instance
|
The PEAR MDB fetch system also supports an extra parameter to the fetch statement. So you can fetch rows from a result by number. This is especially helpful if you only want to show sets of an entire result (for example in building paginated HTML lists), fetch rows in an special order, etc.
Пример 34-6. Fetching by number
|
It is recommended to finish the result set after processing in order to to save memory. Use freeResult() to do this.
Пример 34-7. Freeing
|
MDB provides some special ways to retrieve information from a query without the need of using fetch*() and loop throw results.
queryOne() retrieves the first result of the first column from a query
$numrows = $db->queryOne('select count(id) from clients'); |
queryRow() returns the first row and returns it as an array.
$sql = 'select name, address, phone from clients where id=1'; if (is_array($row = $db->queryRow($sql))) { list($name, $address, $phone) = $row; } |
queryCol() returns an array with the data of the selected column. It accepts the column number to retrieve as the second parameter.
$all_client_names = $db->queryCol('SELECT name FROM clients'); |
$all_client_names = array('Stig', 'Jon', 'Colin'); |
getAll() fetches all the rows returned from a query. This method also has some advanced parameters still will also enable you to return the data as an associative array using the first column as the key.
$data = getAll('SELECT id, text, date FROM mytable'); /* Will return: array( 1 => array('4', 'four', '2004'), 2 => array('5', 'five', '2005'), 3 => array('6', 'six', '2006') ) */ |
The query*() family methods will do all the dirty job for you, this is: launch the query, fetch the data and free the result. Please note that as all PEAR MDB functions they will return a MDB_Error object on errors.
With MDB you have many ways to retrieve useful information from query results. These are:
numRows() : Returns the total number of rows returned from a "SELECT" query.
// Number of rows echo $db->numRows($res); |
numCols() : Returns the total number of columns returned from a "SELECT" query.
// Number of cols echo $db->numCols($res); |
affectedRows() : Returns the number of rows affected by a data manipulation query ("INSERT", "UPDATE" or "DELETE").
// remember that this statement won't return a result object $db->query('DELETE * FROM clients'); echo 'I have deleted ' . $db->affectedRows() . ' clients'; |
tableInfo() : Returns an associative array with information about the returned fields from a "SELECT" query.
// Table Info print_r($db->tableInfo($res)); |
Sequences are a way of offering unique IDs for data rows. If you do most of your work with e.g. MySQL, think of sequences as another way of doing AUTO_INCREMENT. It's quite simple, first you request an ID, and then you insert that value in the ID field of the new row you're creating. You can have more than one sequence for all your tables, just be sure that you always use the same sequence for any particular table. To get the value of this unique ID use nextId() , if a sequence doesn't exists, it will be created automaticlly.
Пример 34-1. Using a sequence
|
prepareQuery() and executeQuery*() give you more power and flexibilty for query execution. You can use them, if you have to do more than one equal query (i.e. adding a list of adresses to a database) or if you want to support different databases, which have different implementations of the SQL standard.
Imagine you want to support two databases with different INSERT syntax:
db1 : INSERT INTO tbl_name ( col1, col2 ... ) VALUES ( expr1, expr2 ... ) db2 : INSERT INTO tbl_name SET col1=expr1, col2=expr2 ... |
$statement['db1']['INSERT_PERSON'] = "INSERT INTO person ( surname, name, age ) VALUES ( ?, ?, ? )" ; $statement['db2']['INSERT_PERSON'] = "INSERT INTO person SET surname=?, name=?, age=?" ; |
To use the features above, you have to do two steps. Step one is to prepareQuery the statement and the second is to executeQuery it.
Prepare() has to be called with the generic statement at least once. It returns a handle for the statement.
To create a generic statement is simple. Write the SQL query as usual, i.e.
SELECT surname, name, age FROM person WHERE name = 'name_to_find' AND age < 'age_limit' |
SELECT surname, name, age FROM person WHERE name = ? AND age < ? |
prepareQuery() can handle different types of placeholders or wildcards.
? - (recommended) stands for a scalar value like strings or numbers, the value will be quoted depending of the database |
! - stands for a scalar value and will inserted into the statement "as is". |
& - requires an existing filename, the content of this file will be included into the statement (i.e. for saving binary data of a graphic file in a database) |
After preparing the statement, you can execute the query. This means to assign the variables to the prepared statement. To do this, executeQuery() requires two arguments, the statement handle of prepareQuery() and an array with the values to assign. The array has to be numerically ordered. The first entry of the array represents the first wildcard, the second the second wildcard etc. The order is independent from the used wildcard char.
Пример 34-1. Inserting data into a datebase
|
INSERT INTO numbers VALUES( '1', 'one', 'en') INSERT INTO numbers VALUES( '2', 'two', 'to') INSERT INTO numbers VALUES( '3', 'three', 'tre') INSERT INTO numbers VALUES( '4', 'four', 'fire') |
Пример 34-2. Using executeMultiple() instead of executeQuery()
|
If executeQuery*() fails a MDB_Error, else MDB_OK will returned.
The main MDB class is simply a container class with some static methods for creating MDB objects.
Data Source Name. See the "DSN" section for further information.
If $options is TRUE the connection will be persistent (requires support by database driver). Default is FALSE. In future releases, this parameter will be an array and take different options depending on the database.
Таблица 34-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
MDB_ERROR_NOT_FOUND | NULL | The database specific class was not found. | Check the $dsn and make sure to have an complete installation of the MDB-package and that you database is supported by MDB. |
MDB_Common is an interface class; that provides all methods to query a specific database. An instance of a database specific class will be returned by the MDB::connect() method.
Таблица 34-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
MDB_ERROR_NOT_CAPABLE | NULL | Function is not supported by the database backend | Switch to another database system, if you really need this feature. |
name of the new sequence to create
starting value of the sequence
Таблица 34-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
every error code | Database specific error | Check the name of the sequence. If correct, probably a bug in the sequence implementation |
Таблица 34-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
MDB_ERROR_NOT_CAPABLE | NULL | Function is not supported by the database backend | Switch to another database system, if you really need this feature. |
MDB_ERROR_NOT_LOCKED | NULL | Locking of sequence table fails | Database specific, check documention of your database, |
MDB_ERROR_NOSUCHTABLE | NULL | Sequence table was not found | Try to create a new sequence or if you are sure, a sequence was already create, check database integrity |
Таблица 34-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
every error code | Database specific error | Check the name of the sequence. If correct, probably a bug in the sequence implementation. |
execute() joins the prepared SQL statment from prepareQuery() with the given data and executes the SQL query.
query handle from prepareQuery()
if supplied, the types of the columns in the result set will be set for fetching
a numeric array containing the data to insert into the query
if supplied, the values in $param will automatically be set to the passed datatypes
Таблица 34-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
MDB_ERROR_INVALID | NULL | SQL statment handle is not valid. | Check correct processing of the SQL statment with prepareQuery() . Note that execute() requires a handle to the statement returned by prepareQuery() , not the statment itself. |
MDB_ERROR_NEED_MORE_DATA | NULL | To less data for filling the prepared SQL statment. | Check the number of wild cards given in the SQL statment for prepareQuery() . Check the count of entries in the array for $data. The count of entries have to be equal to the number of wild cards. |
MDB_ERROR_NO_DB_SELECTED | NULL | No database was choosen. | Check the DSN in connect() . |
every other error code | Database specific error | Check the database related section of PHP-Manual to detect the reason for this error. In the most cases a misformed SQL statment. Ie. using LIMIT in a SQL-Statment for an Oracle database. |
executeQuery() joins the prepared SQL statment from prepareQuery() with the data that was set using one of the setParam() methods and executes the SQL query.
query handle from prepareQuery()
if supplied, the types of the columns in the result set will be set for fetching
Таблица 34-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
MDB_ERROR_INVALID | NULL | SQL statment handle is not valid. | Check correct processing of the SQL statment with prepareQuery() . Note that executeQuery() requires a handle to the statement returned by prepareQuery() , not the statment itself. |
MDB_ERROR_NEED_MORE_DATA | NULL | To less data for filling the prepared SQL statment. | Check the number of wild cards given in the SQL statment for prepareQuery() . Check the count of entries in the array for $data. The count of entries have to be equal to the number of wild cards. |
MDB_ERROR_NO_DB_SELECTED | NULL | No database was choosen. | Check the DSN in connect() . |
every other error code | Database specific error | Check the database related section of PHP-Manual to detect the reason for this error. In the most cases a misformed SQL statment. Ie. using LIMIT in a SQL-Statment for an Oracle database. |
Эта функция не должна вызываться статически.
See Introduction - Execute for general using and an example.
executeMultiple() joins the prepared SQL statment from prepareQuery() with the given data and does the SQL query for every "row" in the $data array.
query handle from prepareQuery()
if supplied, the types of the columns in the result set will be set for fetching
if supplied, prepareQuery()/ executeQuery() will be used with this array as execute parameters
if supplied, the values in $param will automatically set to the passed datatypes
a numeric array containing the data to insert into the query
Таблица 34-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
MDB_ERROR_INVALID | NULL | SQL statment handle is not valid. | Check correct processing of the SQL statment with prepareQuery() . Note that executeMultiple() requires a handle to the statement returned by prepareQuery() , not the statment itself. |
MDB_ERROR_NEED_MORE_DATA | NULL | To less data for filling the prepared SQL statment. | Check the number of wild cards given in the SQL statment for prepareQuery() . Check the count of entries in the array for $data. The count of entries have to be equal to the number of wild cards. |
MDB_ERROR_NO_DB_SELECTED | NULL | No database was choosen. | Check the DSN in connect() . |
every other error code | Database specific error | Check the database related section of PHP-Manual to detect the reason for this error. In the most cases a misformed SQL statment. Ie. using LIMIT in a SQL-Statment for an Oracle database. |
Эта функция не должна вызываться статически.
Внимание |
If an error occurs during execution, the function will be stopped. Possible remaining data will be unprocessed. |
See Introduction - Execute for general using and an example.
Fetch the entire result set of a result set and return it into a nested array and free the result set.
a valid resource returned by query() or executeQuery()
the fetch mode to use
if set to TRUE the array result be modified as follows: If the result set contains more than two columns, the value will be an array of the values from column 2 to n. If the result set contains only two columns, the returned value will be a scalar with the value of the second column (unless forced to an array with the $force_array parameter).
used only if the query returns exactly two columns. If TRUE, the values of the returned array will be one-element arrays instead of scalars.
if TRUE, the values of the returned array is wrapped in another array. If the same key value (in the first column) repeats itself, the values will be appended to this array instead of overwriting the existing values.
Таблица 34-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
MDB_ERROR_TRUNCATED | NULL | The result set contains fewer then two columns | Check the SQL fetch or choose another fetch*() function |
every other error code | Database specific error | Check the database related section of PHP-Manual to detect the reason for this error. In the most cases a misformed SQL statment. Ie. using LIMIT in a SQL-Statment for an Oracle database. |
query() , limitQuery() , prepareQuery() , executeQuery() , fetchRow() , fetchOne() , fetchCol()
a valid resource returned by query() or executeQuery()
if supplied, prepareQuery()/ executeQuery() will be used with this array as execute parameters
which column to return (integer [column number, starting at 0] or string [column name])
array - the first row of results as an array indexed from 0 or a MDB_Error, if fail
Таблица 34-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
MDB_ERROR_TRUNCATED | NULL | The result set contains fewer then two columns | Check the SQL query or choose another query*() function |
every other error code | Database specific error | Check the database related section of PHP-Manual to detect the reason for this error. In the most cases a misformed SQL statment. Ie. using LIMIT in a SQL-Statment for an Oracle database. |
query() , limitQuery() , prepareQuery() , executeQuery() , fetchRow() , fetchOne() , fetchAll()
Fetch the first column of the first row of data returned from a result set and free the result set.
Таблица 34-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
every other error code | Database specific error | Check the database related section of PHP-Manual to detect the reason for this error. In the most cases a misformed SQL statment. Ie. using LIMIT in a SQL-Statment for an Oracle database. |
query() , limitQuery() , prepareQuery() , executeQuery() , fetchRow() , fetchCol() , fetchCol()
a valid resource returned by query() or executeQuery()
the fetch mode to use, default is MDB_FETCHMODE_DEFAULT
the row number to fetch
array - the first row of results as an array indexed from 0 or a MDB_Error, if fail
Таблица 34-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
every other error code | Database specific error | Check the database related section of PHP-Manual to detect the reason for this error. In the most cases a misformed SQL statment. Ie. using LIMIT in a SQL-Statment for an Oracle database. |
result identifier
format of fetched row
the row number to fetch
Fetch the entire result set of a query and return it into a nested array. The function takes care of doing the query and freeing the results when finished.
the SQL query
if supplied, the types of the columns in the result set will be set for fetching
if supplied, prepareQuery()/ executeQuery() will be used with this array as execute parameters
if supplied, the values in $param will automatically set to the passed datatypes
the fetch mode to use, default is MDB_FETCHMODE_DEFAULT
Таблица 34-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
MDB_ERROR_INVALID | NULL | SQL statment for preparing is not valid. | See the prepareQuery() documentation, if you want to use a SQL statemt using wildcards. |
MDB_ERROR_NEED_MORE_DATA | NULL | To less data for filling the prepared SQL statment. | Check the number of wild cards given in the SQL statment prepareQuery() . Check the count of entries in the array for $params. The count of entries have to be equal to the number of wild cards. |
MDB_ERROR_NO_DB_SELECTED | NULL | No database was choosen. | Check the DSN in connect() . |
every other error code | Database specific error | Check the database related section of PHP-Manual to detect the reason for this error. In the most cases a misformed SQL statment. Ie. using LIMIT in a SQL-Statment for an Oracle database. |
query() , limitQuery() , prepareQuery() executeQuery() , getCol() , getRow() , getAssoc() , getOne()
Fetch the entire result set of a query and return it as an associative array using the first column as the key. The function takes care of doing the query and freeing the results when finished. If the result set contains more than two columns, the value will be an array of the values from column 2 to n. If the result set contains only two columns, the returned value will be a scalar with the value of the second column (unless forced to an array with the $force_array parameter).
the SQL query
if supplied, the types of the columns in the result set will be set for fetching
if supplied, prepareQuery()/ executeQuery() will be used with this array as execute parameters
if supplied, the values in $param will automatically set to the passed datatypes
the fetch mode to use
used only if the query returns exactly two columns. If TRUE, the values of the returned array will be one-element arrays instead of scalars.
if TRUE, the values of the returned array is wrapped in another array. If the same key value (in the first column) repeats itself, the values will be appended to this array instead of overwriting the existing values.
Таблица 34-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
MDB_ERROR_INVALID | NULL | SQL statment for preparing is not valid. | See the prepareQuery() documentation, if you want to use a SQL statemt using wildcards. |
MDB_ERROR_NEED_MORE_DATA | NULL | To less data for filling the prepared SQL statment. | Check the number of wild cards given in the SQL statment prepareQuery() . Check the count of entries in the array for $params. The count of entries have to be equal to the number of wild cards. |
MDB_ERROR_NO_DB_SELECTED | NULL | No database was choosen. | Check the DSN in connect() . |
MDB_ERROR_TRUNCATED | NULL | The result set contains fewer then two columns | Check the SQL query or choose another get*() function |
every other error code | Database specific error | Check the database related section of PHP-Manual to detect the reason for this error. In the most cases a misformed SQL statment. Ie. using LIMIT in a SQL-Statment for an Oracle database. |
Fetch a single column from a result set of a query. The function takes care of doing the query and freeing the results when finished.
the SQL query
if supplied, the type of the column in the result set will be set for fetching
if supplied, prepareQuery()/ executeQuery() will be used with this array as execute parameters
if supplied, the values in $param will automatically set to the passed datatypes
which column to return (integer [column number, starting at 0] or string [column name])
array - the first row of results as an array indexed from 0 or a MDB_Error, if fail
Таблица 34-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
MDB_ERROR_INVALID | NULL | SQL statment for preparing is not valid. | See the prepareQuery() documentation, if you want to use a SQL statemt using wildcards. |
MDB_ERROR_NEED_MORE_DATA | NULL | To less data for filling the prepared SQL statment. | Check the number of wild cards given in the SQL statment prepareQuery() . Check the count of entries in the array for $params. The count of entries have to be equal to the number of wild cards. |
MDB_ERROR_NO_DB_SELECTED | NULL | No database was choosen. | Check the DSN in connect() . |
MDB_ERROR_TRUNCATED | NULL | The result set contains fewer then two columns | Check the SQL query or choose another get*() function |
every other error code | Database specific error | Check the database related section of PHP-Manual to detect the reason for this error. In the most cases a misformed SQL statment. Ie. using LIMIT in a SQL-Statment for an Oracle database. |
query() , limitQuery() , prepareQuery() , executeQuery() , getRow() , getOne() , getAssoc()
Fetch the first column of the first row of data returned from a query. The function takes care of doing the query and freeing the results when finished.
the SQL query or the statement to prepare
if supplied, the type of the column in the result set will be set for fetching
if supplied, prepareQuery()/ executeQuery() will be used with this array as execute parameters
if supplied, the values in $param will automatically set to the passed datatypes
Таблица 34-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
MDB_ERROR_INVALID | NULL | SQL statment for preparing is not valid. | See the prepareQuery() documentation, if you want to use a SQL statemt using wildcards. |
MDB_ERROR_NEED_MORE_DATA | NULL | To less data for filling the prepared SQL statment. | Check the number of wild cards given in the SQL statment prepareQuery() . Check the count of entries in the array for $params. The count of entries have to be equal to the number of wild cards. |
MDB_ERROR_NO_DB_SELECTED | NULL | No database was choosen. | Check the DSN in connect() . |
every other error code | Database specific error | Check the database related section of PHP-Manual to detect the reason for this error. In the most cases a misformed SQL statment. Ie. using LIMIT in a SQL-Statment for an Oracle database. |
query() , limitQuery() , prepareQuery() , executeQuery() , getRow() , getCol() , getCol() , getCol()
Fetch the first row of data returned from a query. The function takes care of doing the query and freeing the results when finished.
the SQL query
if supplied, the types of the columns in the result set will be set for fetching
if supplied, prepareQuery()/ executeQuery() will be used with this array as execute parameters
if supplied, the values in $param will automatically set to the passed datatypes
the fetch mode to use, default is MDB_FETCHMODE_DEFAULT
array - the first row of results as an array indexed from 0 or a MDB_Error, if fail
Таблица 34-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
MDB_ERROR_INVALID | NULL | SQL statment for preparing is not valid. | See the prepareQuery() documentation, if you want to use a SQL statemt using wildcards. |
MDB_ERROR_NEED_MORE_DATA | NULL | To less data for filling the prepared SQL statment. | Check the number of wild cards given in the SQL statment prepareQuery() . Check the count of entries in the array for $params. The count of entries have to be equal to the number of wild cards. |
MDB_ERROR_NO_DB_SELECTED | NULL | No database was choosen. | Check the DSN in connect() . |
every other error code | Database specific error | Check the database related section of PHP-Manual to detect the reason for this error. In the most cases a misformed SQL statment. Ie. using LIMIT in a SQL-Statment for an Oracle database. |
Executes a SQL query, but fetches only the the specificed count of rows. It is an emulation of the MySQL LIMIT option.
the SQL query
if supplied, the types of the columns in the result set will be set for fetching
the row to start to fetch
the numbers of rows to fetch
Таблица 34-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
MDB_ERROR_NO_DB_SELECTED | NULL | No database was choosen. | Check the DSN in connect() . |
every other error code | Database specific error | Check the database related section of PHP-Manual to detect the reason for this error. In the most cases a misformed SQL statment. Ie. using LIMIT in a SQL-Statment for an Oracle database. |
Эта функция не должна вызываться статически.
Внимание |
Этот модуль является ЭКСПЕРИМЕНТАЛЬНЫМ. Это означает, что поведение его функций, имена функций и ВСЕ остальное может быть изменено в будущем без каких-либо уведомлений. Вы можете использовать этот модуль только на свой страх и риск. |
Depending on the database you will not really get more speed compared to query() . The advantage of limitQuery() is the deleting of unneeded rows in the resultset, as early as possible. So this can decrease memory usage.
name of the sequence
when TRUE the sequence is automatic created, if it not exists.
Таблица 34-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
MDB_ERROR_NOT_CAPABLE | NULL | Function is not supported by the database backend | Switch to another database system, if you really need this feature. |
MDB_ERROR_NOT_LOCKED | NULL | Locking of sequence table fails | Database specific, check documention of your database, |
MDB_ERROR_NOSUCHTABLE | NULL | Sequence table was not found | Try to create a new sequence or if you are sure, a sequence was already create, check database integrity |
Эта функция не должна вызываться статически.
See Introduction - Execute for general using and an example.
the SQL query
if supplied, the types of the columns in the result set will be set for fetching
Таблица 34-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
MDB_ERROR_NO_DB_SELECTED | NULL | No database was choosen. | Check the DSN in connect() . |
every other error code | Database specific error | Check the database related section of PHP-Manual to detect the reason for this error. In the most cases a misformed SQL statment. Ie. using LIMIT in a SQL-Statment for an Oracle database. |
Fetch the entire result set of a query and return it into a nested array. The function takes care of doing the query and freeing the results when finished.
the SQL query
if supplied, the types of the columns in the result set will be set for fetching
the fetch mode to use
if set to TRUE the array result be modified as follows: If the result set contains more than two columns, the value will be an array of the values from column 2 to n. If the result set contains only two columns, the returned value will be a scalar with the value of the second column (unless forced to an array with the $force_array parameter).
used only if the query returns exactly two columns. If TRUE, the values of the returned array will be one-element arrays instead of scalars.
if TRUE, the values of the returned array is wrapped in another array. If the same key value (in the first column) repeats itself, the values will be appended to this array instead of overwriting the existing values.
Таблица 34-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
MDB_ERROR_NO_DB_SELECTED | NULL | No database was choosen. | Check the DSN in connect() . |
MDB_ERROR_TRUNCATED | NULL | The result set contains fewer then two columns | Check the SQL query or choose another query*() function |
every other error code | Database specific error | Check the database related section of PHP-Manual to detect the reason for this error. In the most cases a misformed SQL statment. Ie. using LIMIT in a SQL-Statment for an Oracle database. |
query() , limitQuery() , prepareQuery() , executeQuery() , queryRow() , queryOne() , queryCol()
Fetch a single column from a result set of a query. The function takes care of doing the query and freeing the results when finished.
the SQL query
if supplied, the type of the column in the result set will be set for fetching
if supplied, prepareQuery()/ executeQuery() will be used with this array as execute parameters
if supplied, the values in $param will automatically set to the passed datatypes
which column to return (integer [column number, starting at 0] or string [column name])
array - the first row of results as an array indexed from 0 or a MDB_Error, if fail
Таблица 34-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
MDB_ERROR_NO_DB_SELECTED | NULL | No database was choosen. | Check the DSN in connect() . |
MDB_ERROR_TRUNCATED | NULL | The result set contains fewer then two columns | Check the SQL query or choose another query*() function |
every other error code | Database specific error | Check the database related section of PHP-Manual to detect the reason for this error. In the most cases a misformed SQL statment. Ie. using LIMIT in a SQL-Statment for an Oracle database. |
query() , limitQuery() , prepareQuery() , executeQuery() , queryRow() , queryOne() , queryAll()
Fetch the first column of the first row of data returned from a query. The function takes care of doing the query and freeing the results when finished.
the SQL query or the statement to prepare
if supplied, the type of the cell in the result set will be set for fetching
Таблица 34-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
MDB_ERROR_NO_DB_SELECTED | NULL | No database was choosen. | Check the DSN in connect() . |
every other error code | Database specific error | Check the database related section of PHP-Manual to detect the reason for this error. In the most cases a misformed SQL statment. Ie. using LIMIT in a SQL-Statment for an Oracle database. |
query() , limitQuery() , prepareQuery() , executeQuery() , queryRow() , queryCol() , queryCol()
Fetch the first row of data returned from a query. The function takes care of doing the query and freeing the results when finished.
the SQL query
if supplied, the types of the columns in the result set will be set for fetching
the fetch mode to use, default is MDB_FETCHMODE_DEFAULT
the row number to fetch
array - the first row of results as an array indexed from 0 or a MDB_Error, if fail
Таблица 34-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
MDB_ERROR_NO_DB_SELECTED | NULL | No database was choosen. | Check the DSN in connect() . |
every other error code | Database specific error | Check the database related section of PHP-Manual to detect the reason for this error. In the most cases a misformed SQL statment. Ie. using LIMIT in a SQL-Statment for an Oracle database. |
MDB_FETCHMODE_ORDEREDor MDB_FETCHMODE_ASSOC, all possibly bit-wise OR'ed with MDB_FETCHMODE_FLIPPED. See "Introduction - Fetch" for further information.
Таблица 34-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
NULL | invalid fetchmode mode | The given fetch mode does not exists or is not implement in your MDB_Error version. | Check writing of the argument and your used version of MDB. |
Returns an associative array of table and field information.
Внимание |
Эта функция не документирована на данный момент. |
In case of failure, most of the MDB functions return a MDB_Error object which contains information about the error. MDB_Error offers the same functions as PEAR_Error.
A unified API for accessing databases and constructing SQL in a portable way.
PEAR MDB2 is a merge of the PEAR DB and Metabase php database abstraction layers.
It provides a common API for all support RDBMS. The main difference to most other database abstraction packages is that MDB2 goes much further to ensure portability. Among other things MDB2 features:
An OO-style query API
A DSN (data source name) or array format for specifying database servers
Datatype abstraction and on demand datatype conversion
Portable error codes
Sequential and non sequential row fetching as well as bulk fetching
Ability to make buffered and unbuffered queries
Ordered array and associative array for the fetched rows
Prepare/execute (bind) emulation
Sequence emulation
Replace emulation
Limited Subselect emulation
Row limit support
Transactions support
Large Object support
Index/Unique support
Module Framework to load advanced functionality on demand
Table information interface
RDBMS management methods (creating, dropping, altering)
Full integration into the PEAR Framework
PHPDoc API documentation
Currently supported RDBMS:
MySQL
MySQLi (PHP5 only)
PostgreSQL
Oracle
Frontbase (unmaintained)
Querysim
Interbase/Firebird (PHP5 only)
MSSQL
SQLite
To connect to a database through PEAR::MDB2, you have to create a valid DSN - data source name. This DSN consists in the following parts:
phptype: Database backend used in PHP (i.e. mysql , pgsql etc.) |
dbsyntax: Database used with regards to SQL syntax etc. |
protocol: Communication protocol to use ( i.e. tcp, unix etc.) |
hostspec: Host specification (hostname[:port]) |
database: Database to use on the DBMS server |
username: User name for login |
password: Password for login |
proto_opts: Maybe used with protocol |
option: Additional connection options in URI query string format. options get separated by &. The Following table shows a non complete list of options: |
Таблица 34-1. List of options
Name | Description |
---|---|
charset | Some backends support setting the client charset. |
new_link | Some RDBMS do not create new connections when connecting to the same host multiple times. This option will attempt to force a new connection. |
The DSN can either be provided as an associative array or as a string. The string format of the supplied DSN is in its fullest form:
phptype(dbsyntax)://username:password@protocol+hostspec/database?option=value |
Most variations are allowed:
phptype://username:password@protocol+hostspec:110//usr/db_file.db phptype://username:password@hostspec/database phptype://username:password@hostspec phptype://username@hostspec phptype://hostspec/database phptype://hostspec phptype:///database phptype:///database?option=value&anotheroption=anothervalue phptype(dbsyntax) phptype |
The currently supported database backends are:
fbsql -> FrontBase ibase -> InterBase / Firebird (requires PHP 5) mssql -> Microsoft SQL Server (NOT for Sybase. Compile PHP --with-mssql) mysql -> MySQL mysqli -> MySQL (supports new authentication protocol) (requires PHP 5) oci8 -> Oracle 7/8/9/10 pgsql -> PostgreSQL querysim -> QuerySim sqlite -> SQLite 2 |
A second DSN format is supported
phptype(syntax)://user:pass@protocol(proto_opts)/database |
If your database, option values, username or password contain characters used to delineate DSN parts, you can escape them via URI hex encodings:
: = %3a / = %2f @ = %40 + = %2b ( = %28 ) = %29 ? = %3f = = %3d & = %26 |
Внимание |
Please note, that some features may be not supported by all database backends. |
Пример 34-1. Connect to database through a socket
|
Пример 34-2. Connect to database on a non standard port
|
Пример 34-3. Connect to SQLite on a Unix machine using options
|
Пример 34-4. Connect to SQLite on a Windows machine using options
|
Пример 34-5. Connect to MySQLi using SSL
|
To instantiate a database object you have several methods available using MDB2.
Таблица 34-1. Connection functions
Function | Summary | Description |
---|---|---|
factory() | Efficient | Will instantiate a new MDB2_Driver_Common instance, but will not connect to the database until required. This will delay making the actual connection. This is called lazy connecting. Using this makes sense if it is possible that due to caching inside the application no connection will ever need to be established. |
connect() | Eager | Will instantiate a new MDB2_Driver_Common instance, and will establish a database connection immediately. This way any connection issues will immediately raise an error. |
singleton() | Available | Returns a MDB2_Driver_Common instance. A new MDB2_Driver_Common object is only created once using factory(), subsequent calls to singleton will return a reference to the existing object. This method is preferred over declaring your database object as a global. |
$dsn = array( 'phptype' => false, 'dbsyntax' => false, 'username' => false, 'password' => false, 'protocol' => false, 'hostspec' => false, 'port' => false, 'socket' => false, 'database' => false, 'new_ink' => false, ); |
The second parameter is the optional $options array that can contain runtime configuration settings for this package.
Таблица 34-2. List of options
Name | Type | Description |
---|---|---|
ssl | boolean | determines if ssl should be used for connections |
field_case | integer | CASE_LOWER|CASE_UPPER: determines what case to force on field/table names |
disable_query | boolean | determines if queries should be executed |
result_class | string | class used for result sets |
buffered_result_class | string | class used for buffered result sets, default is MDB2_Result_Common |
result_wrap_class | string | class used to wrap result sets into, default is MDB2_Result_Common |
result_buffering | boolean | should results be buffered or not? |
fetch_class | string | class to use when fetch mode object is used |
persistent | boolean | persistent connection? |
debug | integer | numeric debug level |
debug_handler | string | function/method that captures debug messages |
debug_expanded_output | boolean | BC option to determine if more context information should be send to the debug handler |
default_text_field_length | integer | default text field length to use |
lob_buffer_length | integer | LOB buffer length |
log_line_break | string | line-break format |
idxname_format | string | pattern with '%s' for index name |
seqname_format | string | pattern with '%s' for sequence name |
savepoint_format | string | pattern with '%s' for auto generated savepoint names |
seqcol_name | string | sequence column name |
quote_identifier | boolean | if identifier quoting should be done when check_option is used |
use_transactions | boolean | if transaction use should be enabled |
decimal_places | integer | number of decimal places to handle |
portability | integer | portability constant |
modules | array | short to long module name mapping for __call() |
emulate_prepared | boolean | force prepared statements to be emulated |
datatype_map | array | map user defined datatypes to other primitive datatypes |
'datatype_map_callback | array | callback function/method that should be called |
In case of success you get a new instance of the database class. It is strongly recommened to check this return value with PEAR::isError() (will detect PEAR_Error or any subclass) or the MDB2_Driver_Common specific isError().
To disconnect use the method disconnect() from your database class instance.
Пример 34-1. Connect and disconnect
|
Пример 34-2. Connect using an array for the DSN information
When connecting to SQLite using a DSN array, the value of the mode element must be a string:
|
Пример 34-3. Connect to MySQLi via SSL using an array for the DSN information The ssl element of the $options array must be set to TRUE in order for SSL to work. Each of the extra elements in the $dsn array (key through cipher in the example below) are optional.
|
Пример 34-4. Connect to a PostgreSQL database via a socket
|
Пример 34-5. Connect using singleton
|
PEAR MDB2 provides several methods for querying databases. The most direct method is query(). It takes a SQL query string as an argument. There are two possible returns: A new MDB2_Result object for queries that return results (such as SELECT queries), or a MDB2_Error object on failure. It should not be used with statements that manipulate data (such as INSERT queries)
Пример 34-1. Doing a query
|
exec() should be used for manipulation queries. There are two possible returns: An integer denoting the number of affected rows for statements that manipulate data (such as INSERT queries), or a MDB2_Error object on failure. It should not be used with statements that return results (such as SELECT queries)
Пример 34-2. Using exec to manipulate data
|
MDB2 supports a number of data types across all drivers. These can be set for result sets in all relevant methods. You can find an overview of the supported data types and their format here.
In order to read/write to only a limited number of rows from a result set and/or to start reading from a specific offset the setLimit() can be called prior to issueing the query. The limit and offset will only affected the next method call that will issue a query or prepare a statement and will automatically be reset after issueing the query. This also applies to any internal queries issues inside MDB2. Note that limit may not work with DML statements on RDBMS that emulate limit support and no error will be raised.
Пример 34-3. Using setLimit with query and exec
|
MDB2 provides a quote() method to quote a value into a DBMS specific format that is suitable to compose query statements. It has four parameters (only the first one is required): the value to be quoted, its datatype, whether or not to quote the value, and whether or not to escape the wildcards in the value. If you don't provide the datatype, it will be guessed from the value.
Пример 34-1. Doing a query with quoted values
|
With the third parameter of the quote() you can specify whether or not the above fields should be individually quoted:
Пример 34-2. Individually choose the values to be quoted
|
The above example will quote the fields and the resulting SQL will look as such:
INSERT INTO sometable FIELDS (textfield1, boolfield2, datefield3) VALUES ('blah', 1, '2006-02-21') |
NB: If you use prepared statements, then quoting will be done automatically, you don't need to do it yourself.
You can quote the db identifiers (table and field names) with quoteIdentifier(). The delimiting style depends on which database driver is being used. NOTE: just because you CAN use delimited identifiers, it doesn't mean you SHOULD use them. In general, they end up causing way more problems than they solve. Anyway, it may be necessary when you have a reserved word as a field name (in this case, we suggest you to change it, if you can).
Some of the internal MDB2 methods generate queries. Enabling the "quote_identifier" option of MDB2 you can tell MDB2 to quote the identifiers in these generated queries. For all user supplied queries this option is irrelevant.
Portability is broken by using the following characters inside delimited identifiers:
backtick (`) -- due to MySQL
double quote (") -- due to Oracle
brackets ([ or ]) -- due to Access
Delimited identifiers are known to generally work correctly under the following drivers:
mssql
mysql
mysqli
oci8
pgsql
sqlite
Within the MDB2 API there are a number of options to set the quoting options, one of which simply quotes the identifiers within the abstraction, the other quotes the field values on insert/update etc. when using the prepared statements methods.
When using the quoteIdentifiers option, all of the field identifiers will be automatically quoted in the resulting SQL statements:
$mdb2->setOption('quote_identifiers', true); |
SELECT * FROM `sometable` WHERE `id` = '123'; |
SELECT * FROM sometable WHERE id='123'; |
If you want to escape a value, without surrounding it with quotes, you can use the escape() method. If you also want to escape the wildcards (_ and %), set the second parameter to TRUE
If you just want to escape the wildcards in a value, you can use the escapePattern() method.
All DBMS provide multiple choice of data types for the information that can be stored in their database table fields. However, the set of data types made available varies from DBMS to DBMS.
To simplify the interface with the DBMS supported by MDB2, it was defined a base set of data types that applications may access independently of the underlying DBMS.
The MDB2 applications programming interface takes care of mapping data types when managing database options. It is also able to convert that is sent to and received from the underlying DBMS using the respective driver.
The following data type examples should be used with MDB2's createTable() method. The example array at the end of the data types section may be used with createTable() to create a portable table on the DBMS of choice (please refer to the main MDB2 documentation to find out what DBMS back ends are properly supported). It should also be noted that the following examples do not cover the creation and maintenance of indices, this chapter is only concerned with data types and the proper usage thereof.
Within the MDB2 API there are a few modifiers that have been designed to aid in optimal table design. These are:
The notnull modifiers
The length modifiers
The default modifiers
unsigned modifiers for some field definitions, although not all DBMS's support this modifier for integer field types.
fixed length modifiers for some field definitions.
'sometime' = array( 'type' = 'time', 'default' = '12:34:05', 'notnull' = true, ), |
Пример 34-1. Example of the length modifier
|
The above example will create a character varying field of length 12 characters in the database table. If the length definition is left out, MDB2 will create a length of the maximum allowable length for the data type specified, which may create a problem with some field types and indexing. Best practice is to define lengths for all or most of your fields.
The text data type is available with two options for the length: one that is explicitly length limited and another of undefined length that should be as large as the database allows.
The length limited option is the most recommended for efficiency reasons. The undefined length option allows very large fields but may prevent the use of indexes, nullability and may not allow sorting on fields of its type.
The fields of this type should be able to handle 8 bit characters. Drivers take care of DBMS specific escaping of characters of special meaning with the values of the strings to be converted to this type.
By default MDB2 will use variable length character types. If fixed length types should be used can be controlled via the fixed modifier.
Пример 34-2. Example of text data type with length and fixed option
|
The boolean data type represents only two values that can be either 1 or 0. Do not assume that these data types are stored as integers because some DBMS drivers may implement this type with single character text fields for a matter of efficiency. Ternary logic is possible by using null as the third possible value that may be assigned to fields of this type.
Пример 34-3. Example of boolean data type
|
The integer data type may store integer values as large as each DBMS may handle. Fields of this type may be created optionally as unsigned integers but not all DBMS support it. Therefore, such option may be ignored. Truly portable applications should not rely on the availability of this option.
Пример 34-4. Example of integer data type
|
The decimal data type may store decimal numbers accurately with a fixed number of decimal places. This data type is suitable for representing accurate values like currency amounts.
Some DBMS drivers may emulate the decimal data type using integers. Such drivers need to know in advance how many decimal places that should be used to perform eventual scale conversion when storing and retrieving values from a database. Despite this, applications may use arithmetic expressions and functions with the values stored on decimal type fields as long as any constant values that are used in the expressions are also converted with the respective MDB2 conversion functions.
The number of places that are used to the left and the right of the decimal point is pre-determined and fixed for all decimal values stored in the same database. By default, MDB2 uses 2 places to the right of the decimal point, but this may be changed when setting the database connection. The number of places available to the right of the decimal point depend on the DBMS.
It is not recommended to change the number places used to represent decimal values in database after it is installed. MDB2 does not keep track of changes in the number of decimal places. The number of decimal places can be set using the setOption() method.
Пример 34-5. Example of decimal data type
|
The float data type may store floating point decimal numbers. This data type is suitable for representing numbers within a large scale range that do not require high accuracy. The scale and the precision limits of the values that may be stored in a database depends on the DBMS that it is used.
Пример 34-6. Example of float data type
|
The date data type may represent dates with year, month and day. DBMS independent representation of dates is accomplished by using text strings formatted according to the IS0-8601 standard.
The format defined by the ISO-8601 standard for dates is YYYY-MM-DD where YYYY is the number of the year (Gregorian calendar), MM is the number of the month from 01 to 12 and DD is the number of the day from 01 to 31. Months or days numbered below 10 should be padded on the left with 0.
Some DBMS have native support for date formats, but for others the DBMS driver may have to represent them as integers or text values. In any case, it is always possible to make comparisons between date values as well sort query results by fields of this type.
Пример 34-7. Example of date data type
|
The time data type may represent the time of a given moment of the day. DBMS independent representation of the time of the day is also accomplished by using text strings formatted according to the ISO-8601 standard.
The format defined by the ISO-8601 standard for the time of the day is HH:MI:SS where HH is the number of hour the day from 00 to 23 and MI and SS are respectively the number of the minute and of the second from 00 to 59. Hours, minutes and seconds numbered below 10 should be padded on the left with 0.
Some DBMS have native support for time of the day formats, but for others the DBMS driver may have to represent them as integers or text values. In any case, it is always possible to make comparisons between time values as well sort query results by fields of this type.
Пример 34-8. Example of time data type
|
The timestamp data type is a mere combination of the date and the time of the day data types. The representation of values of the time stamp type is accomplished by joining the date and time string values in a single string joined by a space. Therefore, the format template is YYYY-MM-DD HH:MI:SS. The represented values obey the same rules and ranges described for the date and time data types
Пример 34-9. Example of timestamp data type
|
The large object data types are meant to store data of undefined length that may be too large to store in text fields, like data that is usually stored in files.
MDB2 supports two types of large object fields: Character Large OBjects (CLOBs) and Binary Large OBjects (BLOBs). CLOB fields are meant to store only data made of printable ASCII characters. BLOB fields are meant to store all types of data.
Large object fields are usually not meant to be used as parameters of query search clause (WHERE) unless the underlying DBMS supports a feature usually known as "full text search"
Пример 34-10. Example of large object data types
|
Пример 34-11. Example of field definition
|
The above example will create a database table as such:
Таблица 34-1. PostgreSQL
Column | Type | Not Null | Default | comment |
---|---|---|---|---|
id | character(32) | |||
somename | character varying(12) | |||
somedate | date | |||
sometimestamp | timestamp without time zone | |||
someboolean | boolean | |||
somedecimal | numeric(18,2) | |||
somefloat | double precision | |||
sometime | time without time zone | NOT NULL | '12:34:05'::time without time zone | |
someclob | text | |||
someblob | bytea |
Таблица 34-2. MySQL
Field | Type | Collation | Attributes | Null | Default | comment |
---|---|---|---|---|---|---|
id | char(32) | YES | ||||
somename | varchar(12) | latin1_swedish_ci | YES | |||
somedate | date | YES | ||||
sometimestamp | timestamp without time zone | YES | ||||
someboolean | tinyint(1) | YES | ||||
somedecimal | decimal(18,2) | YES | ||||
somefloat | double | YES | ||||
sometime | time | NO | 12:34:05 | |||
someclob | longtext | latin1_swedish_ci | YES | |||
someblob | longblob | binary | YES |
Custom data types can be defined. This will be explored soon. For now you can refer to this blog post.
Further reading should be done at the following URL's: getTypeDeclaration, getDeclaration.
The MDB2_Result_Common object provides two methods for fetching data from rows of a result set: fetchOne(), fetchRow(), fetchCol() and fetchAll().
fetchRow() and fetchOne() read an entire row or a single field from a column respectively. The result pointer gets moved to the next row each time these methods are called. NULL is returned when the end of the result set is reached.
fetchAll() and fetchCol() read all rows in the result set and therefore move the result pointer to the end. While fetchAll() reads the entire row data, fetchCol() only reads a single column.
MDB2_Error is returned if an error is encountered.
Пример 34-1. Fetching a result set
|
The data from the row of a query result can be placed into one of three constructs: an ordered array (with column numbers as keys), an associative array (with column names as keys) or an object (with column names as properties).
MDB2_FETCHMODE_ORDERED (default)
Array ( [0] => 28 [1] => hi ) |
MDB2_FETCHMODE_ASSOC
Array ( [a] => 28 [b] => hi ) |
MDB2_FETCHMODE_OBJECT
stdClass Object ( [a] => 28 [b] => hi ) |
NOTE: When a query contains the same column name more than once (such as when joining tables which have duplicate column names) and the fetch mode is MDB2_FETCHMODE_ASSOC or MDB2_FETCHMODE_OBJECT, the data from the last column with a given name will be the one returned. There are two immediate options to work around this issue:
Use aliases in your query, for example People.Name AS PersonName |
Change the fetch mode to MDB2_FETCHMODE_ORDERED |
TIP: If you are running into this issue, it likely indicates poor planning of the database schema. Either data is needlessly being duplicated or the same names are being used for different kinds of data.
You can set the fetch mode each time you call a fetch method and/or you can set the default fetch mode for the whole MDB2 instance by using the setFetchMode() method.
Пример 34-2. Determining fetch mode per call
|
Пример 34-3. Changing default fetch mode
|
The PEAR MDB2 fetch system also supports an extra parameter to the fetch statement. So you can fetch rows from a result by number. This is especially helpful if you only want to show sets of an entire result (for example in building paginated HTML lists), fetch rows in an special order, etc.
Пример 34-4. Fetching by number
|
The MDB2_Result_Common object provides several methods to read entire results sets: fetchCol() and fetchAll().
Once you finish using a result set, if your script continues for a while, it's a good idea to save memory by freeing the result set via Use free().
Пример 34-5. Freeing
|
If whatever data you need to read from a result set is not yet implemented in MDB2 you can get the native result resource using the getResource() method and then call the underlying PHP extension directly (though this would of course require that it is now up to you to make this sufficiently portable).
Пример 34-6. Native result resource
|
With MDB2 there are four ways to retrieve useful information about the query result sets themselves:
Пример 34-7. numRows() tells how many rows are in a SELECT query result
|
Пример 34-8. numCols() tells how many columns are in a SELECT query result
|
Пример 34-9. rowCount() tells which row number the internal result row pointer currently points to
|
Пример 34-10. getColumnNames() returns an associative array with the names of the column of the result set as keys and the position inside the result set as the values
|
Пример 34-11. seek() allows to seek to a specific row inside a result set. Note that seeking to previously read rows is only possible if the 'result_buffering' option is left enabled, otherwise only forward seeking is supported.
|
Пример 34-12. nextResult() allows iterate over multiple results returned by a multi query.
|
Пример 34-13. bindColumn() allows to bind a reference to a user variable to a specific field inside the result set. This means that when fetching the next row, this variable is automatically updated.
|
All of the fetch methods are also available in a variant that executes a query directly: queryOne(), queryRow(), queryCol() and queryAll().
Пример 34-14.
|
Users that prefer to use prepared statements can make use of the following methods from the Extended module: getOne(), getRow(), getCol(), getAll() and getAssoc().
Пример 34-15.
|
MDB2 supports a number of data types across all drivers. These can be set for result sets at query or prepare time or using the setResultTypes() method. You can find an overview of the supported data types and their format here.
To retrieve a Large Object (BLOB or CLOB), you can use streams, as you were reading a file
Пример 34-16. Fetching LOBs with streams.
|
Don't forget to use isError() to check if your actions return a MDB2_Error object.
prepare() and execute() give you more power and flexibilty for query execution. Prepare/execute mode is helpful when you have to run the same query several times but with different values in it, such as adding a list of addresses into a database.
Another place prepare/execute is useful is supporting databases which have different SQL syntaxes. Imagine you want to support two databases with different INSERT syntax:
db1: INSERT INTO tbl_name (col1, col2) VALUES (expr1, expr2) db2: INSERT INTO tbl_name SET col1=expr1, col2=expr2 |
$statement['db1']['INSERT_PERSON'] = 'INSERT INTO person (surname, name, age) VALUES (?, ?, ?)'; $statement['db2']['INSERT_PERSON'] = 'INSERT INTO person SET surname=?, name=?, age=?'; |
$statement['db1']['INSERT_PERSON'] = 'INSERT INTO person (surname, name, age) VALUES (:surname, :lastname, :age)'; $statement['db2']['INSERT_PERSON'] = 'INSERT INTO person SET surname=:surname, name=:lastname, age=:age'; |
To use the features above, you have to do two steps. Step one is to prepare the statement which returns an instance of the MDB2_Statement_Common class. The second step is to execute it.
To start out, you need to prepare() a generic SQL statment. Create a generic statment by writing the SQL query as usual:
SELECT surname, name, age FROM person WHERE name = 'name_to_find' AND age < age_limit |
SELECT surname, name, age FROM person WHERE name = ? AND age < ? |
prepare() can handle different types of placeholders (a.k.a. wildcards). By default all placeholders are handled as strings. However passing an array of data types as the second parameter makes it possible to set a specific type for each placeholder.
Since DML (data manipulation language - INSERT, UPDATE, DELETE) statements have different return values than data fetches the prepare() accepts a third parameter. This parameter should be set to MDB2_PREPARE_MANIP for DML statements. For data reads it should either be set to MDB2_PREPARE_RESULT, an array of data types for each of the columns in the result set or TRUE in order to automatically detect the data types in the result set.
After preparing the statement, you can execute the query. This means to assign the variables to the prepared statement. To do this, execute() requires one argument a scalar or array with the values to assign.
Пример 34-1. Passing scalars to execute()
|
When a prepared statement has multiple placeholders, you must use an array to pass the values to execute(). The first entry of the array represents the first placeholder, the second the second placeholder, etc. The order is independent of the type of placeholder used.
Пример 34-2. Passing an array to execute()
|
When using named placeholders the data array needs to be an associative array with the keys matching the placeholder names.
Пример 34-3. Passing an array to execute()
|
When using named placeholders the data array needs to be an associative array with the keys matching the placeholder names.
Пример 34-4. Passing an array to execute()
|
Внимание |
The values passed in $data must be literals. Do not submit SQL functions (for example CURDATE()). SQL functions that should be performed at execution time need to be put in the prepared statement. Similarly, identifiers (i.e. table names and column names) can not be used because the names get validated during the prepare phase. |
MDB2 contains a process for executing several queries at once. So, rather than having to execute them manually, like this:
Пример 34-5. Passing arrays to execute()
|
INSERT INTO numbers VALUES ('1', 'one', 'en') INSERT INTO numbers VALUES ('2', 'two', 'to') INSERT INTO numbers VALUES ('3', 'three', 'tre') INSERT INTO numbers VALUES ('4', 'four', 'fire') |
Пример 34-6. Using executeMultiple() from the Extended Module instead of execute()
|
The result is the same. If one of the records failed, the unfinished records will not be executed.
execute() has three possible returns: a new MDB2_Result_Common object for queries that return results (such as SELECT queries), integer for queries that manipulate data (such as INSERT queries) or a MDB2_Error object on failure
MDB2 supports a number of data types across all drivers. These can be set for prepared placeholders as well as result sets in all relevant methods. You can find an overview of the supported data types and their format here.
Once you finish using prepared statements, if your script continues for a while, it's a good idea to save memory by freeing the prepared statement set via Use free().
Пример 34-7. Freeing
|
In order to read/write to only a limited number of rows from a result set and/or to start reading from a specific offset, the setLimit() can be called prior to calling prepare(). The limit and offset will only affect the next method call that will issue a query or prepare a statement and will automatically be reset after issuing the query. This also applies to any internal queries issued inside MDB2. Note that limit may not work with DML statements on RDBMS that emulate limit support and no error will be raised.
Пример 34-8. Using setLimit with prepare
|
PEAR MDB2 default to auto commiting all queries. However using the beginTransaction() one can open a new transaction and with the commit() and rollback() a transaction is finished. All of these three methods optionally accept a string name of a savepoint to set, release or rollback to respectively. The method inTransaction() may be used to check if a transaction is currently open.
Пример 34-1. Doing a transaction
|
Внимание |
PEAR MDB2 does not emulate transactions or savepoints. This means that it depends on the underlying RDBMS (and in the case of MySQL the storage engines used) if transactions will be available in MDB2. Also note that some RDBMS implicitly commit transactions when executing DDL statements (notably exceptions are Oracle and PostgreSQL). |
MDB2 also supports "nested" transactions using the beginNestedTransaction() method. Actually these are not true nested transactions as they are natively supported in Interbase for example. MDB2 maintains a counter of opened nested transactions. The transaction is finished once that counter is decremented back to 1 with completeNestedTransaction() calls. If the RDBMS supports savepoints then MDB2 will automatically set a savepoint on every call of the beginNestedTransaction() method after the initial call and will return the name. These savepoints are automatically released by the completeNestedTransaction() method. The name of these automatic savepoints are determined by the "savepoint_format" (default: 'MDB2_SAVEPOINT_%s') option and the nested transaction counter.
If after initial opening of the nested transaction an unexpected PEAR error is raised on the MDB2 instance the transaction is rolled back, otherwise it is commited at this point. Using the getNestedTransactionError() method it is possible to check if there has been an error inside the transaction. Alternatively an rollback can be forced using the the failNestedTransaction(). This method optionally accepts a mixed parameter which will set the error to return if the getNestedTransactionError() method is called as well as a second boolean parameter that optionally forces an immidiate rollback.
Пример 34-2. Using emulated nested transactions
|
Finally MDB2 supports setting of the transaction isolation level as per the SQL 92 standard using the setTransactionIsolation() method. If a given RDBMS does not support a given isolation level but supports a higher more strict isolation level, then MDB2 silently uses that higher transaction level. Some RDBMS support additional options which are silently ignored if they are not supported.
Пример 34-3. Setting the transaction isolation level
|
MDB2 follows a modular concept to provide functionality beyond the basic ability to send queries to the database and fetch result sets. Currently the following modules are available:
Datatype module - handles datatype abstraction via the MDB2_Datatype_Common class
Extended module - provides numerous high-level methods via the MDB2_Extended class
Function module - handles SQL function abstraction via the MDB2_Function_Common class
Manager module - handles data definition language (DDL) abstraction and schema listing via the MDB2_Manager_Common class
Native module - handles RDBMS specific functions via the MDB2_Native_Common class
Reverse module - handles schema reverse engineering abstraction via the MDB2_Reverse_Common class
A module is loaded using the loadModule() method. This method returns the module instance, but also stores the instance in a property. The name of the property is either the lowercased name of the module passed in as the first parameter, or optionally the non null value of the second parameter. The optional third parameter is used to differentiate modules that depend on a specific RDBMS (like the Datatype module) and those that do not (like the Extended module). The method can also be used to load custom modules that are installed.
Внимание |
The third parameter is automatically detected if it is not set. On hosts that have 'safe_mode' enabled automatic detection does however require silenced falls to fopen(). Error handling and error handlers should be configured accordingly. |
Пример 34-1. Loading a module
|
Пример 34-2. Loading a custom module that is RDBMS independent
|
Пример 34-3. Loading a custom module that is RDBMS dependent
|
Пример 34-4. Using a loaded module
|
On PHP5 users can also rely on overloading to load and call modules.
Пример 34-5. Using the 'modules' option with PHP5 overloading
|
Пример 34-6. Calling a method on a loaded module with PHP5 overloading
|
autoPrepare() and autoExecute() reduce the need to write boring INSERT, UPDATE, DELETE or SELECT SQL queries which are difficult to maintain when you add a field for instance. It requires the use of the Extended module
Imagine you have a 'user' table with 3 fields (id, name and country). You have to write sql queries like:
INSERT INTO table (id, name, country) VALUES (?, ?, ?) UPDATE table SET id=?, name=?, country=? WHERE ... |
With autoPrepare(), you don't have to write your insert, update, delete or select queries. For example:
<?php // Once you have a valid MDB2 object named $mdb2... $table_name = 'user'; $table_fields = array('id', 'name', 'country'); $types = array('integer', 'text', 'text'); $mdb2->loadModule('Extended'); $sth = $mdb2->extended->autoPrepare($table_name, $table_fields, MDB2_AUTOQUERY_INSERT, null, $types); if (PEAR::isError($sth)) { die($sth->getMessage()); } ?> |
INSERT INTO user (id, name, country) VALUES (?, ?, ?) |
To add records, you have to use execute() or executeMultiple() like:
<?php // ... continuing from the example above... $table_values = array(1, 'Fabien', 'France'); $res =& $sth->execute($table_values); if (PEAR::isError($res)) { die($res->getMessage()); } ?> |
<?php // Once you have a valid MDB2 object named $mdb2... $table_name = 'user'; $mdb2->loadModule('Extended'); $sth = $mdb2->extended->autoPrepare($table_name, null, MDB2_AUTOQUERY_DELETE, 'id = '.$mdb2->quote(1, 'integer')); if (PEAR::isError($sth)) { die($sth->getMessage()); } $res =& $sth->execute($table_values); if (PEAR::isError($res)) { die($res->getMessage()); } ?> |
UPDATE user SET name=?, country=? WHERE id=1 |
Be careful, if you don't specify any WHERE clause, all the records of the table will be updated.
Using autoExecute() is the easiest way to do insert, update, delete or select queries. It is a mix of autoPrepare() and execute().
You only need an associative array (key => value) where keys are fields names and values are corresponding values of these fields. This is only relevant for insert and update queries. For instance:
<?php // Once you have a valid MDB2 object named $mdb2... $table_name = 'user'; $fields_values = array( 'id' => 1, 'name' => 'Fabien', 'country' => 'France' ); $types = array('integer', 'text', 'text'); $mdb2->loadModule('Extended'); $affectedRows = $mdb2->extended->autoExecute($table_name, $fields_values, MDB2_AUTOQUERY_INSERT, null, $types); if (PEAR::isError($affectedRows)) { die($affectedRows->getMessage()); } ?> |
INSERT INTO user (id, name, country) VALUES (1, 'Fabien', 'France') |
And it's the same thing for UPDATE queries:
<?php // Once you have a valid MDB2 object named $mdb2... $table_name = 'user'; $fields_values = array( 'name' => 'Fabien', 'country' => 'France' ); $types = array('text', 'text'); $mdb2->loadModule('Extended'); $affectedRows = $mdb2->extended->autoExecute($table_name, $fields_values, MDB2_AUTOQUERY_UPDATE, 'id = '.$mdb2->quote(1, 'integer'), $types); if (PEAR::isError($affectedRows)) { die($affectedRows->getMessage()); } ?> |
UPDATE user SET name='Fabien', country='France' WHERE id = 1 |
Be careful, if you don't specify any WHERE statement, all the records of the table will be updated.
Here is an example for a DELETE queries:
<?php // Once you have a valid MDB2 object named $mdb2... $table_name = 'user'; $mdb2->loadModule('Extended'); $affectedRows = $mdb2->extended->autoExecute($table_name, null, MDB2_AUTOQUERY_DELETE, 'id = '.$mdb2->quote(1, 'integer')); if (PEAR::isError($affectedRows)) { die($affectedRows->getMessage()); } ?> |
DELETE FROM user WHERE id = 1 |
Finally an example for a SELECT queries:
<?php // Once you have a valid MDB2 object named $mdb2... $table_name = 'user'; // if left as a non array all fields of the table will be fetched using '*' // in that case this variable can be set to true, to autodiscover the types $result_types = array( 'name' => 'text', 'country' => 'text' ); $mdb2->loadModule('Extended'); $res = $mdb2->extended->autoExecute($table_name, null, MDB2_AUTOQUERY_SELECT, 'id = '.$mdb2->quote(1, 'integer'), null, true, $result_types); if (PEAR::isError($res)) { die($res->getMessage()); } $row = $res->fetchRow(); ?> |
SELECT name, country FROM user WHERE id = 1 |
Внимание |
The values passed in $data must be literals. Do not submit SQL functions (for example CURDATE()). SQL functions that should be performed at execution time need to be put in the prepared statement. |
Each database management system (DBMS) has it's own behaviors. For example, some databases capitalize field names in their output, some lowercase them, while others leave them alone. These quirks make it difficult to port your scripts over to another server type. PEAR MDB2 strives to overcome these differences so your program can switch between DBMS's without any changes.
You control which portability modes are enabled by using the portability configuration option. Configuration options are set via factory() and setOption().
The portability modes are bitwised, so they can be combined using | and removed using ^. See the examples section below on how to do this.
MDB2_PORTABILITY_ALL (default)
turn on all portability features. this is the default setting.
MDB2_PORTABILITY_DELETE_COUNT
Force reporting the number of rows deleted. Some DBMS's don't count the number of rows deleted when performing simple DELETE FROM tablename queries. This mode tricks such DBMS's into telling the count by adding WHERE 1=1 to the end of DELETE queries.
MDB2_PORTABILITY_EMPTY_TO_NULL
Convert empty strings values to null in data in and output. Needed because Oracle considers empty strings to be null, while most other DBMS's know the difference between empty and null.
MDB2_PORTABILITY_ERRORS
Makes certain error messages in certain drivers compatible with those from other DBMS's
Таблица 34-1. Error Code Re-mappings
Driver | Description | Old Constant | New Constant |
---|---|---|---|
mysql, mysqli | unique and primary key constraints | MDB2_ERROR_ALREADY_EXISTS | MDB2_ERROR_CONSTRAINT |
mysql, mysqli | not-null constraints | MDB2_ERROR_CONSTRAINT | MDB2_ERROR_CONSTRAINT_NOT_NULL |
MDB2_PORTABILITY_FIX_ASSOC_FIELD_NAMES
This removes any qualifiers from keys in associative fetches. Some RDBMS, for example SQLite, will default to use the fully qualified name for a column in assoc fetches if it is qualified in a query.
MDB2_PORTABILITY_FIX_CASE
Convert names of tables and fields to lower or upper case in all methods. The case depends on the 'field_case' option that may be set to either CASE_LOWER (default) or CASE_UPPER
MDB2_PORTABILITY_NONE
Turn off all portability features
MDB2_PORTABILITY_NUMROWS
Enable hack that makes numRows() work in Oracle
MDB2_PORTABILITY_RTRIM
Right trim the data output for all data fetches. This does not apply to drivers for RDBMS that automatically right trim values of fixed length character values, even if they do not right trim value of variable length character values.
Пример 34-1. Disabling all portability options while connecting
|
Пример 34-2. Using setOption() to enable portability for lowercasing and trimming
|
Пример 34-3. Using setOption() to enable all portability options except trimming
|
Sequences are a way of offering unique IDs for data rows. If you do most of your work with e.g. MySQL, think of sequences as another way of doing AUTO_INCREMENT.
It's quite simple, first you request an ID, and then you insert that value in the ID field of the new row you're creating. You can have more than one sequence for all your tables, just be sure that you always use the same sequence for any particular table. To get the value of this unique ID use nextID(), if a sequence doesn't exists, it will be created automatically.
The sequence is automatically incremented each time nextID() is called.
Пример 34-1. Using a sequence
|
Внимание |
When using PEAR MDB2's sequence methods, we strongly advise using these methods for all procedures, including the creation of the sequences. Do not use PEAR MDB2's methods to access sequences that were created directly in the DBMS. If you have a compelling reason to ignore this advice, be aware that the $seq_name argument given to all of PEAR MDB2's sequence methods are modified before MDB2 calls the underlying DBMS. $seq_name is passed through PHP's sprintf() function using the value from the seqname_format option as sprintf()'s format argument. The default seqname_format is %s_seq. So, for example, if you use person_id_sequence as the $seq_name, PEAR MDB2 will change that name to person_id_sequence_seq when querying the DBMS about creating/accessing/updating the sequence. Also note that the default table layout for sequences emulated in PEAR DB is slightly different in PEAR MDB2. Where PEAR DB calls the column "id" PEAR MDB2 instead calls it "sequence" to make its purpose more clear. For backward compatibility this can be controlled via the seqcol_name option. The seqname_format and seqcol_name can be modified when connecting or via setOption(). |
If you prefer using AUTO_INCREMENT you can alternatively use the lastInsertID() method to retrieve the last generated value. This method alternatively also supports getting the current ID from a sequence using the format defined in PostgreSQL's SERIAL data type. MDB2 can emulate this behaviour for RDBMS that do not support autoincrement at table creation time when using the createTable() method.
Пример 34-2. Using lastInsertID()
|
If you can get the current global value of a sequence using the currID() method.
Пример 34-3. Using currID()
|
Finally if you prefer using what ever native feature the RDBMS supports you can use the getBeforeID() and getAfterID() methods from the Extended module. This way MDB2 will automatically use AUTO_INCREMENT if its natively supported. If not MDB2 will instead use a sequence to get the next id.
Пример 34-4. Using getBeforeID()/getAfterID()
|
If you get a PEAR_Error (or a MDB2_Error object), try using getMessage() and getUserInfo(). They do often give you more information about the cause of the error.
If you get this error after creating the MDB2 instance it means that you don't have any MDB2 database driver installed. Since most people use only one database system, it is unnecessary to install 15 driver files.
If SQLite is the database of your choice, do a pear install MDB2_Driver_sqlite and it should work.
Also search for MDB2 drivers in the PEAR package list.
If you get this error when trying to install a driver it means that the php.ini loaded in the given installer does not see the "XXX" extension. Either you forgot to install the extension all together or you need to make sure that the extension is actived in all relevant php.ini files. Note that there are usually separate php.ini files for the CLI and your other SAPIs.
If all else failes do pear install -nodeps MDB2_Driver_XXX and it should work.
This package is an OO-abstraction to the SQL-Query language, it provides methods such as setWhere, setOrder, setGroup, setJoin, etc. to easily build queries.
This package is an OO-abstraction to the SQL-Query language, it provides methods such as setWhere, setOrder, setGroup, setJoin, etc. to easily build queries. It also provides an easy to learn interface that interacts nicely with HTML-forms using arrays that contain the column data, that shall be updated/added in a DB. This package bases on an SQL-Builder which lets you easily build SQL-Statements and execute them. It supports all the db engines supported by MDB.
Since it's a 1:1 port of DB_QueryTool, it has the same API, the only difference being the class name (and the constructor name, of course). Unfortunately, complete documentation is not available at the moment.
The best way to use MDB_QueryTool is creating a class that extends it. Here's a sample usage:
require_once 'MDB/QueryTool.php'; define('TABLE_CARS', 'cars'); $dsn = 'mysql://user:pass@host/dbname'; /** * Let's suppose the "car" table has the following fields: * (id, model, hp, color, clima, price) */ class Car extends MDB_QueryTool { var $table = TABLE_CARS; var $sequenceName = TABLE_CARS; // this is default, but to demonstrate it here ... var $primaryCol = 'id'; /** * This table spec assigns a short name to a table name * this short name is needed in case the table name changes * i.e. when u put the application on a provider's db, where you have to * prefix each table, and you dont need to change the entire application to * where you refer to joined table columns, for that joined results the * short name is used instead of the table name */ var $tableSpec = array( array('name' => TABLE_CARS, 'shortName' => 'cars'), //array('name' => TABLE_TIME, 'shortName' => 'time'), ); } //instanciate an object of the Car class $car = new Car($dsn); //get the car #3 $car->reset(); // reset the query-builder, so no where, order, etc. are set $res = $car->get(3); var_dump($res); //get all the cars $car->reset(); // reset the query-builder, so no where, order, etc. are set $res = $car->getAll(); var_dump($res); // get the first 10 cars $car->reset(); // reset the query-builder, so no where, order, etc. are set $res = $car->getAll(0, 10); var_dump($res); //get all the red cars with clima, sorted by price $car->reset(); $car->setWhere('color="red"'); $car->setWhere('clima=1'); $car->setOrder('price'); $res = $car->getAll(); var_dump($res); //add a new car to the database $data = array( 'model' => 'Super Trooper', 'hp' => 140, 'color' => 'black', 'clima' => 0, 'price' => 19000 ); $newCarId = $car->save($data); var_dump($newCarId); //update an existing car $data = array( 'id' => $newCarId, 'clima' => 1, 'price' => 20000, ); $res = $car->save($data); //equivalent to $car->update($data); var_dump($res); //remove the car from the database $res = $car->remove($newCarId); var_dump($res); |
MDB_QueryTool also offers working with classes. Here's a sample usage:
require_once 'MDB/QueryTool.php'; define('TABLE_CARS', 'cars'); $dsn = 'mysql://user:pass@host/dbname'; /** * Let's suppose the "car" table has the following fields: * (id, model, hp, color, clima, price) */ class Car extends MDB_QueryTool { var $table = TABLE_CARS; var $sequenceName = TABLE_CARS; // this is default, but to demonstrate it here ... var $primaryCol = 'id'; /** * This table spec assigns a short name to a table name * this short name is needed in case the table name changes * i.e. when u put the application on a provider's db, where you have to * prefix each table, and you dont need to change the entire application to * where you refer to joined table columns, for that joined results the * short name is used instead of the table name */ var $tableSpec = array( array('name' => TABLE_CARS, 'shortName' => 'cars'), //array('name' => TABLE_TIME, 'shortName' => 'time'), ); } //instanciate an object of the Car class $car = new Car($dsn); $car->useResult('object'); //get the car #3 $car->reset(); // reset the query-builder, so no where, order, etc. are set $res = $car->get(3)->fetchRow(); var_dump($res); //get all the cars $car->reset(); // reset the query-builder, so no where, order, etc. are set $cars = $car->getAll(); while ($res = $cars->getNext()) { var_dump($res); } // get the first 10 cars $car->reset(); // reset the query-builder, so no where, order, etc. are set $cars = $car->getAll(0, 10); while ($res = $cars->getNext()) { var_dump($res); } //get all the red cars with clima, sorted by price $car->reset(); $car->setWhere('color="red"'); $car->setWhere('clima=1'); $car->setOrder('price'); $cars = $car->getAll(); while ($res = $cars->getNext()) { var_dump($res); } //add a new car to the database $newCar = $car->newEntity(); $newCar->model = 'Super Trooper'; $newCar->hp = 140; $newCar->color = 'black'; $newCar->clima = 0; $newCar->price = 19000; $newCarId = $newCar->save(); var_dump($newCarId); //update an existing car $car->reset(); $res = $car->get($newCarId)->fetchRow(); $res->clima = 1; $res->price = 20000; $res->save(); var_dump($res); //remove the car from the database $car->reset(); $res = $car->get($newCarId)->fetchRow(); var_dump($res->remove()); unset($res); |
It is possible to use Objects as result. A comprehensive example may be seen in the intro.
But using objects is not a simple alternative to using arrays as result. It is also possible to register an own Class to be resulted instead of the default MDB_QueryTool_Result_Row. The new resulting class has to be child of the MDB_QueryTool_Result_Row class.
To change the resulting class the method setReturnClass is used.
require_once 'MDB/QueryTool.php'; require_once 'MDB/QueryTool/Result/Object.php'; define('TABLE_CARS', 'cars'); $dsn = 'mysql://user:pass@host/dbname'; /** * Let's suppose the "cars" table has the following fields: * (id, model, hp, color, clima, price) */ class Car extends MDB_QueryTool { public $table = TABLE_CARS; } class CarEntity extends MDB_QueryTool_Result_Row { } //instanciate an object of the Car class $car = new Car($dsn); $car->useResult('object'); $car->setReturnClass('CarEntity'); |
This can now be used to implement getter and setter and thus regulate the accessability to the values. In order to block the access to the class variables from outside they have to be declared as protected. Declaring them as private would result in also blocking the parent class, which gets the data, of accessing them. Of course when doing so corresponding methods have to be implemented to access the variables again.
To keep the example short only methods for dealing with model, hp and clima have been implemented.
require_once 'MDB/QueryTool.php'; require_once 'MDB/QueryTool/Result/Object.php'; define('TABLE_CARS', 'cars'); $dsn = 'mysql://user:pass@host/dbname'; /** * Let's suppose the "cars" table has the following fields: * (id, model, hp, color, clima, price) */ class Car extends MDB_QueryTool { public $table = TABLE_CARS; } class CarEntity extends MDB_QueryTool_Result_Row { protected $id; protected $model; protected $hp; protected $color; protected $clima; protected $price; public function getModel() { return $this->model; } public function setModel($model) { $this->model = $model; } public function getHp() { return $this->hp; } public function setHp($hp) { $this->hp = $hp; } public function getClima() { if ($this->clima) { return true; } else { return false; } } public function setClima($clima) { if ($clima) { $this->clima = 1; } else { $this->clima = 0; } } } //instantiate an object of the Car class $car = new Car($dsn); $car->useResult('object'); $car->setReturnClass('CarEntity'); |
This example only demonstrates a very basic feature. But it enables for example the implementation of Decorators. Every feature of modern OOP is now possible to implement.
MDB_QueryTool provides the following methods:
autoJoin($tables)
Join the given tables, using the column names, to find out how to join the tables; i.e., if table1 has a column named "table2_id", this method will join "WHERE table1.table2_id=table2.id". All joins made here are only concatenated via AND.
getDbInstance
Return a PEAR::DB object
setDbInstance
Pass an existing PEAR::DB object to MDB_QueryTool
get($id, $column)
Get the data of a single entry. If the second parameter is only one column, the result will be returned directly, not as an array!
getMultiple($ids, $column)
Same as get(), but for all the elements in the $ids array.
getAll()
Get all the entries from the db.
getCol($column)
This method only returns one column, so the result will be a one dimensional array. This does also mean that using setSelect() should be set to *one* column, the one you want to have returned. A common use case for this could be:
$table->setSelect('id'); $ids = $table->getCol(); //OR $ids = $table->getCol('id'); |
getCount()
Get the number of entries.
getDefaultValues()
return an empty element where all the array elements do already exist corresponding to the columns in the DB
getQueryString()
Render the current query and return it as a string.
save($data)
Save data, calls either update() or add(). If the primaryCol is given in the data this method knows that the data passed to it are meant to be updated (call update()), otherwise it will call the method add(). If you dont like this behaviour simply stick with the methods add() and update() and ignore this one here. This method is very useful when you have validation checks that have to be done for both adding and updating, then you can simply overwrite this method and do the checks in here, and both cases will be validated first.
update($data)
Update the member data of a data set.
add($data)
Add a new member in the db.
addMultiple($data)
Adds multiple new members in the db.
remove($data, $whereCol)
Removes a member from the db. data is the value of the column that shall be removed (integer/string); if an array is used, it must contain multiple columns that shall be matched (in this case, the second parameter will be ignored); $whereCol: the column to match the data against, only if data is not an array
removeAll()
Empty a table.
removeMultiple($ids, $colName)
Remove the datasets with the given ids. If colName is set, it is used as the primary key column name.
removePrimary($ids, $colName, $atLeastOneObject)
Removes a member from the db and calls the remove() methods of the given objects so all rows in another table that refer to this table are erased too.
setLimit($from=0, $count=0)
Set the limits for the following query.
getLimit()
Get the limits for the following query.
setWhere($whereCondition)
Sets the where condition which is used for the current instance.
getWhere()
Gets the where condition which is used for the current instance.
addWhere($whereCondition, $condition)
Adds a string to the where clause. The default condition is AND.
addWhereSearch($column, $stringToSearch, $condition)
Add a where-like clause which works like a search for the given string; i.e. calling it like this:
$this->addWhereSearch('name', 'otto hans') |
UPPER(name) LIKE "%OTTO%HANS%" |
setOrder($orderCondition, $desc=FALSE)
Sets the order condition which is used for the current instance.
getOrder()
Gets the order condition which is used for the current instance.
addOrder($orderCondition, $desc=FALSE)
Adds an order parameter to the query.
setHaving($havingCondition)
Sets the having condition which is used for the current instance.
getHaving()
Gets the having condition which is used for the current instance.
addHaving($what, $connectString)
Adds an having parameter to the query.
setJoin($table, $where, $joinType)
Sets the join condition which is used for the current instance.
setLeftJoin($table, $where)
Sets a left join on $this->table.
addLeftJoin($table, $where, $type)
Adds a left join to the query.
setRightJoin($table, $where)
Sets a right join on $this->table.
getJoin($what)
Gets the join-condition.
addJoin($table, $where, $type)
adds a table and a where clause that shall be used for the join instead of calling
setJoin(array(table1, table2), '<where clause1> AND <where clause2>'); |
setJoin(table1,'<where clause1>'); addJoin(table2,'<where clause2>'); |
setTable($table)
Sets the table this class is currently working on.
getTable()
Gets the table this class is currently working on.
setGroup($group)
Sets the group-by condition.
getGroup()
Gets the group-by condition.
setSelect($what)
Limit the result to return only the columns given in what.
addSelect($what, $connectString)
Add a string to the select-part of the query and connects it to an existing string using the connectString, which by default is a comma. ("SELECT xxx FROM..." xxx is the select-part of a query)
getSelect()
Gets the select-part of the query.
setDontSelect($what)
Exclude some columns from the resultset.
getDontSelect()
Gets the columns excluded from the resultset.
reset($what)
Reset all the set* settings, with no parameter given it resets them all.
setOption($option, $value)
Set mode the class shall work in. The 'raw' mode does not quote the data before building the query
getOption($option)
Get the given option.
debug($string)
override this method and i.e. print the queryString to see the final query.
getTableShortName($table)
Gets the short name for a table.
execute($query, $method)
Execute a query (the current query is executed when query is null.
writeLog($text)
Write events to the logfile. It does some additional work, like time measuring etc. to see some additional info.
returnResult($result)
Return the chosen result type
setIndex($key)
Format the result to be indexed by key. NOTE: be careful, when using this you should be aware, that if you use an index which's value appears multiple times you may loose data since a key can't exist multiple times! The result for a result to be indexed by a key(=columnName) (i.e. 'relationtoMe') which's values are 'brother' and 'sister' or alike normally returns this:
$res['brother'] = array('name' => 'xxx'); $res['sister'] = array('name' => 'xxx'); |
getIndex()
Gets the index.
useResult($type)
Choose the type of the returned result ('array', 'object', 'none')
setErrorCallback($param)
Set both callbacks.
setErrorLogCallback($param)
Set the error log callback.
setErrorSetCallback($param)
Set the error set callback.
Предоставляет пакеты для шифрования.
Classes for generating packets for various CHAP Protocols
CHAP is a part usualy of PPP (Point-to-Point Protocol) software, implemented in the authentication subsystem. CHAP avoid's sending plaintext passwords over an insecure link. The traditional CHAP-MD5 needs the plaintext password stored on the server. MS-CHAP doesen't need this, but also needs the password either as NT-Hash and/or as LAN-Manager-Hash. LAN-Manager-Hashes are weak and shouldn't be used anymore.
This package provides 3 classes:
In order to get the MS-CHAP* to work you need the mhash extension.
This method generates a new random challenge and stores it in the given property, the default size of the challenge is 8 bytes.
string $varname - name of the property for storing the challenge
int $size - the size of the challenge
Пример 36-1. Using Crypt_CHAP::generateChallenge()
|
This method generates the challenge-response paket, by doing: md5(ID + Password + Challenge).
Пример 36-1. Using Crypt_CHAP_MD5::challengeResponse()
|
Пример 36-1. Using Crypt_CHAP_MSCHAPv1::challengeResponse()
|
Пример 36-1. Using Crypt_CHAP_MSCHAPv1::lmChallengeResponse()
|
Пример 36-1. Using Crypt_CHAP_MSCHAPv1::ntChallengeResponse()
|
This method generates NT-Hash from the given plaintext-password or from the password property. The NT-Hash is computed like this: md4(str2unicode(plaintext))
Пример 36-1. Using Crypt_CHAP_MSCHAPv1::ntPasswordHash()
|
This method generates LAN-Manager-Hash from the given plaintext-password or from the password property.
Эта функция не должна вызываться статически.
LAN-Manager Hash are weak and should not be used anymore.
Пример 36-1. Using Crypt_CHAP_MSCHAPv1::lmPasswordHash()
|
Пример 36-1. Using Crypt_CHAP_MSCHAPv1::str2unicode()
|
This method generates the response paket, containing the NT-Challenge-Response and/or the LM-Challenge-Response. By default the LM-Challenge-Response is not included.
Пример 36-1. Using Crypt_CHAP_MSCHAPv1::response()
|
Generates a new Object for generating MS-CHAPv2 compliant pakets. This version of CHAP uses also a Peer-Challenge, LM-Hashes are not used anymore. The Constructor generates automatically a Peer-Challenge and the Authenticator-Challenge.
This method generates the (SHA1) Challenge-Hash containing the authenticator and the peer challenge and the username.
Пример 36-1. Using Crypt_CHAP_MSCHAPv2::challengeHash()
|
Пример 36-1. Using Crypt_CHAP_MSCHAPv2::ntPasswordHashHash()
|
Provides packages for event based development.
Dispatch notifications using PHP callbacks
Event_Dispatcher acts as a notification dispatch table. It is used to notify other objects of interesting things. This information is encapsulated in Event_Notification objects.
Client objects register themselves with the Event_Dispatcher as observers of specific notifications posted by other objects. When an event occurs, an object posts an appropriate notification to the Event_Dispatcher. The Event_Dispatcher dispatches a message to each registered observer, passing the notification as the sole argument.
Event_Dispatchers allows you to use event bubbling similar to JavaScript's event management. If an event is not handled by the dispatcher that triggered the event, it may bubble up to the next dispatcher.
The following examples show you how to use Event_Dispatcher to create more flexible applications.
Пример 37-1. Basic example
In this example, Event_Dispatcher is used to allow observers to hook into the authentication process. Whenever a user authenticates, a notification onLogin is sent. This can be used to write logfiles or block the application for other users. |
Пример 37-2. Cancelling notifications
In this case, the cancelNotification() method is used to cancel the notification if a certain user tries to authenticate. The login method has been changed as well to check whether the notification has been cancelled and to take the necessary steps. This allows you to add some flexible rules to your authentication system. |
Create a new Event_Dispatcher object.
As Event_Dispatcher uses the singleton pattern, you must not use the new operator to create a new instance of Event_Dispatcher, but use getInstance() instead.
If you need more than one instance of Event_Dispatcher, pass different names to the method.
Get the name of the dispatcher.
The name of the dispatcher is used as a unique identifier. This is important for the methods getInstance() and removeNestedDispatcher().
Adds a new observer to the dispatcher.
Observers are PHP callbacks. That means you may either pass a function name as a string or an array containing an object or class and a method to call.
The callback is used as a signature for the observer, which allows you to remove it by passing the exact same parameters to removeObserver().
mixed $callback
Callback to notity, may either be a string containing the name of a global function or an array containing class or object and the name of the method to call.
string $nName = EVENT_DISPATCHER_GLOBAL
Acts as a filter: notify the observer only if the notification name matches the name passed in this parameter. Use EVENT_DISPATCHER_GLOBAL if the observer should be notified regardles of the notification name.
string $class = ''
Acts as a filter: notify the observer only if the sender of the notification matches the class passed in this parameter.
Remove an observer from dispatcher.
To remove an observer, specify the same parameters as used in the call to addObserver().
mixed $callback
Callback to notity, may either be a string containing the name of a global function or an array containing class or object and the name of the method to call.
string $nName = EVENT_DISPATCHER_GLOBAL
Acts as a filter: notify the observer only if the notification name matches the name passed in this parameter. Use EVENT_DISPATCHER_GLOBAL if the observer should be notified regardles of the notification name.
string $class = ''
Acts as a filter: notify the observer only if the sender of the notification matches the class passed in this parameter.
Set the name of the class that will be used as a notification object when post() is called.
You may call this method on an object to change it for a single dispatcher or statically, to set the default for all dispatchers that will be created.
string $class
Name of the class that is used as a notification container when the post() method is called. Make sure the class is loaded before using it as notification class.
object &$object
Reference to the object that posts the notification (the sender). May be used to filter notifications in the callbacks.
string $nName
Name of the notification.
mixed $info = array()
Additional information about the notification.
bool $pending = TRUE
Notifications are by default added to a pending notification list. This way, if an observer is not registered by the time they are posted, it will still be notified when it is added as an observer.
This behaviour can be turned off in order to make sure that only the registered observers will be notified.
bool $bubble = TRUE
Notifications are by default added broadcasted to any nested dispatchers that have been added using addNestedDispatcher().
This behaviour can be turned off in order to make sure that only the observers added the the posting dispatcher will be notified. This allows you to differentiate between global and local notifications.
Adds a nested dispatcher to the dispatcher.
Nested dispatchers allow you to create event bubbling like it is implemented in Javascript. After an event has been posted to all observers of the dispatcher, it will be broadcasted to all nested dispatchers.
If you have one dispatcher that dispatches events of a component in your framework and one dispatcher that dispatches global events that are triggered by the framework itself it could make sense that you nest these dispatchers, so that events posted by the component dispatcher will also be broadcasted to the global dispatcher.
object Event_Dispatcher &$dispatcher
Dispatcher that should be added as a nested dispatcher to the current dispatcher.
Removes a nested dispatcher from the dispatcher.
To remove a dispatcher from the list of nested dispatcher, just pass the same object to removeNestedDispatcher().
object Event_Dispatcher &$dispatcher
Dispatcher that should be removed from the list of nested dispatchers.
The Event_Notification class acts as a container for event information. It provides some setters and getters to access the contained information.
If you need to store additional information about the events or provide additional features, you may change the class that is used by Event_Dispatcher, but it is recommended to extend Event_Notification.
Constructor of the Event_Notification class.
In most cases, you will not need to create the notification objects yourself, as this is done automatically by the Event_Dispatcher::post() method..
object &$object
Reference to the object that posts the notification (the sender). May be used to filter notifications in the callbacks.
string $nName
Name of the notification.
mixed $info = array()
Additional information about the notification.
Cancels the notification.
If a notification is cancelled, no more observers will be notified by this notification.
Предоставляет пакеты для работы с разными форматами файлов.
Build (create) and fetch vCard 2.1 and 3.0 text blocks.
Please read About Contact_Vcard first.
Allows you to programmatically create a vCard, version 2.1 or 3.0, and fetch the vCard text.
Download and un-compress Contact_Vcard_Build from the PEAR archive.
Include Contact_Vcard_Build.php in your PHP script.
Instantiate a new Contact_Vcard_Build object (by default, the vCard version is 3.0, but 2.1 vCards are also supported).
Set or add values and parameters that you want in the vCard.
Fetch the completed vCard, then use print_r() to view the results.
Пример 38-1. Example code:
|
The 2.1 specification uses CRLF to terminate lines (\r\n). It allows the following components and parameters:
Parameters:
TYPE of DOM, INTL, POSTAL, PARCEL, HOME, WORK, PREF, VOICE, FAX, MSG, CELL, PAGER, BBS, MODEM, CAR, ISDN, VIDEO, AOL, APPLELINK, ATTMAIL, CIS, EWORLD, INTERNET, IBMMAIL, MCIMAIL, POWERSHARE, PRODIGY, TLX, X400, GIF, CGM, WMF, BMP, MET, PMB, DIB, PICT, TIFF, PDF, PS, JPEG, QTIME, MPEG, MPEG2, AVI, WAVE, AIFF, PCM, X509, or PGP.
ENCODING of 7BIT, 8BIT, BASE64, QUOTED-PRINTABLE
VALUE of INLINE, CONTENT-ID, CID, URL, VCARD
CHARSET of any ISO charset specification.
LANGUAGE is very lenient, basically anything so long as it uses only the characters a-z, A-Z, 0-9, and dash (-).
Components and methods
VERSION (setVersion())
FN (setFormattedName())
N (setName())
PHOTO (setPhoto())
BDAY (setBirthday())
ADR (addAddress())
LABEL (addLabel())
TEL (addTelephone())
EMAIL (addEmail())
MAILER (setMailer())
TZ (setTZ())
GEO (setGeo())
TITLE (setTitle())
ROLE (setRole())
LOGO (setLogo())
AGENT (setAgent())
ORG (addOrganization())
NOTE (setNote())
REV (setRevision())
SOUND (setSound())
URL (setURL())
KEY (setKey())
The 3.0 specification uses LF to terminate lines (\n). It allows the following components and parameters:
Parameters:
TYPE of any of the 2.1 TYPE values, or any other value so long as it uses only the characters a-z, A-Z, 0-9, and dash (-).
ENCODING of 8BIT and B ("binary").
VALUE of BINARY, PHONE-NUMBER, TEXT, URI, UTC-OFFSET, or VCARD.
Components and Methods:
VERSION (setVersion())
FN (setFormattedName())
N (setName())
NAME (setSourceName())
SOURCE (setSource())
NICKNAME (addNickname())
PHOTO (setPhoto())
BDAY (setBirthday())
ADR (addAddress())
LABEL (addLabel())
TEL (addTelephone())
EMAIL (addEmail())
MAILER (setMailer())
TZ (setTZ())
GEO (setGeo())
TITLE (setTitle())
ROLE (setRole())
LOGO (setLogo())
AGENT (setAgent())
ORG (addOrganization())
CATEGORIES (addCategories())
NOTE (setNote())
PRODID (setProductID())
REV (setRevision())
SORT-STRING (setSortString())
SOUND (setSound())
UID (setUniqueID())
URL (setURL())
CLASS (setClass())
KEY (setKey())
The basic use of Contact_Vcard_Build is straightforward: instantiate a builder object, add values and parameters, then fetch the resulting vCard.
To create an instance of a Contact_Vcard_Build ("builder") object, include the class file and issue a new directive:
<?php require_once 'Contact_Vcard_Build.php'; $vcard =& new Contact_Vcard_Build(); ?> |
By default, this creates a builder object that will allow you to fetch a version 3.0 vCard. If you want to build a version 2.1 vCard, pass '2.1' as the only constructor argument:
<?php $vcard =& new Contact_Vcard_Build('2.1'); ?> |
There are two ways to set the value of a component: use the method specifically for the component you want to add, or use the generic setValue() and addValue() methods. While the generic methods allow you direct control over every individual component, iteration, structured part, and value repetition, the component-specific methods are often easier to use.
Замечание: You must set the FN (formatted name) and N (personal name) components; these are required by both 2.1 and 3.0 version vCards.
For example, if you want to add two ADR components to the vCard, you can do it with the ADR-specific method...
<?php // add first address iteration $vcard->addAddress($pobox0, $extend0, $street0, $city0, $state0, $zip0, $country0); // add second address iteration $vcard->addAddress($pobox1, $extend1, $street1, $city1, $state1, $zip1, $country1); ?> |
...or you can use the generic methods:
<?php // add first address (iteration = 0) $vcard->addValue('ADR', 0, VCARD_ADR_POB, $pobox0); $vcard->addValue('ADR', 0, VCARD_ADR_EXTEND, $extend0); $vcard->addValue('ADR', 0, VCARD_ADR_STREET, $street0); $vcard->addValue('ADR', 0, VCARD_ADR_LOCALITY, $city0); $vcard->addValue('ADR', 0, VCARD_ADR_REGION, $state0); $vcard->addValue('ADR', 0, VCARD_ADR_POSTCODE, $zip0); $vcard->addValue('ADR', 0, VCARD_ADR_COUNTRY, $country0); // add second address (iteration = 1) $vcard->addValue('ADR', 1, VCARD_ADR_POB, $pobox1); $vcard->addValue('ADR', 1, VCARD_ADR_EXTEND, $extend1); $vcard->addValue('ADR', 1, VCARD_ADR_STREET, $street1); $vcard->addValue('ADR', 1, VCARD_ADR_LOCALITY, $city1); $vcard->addValue('ADR', 1, VCARD_ADR_REGION, $state1); $vcard->addValue('ADR', 1, VCARD_ADR_POSTCODE, $zip1); $vcard->addValue('ADR', 1, VCARD_ADR_COUNTRY, $country1); ?> |
Please see the Contact_Vcard_Build.php inline comments for descriptions of how to use each component-specific method.
There is only one way to add a parameter: use the addParam() method. Unlike with adding values, there are no component-specifc methods to add parameters.
In general, you should add the parameters of a component immediately after you add the complete value of a component, because the builder object keeps track of what was the last component value added. (This is why there are no component-specific add-parameter methods.)
For example, we can set the params for the ADR components as in the above code:
<?php // add first address iteration $vcard->addAddress($pobox0, $extend0, $street0, $city0, $state0, $zip0, $country0); // add parameters to the first address $vcard->addParam('TYPE', 'HOME'); $vcard->addParam('TYPE', 'PREF'); // add second address iteration $vcard->addAddress($pobox1, $extend1, $street1, $city1, $state1, $zip1, $country1); // add parameters to the second address $vcard->addParam('TYPE', 'WORK'); ?> |
Thus, the first address will have TYPE=HOME,PREF and the second will have TYPE=WORK as their parameters.
Alternatively, you can add parameters directly using the same addParam() method, with some additional arguments:
<?php // add parameters to the first address iteration // (component = ADR, iteration = 0) $vcard->addParam('TYPE', 'HOME', 'ADR', 0); $vcard->addParam('TYPE', 'PREF', 'ADR', 0); // add parameters to the second address iteration // (component = ADR, iteration = 1) $vcard->addParam('TYPE', 'WORK', 'ADR', 1); ?> |
This does the same thing as the earlier addParam() code.
Замечание: Although the version 2.1 specification optionally allows parameter values to be indicated without without specified types (i.e, "HOME" instead of "TYPE=HOME") the Contact_Vcard_Build class is not so lenient. With Contact_Vcard_Builder, you must set both the parameter kind and parameter value.
After you have added all the values and parameters that you want, you get back the vCard using the fetch() method. This will return the components, parameters, and values (including BEGIN:VCARD and END:VCARD) in proper format for the vCard version.
<?php $text = $vcard->fetch(); ?> |
Замечание: If you set values and parameters for components that are not part of the selected vCard version, they will not be included in the fetched vCard text.
Замечание: You must have set the FN (formatted name) and N (personal name) components, or the fetch() method will return a PEAR_Error object. The FN and N components are required by both 2.1 and 3.0 version vCards.
Parse vCard 2.1 and 3.0 files.
Please read About Contact_Vcard first.
Here are some quick instructions for the impatient. :-)
Download and un-compress Contact_Vcard_Parse from the PEAR archive.
Include Contact_Vcard_Parse.php in your PHP script.
Instantiate a new Contact_Vcard_Parse object.
Use the fromFile() method to parse any file which may have one or more vCards in it; try the sample.vcf file for a start. Contact_Vcard_Parse should work with both 2.1 and 3.0 vCard files.
Use print_r() to view the resulting array of data from the parsed file.
Do what you want with the data, such as insert into a table.
Пример 38-1. Example code
|
Contact_Vcard_Parse reads a file or block of text for vCard data, then converts that data into a series of nested arrays. I used to present a detailed prose explanation of the array, but I think it's easier to just give a generic outline of the array:
$parse_result = array ( [int_cardnumber] => array ( [string_datatype] => array ( ["param"] => array ( [string_paramname] => array ( [int_repetitionnumber] => string_paramtext ) ) ["value"] => array ( [int_partnumber] => array ( [int_repetitionnumber] => string_valuetext ) ) ) ) ) |
By way of example, let's take a look at the vCard of my friend Bolivar Shagnasty.
BEGIN:VCARD VERSION:3.0 N:Shagnasty;Bolivar;Odysseus;Mr.;III,B.S. FN:Bolivar Shagnasty ADR;TYPE=HOME,WORK:;;123 Main,Apartment 101;Beverly Hills;CA;90210 EMAIL;TYPE=HOME;TYPE=WORK:boshag@example.com EMAIL;TYPE=PREF:boshag@ciaweb.net END:VCARD |
This is a pretty simple vCard: my buddy Bolivar's name, one address (looks like Bolivar works from home), two email addresses (one for work and home, and one as his "preferred" address). This simple vCard, when it gets parsed, looks like this:
( [0] => Array ( [VERSION] => Array ( [0] => Array ( [param] => Array ( ) [value] => Array ( [0] => Array ( [0] => 3.0 ) ) ) ) [N] => Array ( [0] => Array ( [param] => Array ( ) [value] => Array ( [0] => Array // family ( [0] => Shagnasty ) [1] => Array // first ( [0] => Bolivar ) [2] => Array // additional or middle ( [0] => Odysseus ) [3] => Array // honorifix prefix ( [0] => Mr. ) [4] => Array // honorifix suffix ( [0] => III [1] => B.S. ) ) ) ) [FN] => Array ( [0] => Array ( [param] => Array ( ) [value] => Array ( [0] => Array ( [0] => Bolivar Shagnasty ) ) ) ) [ADR] => Array ( [0] => Array ( [param] => Array ( [TYPE] => Array ( [0] => HOME [1] => WORK ) ) [value] => Array ( [0] => Array // p.o. box ( [0] => ) [1] => Array // extended ( [0] => ) [2] => Array // street ( [0] => 123 Main [1] => Apartment 101 ) [3] => Array // locality or city ( [0] => Beverly Hills ) [4] => Array // region, state, or province ( [0] => CA ) [5] => Array // postal code ( [0] => 90210 ) [6] => Array // country ( [0] => ) ) ) ) [EMAIL] => Array ( [0] => Array ( [param] => Array ( [TYPE] => Array ( [0] => HOME [1] => WORK ) ) [value] => Array ( [0] => Array ( [0] => boshag@example.com ) ) ) [1] => Array ( [param] => Array ( [TYPE] => Array ( [0] => PREF ) ) [value] => Array ( [0] => Array ( [0] => boshag@ciaweb.net ) ) ) ) ) ) |
Sweet Jebus! That's an ugly mess. But it retains every bit of info about the vCard so you can do what you like with it. It keeps (separately) every element and component so you can see the underlying structure of the vCard.
Yes, I know it's a deeply-nested array set, and is ugly and probably inefficient. The problem (or genius?) of the vCard format is that just about every part of a vCard element can have multiple values. While this makes the vCard format very flexible, it makes it a little difficult to parse and interpret in a simple fashion. The easiest way I could think of was a series of nested arrays. An object-oriented approach might be better, but even then you're going to have nested objects or nested arrays within the vCard object to represent multiple values of a vCard data element.
When I wrote this parser, my primary goal was to be able to read vCard files produced by the Mac OS X Address Book application. However, it looks like Address Book puts some weird character after every single text character in the output, in addition to some weird line endings. If you want to use .vcf files generated by the Mac OS X Address Book, you might need to massage the file in BBEdit or TextWrangler first; turn on "show invisibles" to see the offending characters, then do a search-and-replace to delete them all at once (or perhaps "Zap Gremlins").
UPDATE: David Weingart writes, "That's probably Unicode. In my extremely limited testing, it looks like in some cases you get plain vanilla ISO Latin 1, but if there are any high ascii characters in the entry, they export UTF 16 (double-byte) Unicode." Thanks, David. (Contact_Vcard_Parse does not do Unicode at this time.)
Contact_Vcard_Parse does not validate the information or formatting in the vCard (although it does decode quoted-printable text). In the spirit of "be lenient in what you accept and strict in what you produce", Contact_Vcard_Parse should be able to read just about anything from a vCard file, but it's up to you as the programmer to make sense of the data.
Contact_Vcard_Parse should work on file with any kind of line endings (Mac \r, Unix \n, and DOS \r\n) automatically. It also unfolds lines automatically, so data elements spread across multiple lines should come through OK.
If you discover a new bug or want to contribute code to Contact_Vcard_Parse, contact Paul M. Jones at pjones at ciaweb dot net; the subject line should start with [VCARD].
This package will let you manipulate easily tar, gz, bz2, tgz, tbz, zip, ar and deb files.
There is currently no documentation in the PEAR manual. Please go to http://poocl.la-grotte.org.
Package for reading and modifying DICOM files
File_DICOM allows reading and modifying of DICOM files. DICOM stands for Digital Imaging and COmmunications in Medicine, and is a standard for creating, storing and transfering digital images (X-rays, tomography) and related information used in medicine. This package in particular does not support the exchange/transfer of DICOM data, nor any network related functionality. More information on the DICOM standard can be found at the NEMA site.
Please be aware that any use of the information produced by this package for diagnosing purposes is strongly discouraged by the author. See here for more information.
File_DICOM can be used to accomplish two things, to retrieve data from a file (including image data), and to set new values for that data (allowing to write the modified file).
Let's see how we could show some relevant data from a DICOM file and export it's image data at the same time.
Пример 38-1. Showing data
|
The name of the file to write. If not given it assumes the name of the file parsed. If no file was parsed and no name is given returns a PEAR_Error
The group the DICOM element belongs to (integer), or its name (string)
The identifier for the DICOM element (unique inside a group). Optional
Пример 38-1. Using getValue()
|
The group the DICOM element belongs to
The identifier for the DICOM element (unique inside a group)
This package reads and writes fstab files, or other files sharing their format, such as /proc/mounts on Linux systems.
This package allows you to read, manipulate, and write fstab-format files, such as /etc/fstab, /etc/mtab, and /proc/mounts.
Пример 38-1. Getting the filesystem type of the root device.
|
Пример 38-2. Determine if a user may mount the CD-ROM The user option in your fstab determines whether users may mount a given device or not.
|
The File_Fstab_Entry class represents all the information available about a particular entry in a Fstab file.
The entry has a number of properties which represent the information in the fstab file.
This is the path to the block device for this entry. $device, $uuid, and $label are mutually exclusive; only one of the three may be set.
The UUID of the device.
The label for this device.
The directory this device is mounted on.
The type of filesystem on $device.
Array of mount options for this device.
How often / if this filesystem should be backed up by dump.
Order of / if this device should be checked by fsck when the system boots.
You may want to read fstab(5) for more information about what these fields mean.
There are a number of ways of finding a specific entry from the fstab. You may find based on device, mountpoint, filesystem label, or UUID.
To find by device, you want to use the getEntryForDevice() function. The single argument this function accepts is the path to the block device for an entry.
Пример 38-1. Get entry by device
|
You may want to find a device based on the path it is mounted on; for example, you may want to get the entry for /cdrom, without caring if the CD device is /dev/hdb, /dev/cdrom, or some other device. To do this, use the getEntryForPath() function.
Пример 38-2. Get entry by path
|
Some systems use a filesystem UUID to specify the device to mount. A UUID may look like this: b46ad2ee-01f3-4041-96ca-91d35d059417. The getEntryForUUID() function handles this.
Пример 38-3. Get entry by UUID
|
Some filesystems allow you to specify a textual label to a filesystem. For example, you may label your root device rootdev, the device you mount on /home could be named homedirs and so forth. File_Fstab supports getting entries based on the device label. This is accomplished by using the getEntryForLabel() function.
Пример 38-4. Get entry by label
|
In addition to reading fstab files, you may modify them as well.
Пример 38-5. Add an entry for a floppy disk
|
After modifying a fstab file, you will want to save your changes. The save() function does this.
Внимание |
Comments from the loaded file are not preserved when saving, and whitespace may change. This has no effect on the functionality of the fstab file, but you may lose helpful comments. |
Пример 38-1. Save to the same file This will save your changes back to the file you loaded, overwriting the old file.
|
Пример 38-2. Save to a different file This will save your changes to a different file than the one you originally loaded.
|
Package to manage passwd-style files
The File_Passwd class provides a factory for all special purpose classes, static authentication and common encryption methods.
Таблица 38-1. Encryption Constants
Name | Value | Description |
---|---|---|
FILE_PASSWD_DES | "des" | DES encryption |
FILE_PASSWD_MD5 | "md5" | MD5 encryption |
FILE_PASSWD_SHA | "sha" | SHA encryption |
FILE_PASSWD_NT | "nt" | NT hash |
FILE_PASSWD_LM | "lm" | LM hash |
FILE_PASSWD_PLAIN | "plain" | no encryption |
Таблица 38-2. Error Constants
Name | Value | Description |
---|---|---|
FILE_PASSWD_E_UNDEFINED | 0 | undefined - some seldom occuring errors |
FILE_PASSWD_E_INVALID_FORMAT | 1 | passwd file has invalid format |
FILE_PASSWD_E_INVALID_PROPERTY | 2 | an invalid (additional) property was supplied |
FILE_PASSWD_E_INVALID_CHARS | 3 | parameter contains illegal chracters (usually only alphanumerics, the dash and underline are allowed) |
FILE_PASSWD_E_INVALID_ENC_MODE | 4 | an invalid encryption mode was supplied (depending on the class actually used) |
FILE_PASSWD_E_EXISTS_ALREADY | 5 | an entry (user, group, etc) to add exists already |
FILE_PASSWD_E_EXISTS_NOT | 6 | an entry (user, group, etc) to delete/change doesn't exist |
FILE_PASSWD_E_USER_NOT_IN_GROUP | 7 | the specified user is not in this certain group |
FILE_PASSWD_E_USER_NOT_IN_REALM | 8 | the specified user is not in this certain realm |
FILE_PASSWD_E_PARAM_MUST_BE_ARRAY | 9 | the supplied param must be of type array |
FILE_PASSWD_E_METHOD_NOT_IMPLEMENTED | 10 | requested method was not implemented yet |
FILE_PASSWD_E_DIR_NOT_CREATED | 11 | a certain directory couldn't be created |
FILE_PASSWD_E_FILE_NOT_OPENED | 12 | passwd file couldn't be opened |
FILE_PASSWD_E_FILE_NOT_LOCKED | 13 | passwd file couldn't be locked |
FILE_PASSWD_E_FILE_NOT_UNLOCKED | 14 | passwd file couldn't be unlocked |
FILE_PASSWD_E_FILE_NOT_CLOSED | 15 | passwd file couldn't be closed |
Load the desired worker class (extension).
Unix - for standard Unix passwd files
CVS - for CVS pserver passwd files
SMB - for SMB server passwd files
Authbasic - for AuthUserFiles
Authdigest - for AuthDigestFiles
Custom - for custom formatted passwd files
Static user autentication.
Though this approach should be reasonable fast, it is NOT with APR compatible MD5 encryption used for htpasswd style password files encrypted in MD5.
Generating one MD5 password takes about 0.25 seconds!
Depending on $type, $opt should be:
Smb:
encryption method (NT or LM) |
Unix:
encryption method (des or md5) |
Authbasic:
encryption method (des, sha or md5) |
Authdigest:
the realm the user is in |
Cvs:
n/a (empty) |
Custom:
array of 2 elements: encryption function and delimiter |
Unix, Cvs, Smb, Authbasic or Authdigest
path to passwd file
the user to authenticate
the plaintext password
Smb:
nt | lm |
Unix:
des | md5 |
Authbasic:
des | sha | md5 |
Authdigest:
the realm the user is in |
Cvs:
n/a (empty) |
Custom:
array of 2 elements: encryption function and delimiter |
Returns TRUE if authenticated, FALSE if not, or PEAR_Error on failure.
Таблица 38-1. Возможные значения PEAR_Error
Error Code | Summary |
---|---|
FILE_PASSWD_E_NOT_EXISTS | passwd file doesn't exist |
FILE_PASSWD_E_FILE_NOT_OPENED | passwd file couldn't be opened in read mode |
FILE_PASSWD_E_FILE_NOT_LOCKED | passwd file couldn't be locked shared |
FILE_PASSWD_E_FILE_NOT_UNLOCKED | passwd file couldn't be unlocked (only if auth fails) |
FILE_PASSWD_E_FILE_NOT_CLOSED | passwd file couldn't be closed /only if auth fails) |
FILE_PASSWD_E_UNDEFINED | if class/file couldn't be loaded |
FILE_PASSWD_E_INVALID_ENC_MODE | supplied encryption mode is not supported |
FILE_PASSWD_E_USER_NOT_IN_REALM | user doesn't exist in this realm (only File_Passwd_Authdigest) |
Base class for worker class extensions.
Таблица 38-1. Classes that extend File_Passwd_Common
Class | Summary |
---|---|
File_Passwd_Authbasic | Manipulate AuthUserFiles as used for HTTP Basic Authentication. |
File_Passwd_Authdigest | Manipulate AuthDigestFiles as used for HTTP Digest Authentication. |
File_Passwd_Cvs | Manipulate CVS pserver passwd files. |
File_Passwd_Smb | Manipulate SMB server passwd files. |
File_Passwd_Unix | Manipulate standard Unix passwd files. |
File_Passwd_Custom | Manipulate custom formatted passwd files. |
Таблица 38-2. Inherited methods from File_Passwd_Common
Method Name | Summary |
---|---|
File_Passwd_Common::delUser() | Delete a certain user |
File_Passwd_Common::getFile() | Get path of passwd file |
File_Passwd_Common::listUser() | List user |
File_Passwd_Common::load() | Loads the file |
File_Passwd_Common::parse() | Parse the content of the file |
File_Passwd_Common::save() | Apply changes and rewrite passwd file |
File_Passwd_Common::setFile() | Set path to passwd file |
File_Passwd_Common::userExists() | Check if a certain user already exists |
File_Passwd_Common::_auth() | Base method for File_Passwd::staticAuth() |
File_Passwd_Common::_close() | Closes a prior opened and locked file handle |
File_Passwd_Common::_open() | Opens a file, locks it exclusively and returns the filehandle |
File_Passwd_Common::_save() | Save the modified content to the passwd file |
Возвращает TRUE при удаче и PEAR_Error в обратном случае.
Таблица 38-1. Возможные значения PEAR_Error
Error Code | Summary |
---|---|
FILE_PASSWD_E_EXISTS_NOT | user doesn't exist |
Returns array of user(s) or PEAR_Error on failure.
Таблица 38-1. Возможные значения PEAR_Error
Error Code | Summary |
---|---|
FILE_PASSWD_E_NOT_EXISTS | suer doesn't exist |
Возвращает TRUE при удаче и PEAR_Error в обратном случае.
Таблица 38-1. Возможные значения PEAR_Error
Error Code | Summary |
---|---|
FILE_PASSWD_E_DIR_NOT_CREATED | the directory in which the passwd file should reside couldn't be created |
FILE_PASSWD_E_FILE_NOT_OPENED | passwd file couldn't be opened in read mode |
FILE_PASSWD_E_FILE_NOT_LOCKED | passwd file couldn't be locked shared |
FILE_PASSWD_E_FILE_NOT_UNLOCKED | passwd file couldn't be unlocked |
FILE_PASSWD_E_FILE_NOT_CLOSED | passwd file couldn't be closed |
FILE_PASSWD_E_INVALID_FORMAT | passwd file has invalid format |
This is kinda abstract method which only returns a PEAR_Error, so it is to be overwritten in the extending child class.
You must overwrite this method in your File_Passwd_* class.
(для разработчиков)
This is kinda abstract method which only returns a PEAR_Error, so it is to be overwritten in the extending child class.
You must overwrite this method in your File_Passwd_* class.
(для разработчиков)
Returns string line of passwd file containing $id, FALSE if $id wasn't found, or PEAR_Error on failure.
Таблица 38-1. Возможные значения PEAR_Error
Error Code | Summary |
---|---|
FILE_PASSWD_E_EXISTS_NOT | passwd file doesn't exist |
FILE_PASSWD_E_FILE_NOT_OPENED | passwd file couldn't be opened in read mode |
FILE_PASSWD_E_FILE_NOT_LOCKED | passwd file couldn't be locked shared |
FILE_PASSWD_E_FILE_NOT_UNLOCKED | passwd file couldn't be unlocked (only if auth fails) |
FILE_PASSWD_E_FILE_NOT_CLOSED | passwd file couldn't be closed (only if auth fails) |
Returns resource file handle or PEAR_Error on failure.
Таблица 38-1. Возможные значения PEAR_Error
Error Code | Summary |
---|---|
FILE_PASSWD_E_DIR_NOT_CREATED | the directory in which the passwd file should reside couldn't be created |
FILE_PASSWD_E_FILE_NOT_OPENED | passwd file couldn't be opened in the desired mode |
FILE_PASSWD_E_FILE_NOT_LOCKED | passwd file couldn't be locked |
Closes a prior with File_Passwd_Common::_open() opened and locked file handle.
(для разработчиков)
Возвращает TRUE при удаче и PEAR_Error в обратном случае.
Таблица 38-1. Возможные значения PEAR_Error
Error Code | Summary |
---|---|
FILE_PASSWD_E_FILE_NOT_UNLOCKED | passwd file couldn't be unlocked |
FILE_PASSWD_E_FILE_NOT_CLOSED | passwd file couldn't be closed |
Возвращает TRUE при удаче и PEAR_Error в обратном случае.
Таблица 38-1. Возможные значения PEAR_Error
Error Code | Summary |
---|---|
FILE_PASSWD_E_DIR_NOT_CREATED | the directory in which the passwd file should reside couldn't be created |
FILE_PASSWD_E_FILE_NOT_OPENED | passwd file couldn't be opened in write mode |
FILE_PASSWD_E_FILE_NOT_LOCKED | passwd file couldn't be locked exclusively |
FILE_PASSWD_E_FILE_NOT_UNLOCKED | passwd file couldn't be unlocked |
FILE_PASSWD_E_FILE_NOT_CLOSED | passwd file couldn't be closed |
Manipulate custom formatted passwd files. (inherited methods)
path to passwd file
user to authenticate
plaintext password
A two element array containing the encryption function to use and the delimiting character: e.g. array('md5', '|')
Returns TRUE if authenticated, FALSE if not or PEAR_Error on failure.
Таблица 38-1. Возможные значения PEAR_Error
Error Code | Summary |
---|---|
FILE_PASSWD_E_NOT_EXISTS | passwd file doesn't exist |
FILE_PASSWD_E_FILE_NOT_OPENED | passwd file couldn't be opened in read mode |
FILE_PASSWD_E_FILE_NOT_LOCKED | passwd file couldn't be locked shared |
FILE_PASSWD_E_FILE_NOT_UNLOCKED | passwd file couldn't be unlocked (only if auth fails) |
FILE_PASSWD_E_FILE_NOT_CLOSED | passwd file couldn't be closed (only if auth fails) |
Parse the custom passwd file. (для разработчиков)
This usually happens in File_Passwd_Custom::load() .
Возвращает TRUE при удаче и PEAR_Error в обратном случае.
Returns PEAR_Error FILE_PASSWD_E_INVALID_FORMAT, if passwd file has illegal format.
Возвращает TRUE при удаче и PEAR_Error в обратном случае.
Таблица 38-1. Возможные значения PEAR_Error
Error Code | Summary |
---|---|
FILE_PASSWD_E_DIR_NOT_CREATED | directory in which the passwd file should reside couldn't be created |
FILE_PASSWD_E_FILE_NOT_OPENED | passwd file couldn't be opened in write mode |
FILE_PASSWD_E_FILE_NOT_LOCKED | passwd file couldn't be locked exclusively |
FILE_PASSWD_E_FILE_NOT_UNLOCKED | passwd file couldn't be unlocked |
FILE_PASSWD_E_FILE_NOT_CLOSED | passwd file couldn't be closed |
The username must start with an alphabetical character and must NOT contain any other characters than alphanumerics, the underline and dash.
The username MUST NOT contain the custom delimiter!
If you use the 'name map' you should also use these naming in the supplied extra array, because your values would get mixed up if they are in the wrong order, which is always true if you DON'T use the 'name map'!
So be warned and USE the 'name map'!
the name of the user to add
the password of the user to add
extra properties of user to add
Возвращает TRUE при удаче и PEAR_Error в обратном случае.
Таблица 38-1. Возможные значения PEAR_Error
Error Code | Summary |
---|---|
FILE_PASSWD_E_ALREADY_EXISTS | user already exists |
FILE_PASSWD_E_INVALID_CHARS | username contains illegal characters |
FILE_PASSWD_E_INVALID_CHARS | any of the extra proporties contains the delimiter |
FILE_PASSWD_E_INVALID_ENC_MODE | actual encryption mode is not supported |
FILE_PASSWD_E_UNDEFINED | if passwd file is shadowed |
You shouldn't modify the password of the user with this method, use File_Passwd_Custom::changePasswd() instead.
You should use this method only if the 'name map' is used, too.
the user to modify
an associative array of properties to modify
Возвращает TRUE при удаче и PEAR_Error в обратном случае.
Таблица 38-1. Возможные значения PEAR_Error
Error Code | Summary |
---|---|
FILE_PASSWD_E_EXISTS_NOT | user doesn't exists |
FILE_PASSWD_E_INVALID_CHARS | any of the extra properties contains the delimiter |
the user whose password should be changed
the new plaintext password
Возвращает TRUE при удаче и PEAR_Error в обратном случае.
Таблица 38-1. Возможные значения PEAR_Error
Error Code | Summary |
---|---|
FILE_PASSWD_E_EXISTS_NOT | user doesn't exist |
FILE_PASSWD_INVALID_ENC_MODE | actual encryption mode is not supported |
the user whose password should be verified
the password to verify
Returns TRUE if passwords equal, FALSE if they don't or PEAR_Error on failure.
Таблица 38-1. Возможные значения PEAR_Error
Error Code | Summary |
---|---|
FILE_PASSWD_E_EXISTS_NOT | user doesn't exist |
FILE_PASSWD_E_INVALID_ENC_MODE | actual encryption mode isn't supported |
Whether to use the 'name map' of the extra properties or not.
You first must supply a 'name map' to use it.
Returns boolean TRUE if you set a value, or the actual value if called without param.
Set the 'name map' to use with the extra properties of the user.
This map is used for naming the associative array of the extra properties.
Manipulate standard Unix passwd files. (inherited methods)
path to passwd file
user to authenticate
plaintext password
des or md5
Returns TRUE if authenticated, FALSE if not or PEAR_Error on failure.
Таблица 38-1. Возможные значения PEAR_Error
Error Code | Summary |
---|---|
FILE_PASSWD_E_NOT_EXISTS | passwd file doesn't exist |
FILE_PASSWD_E_FILE_NOT_OPENED | passwd file couldn't be opened in read mode |
FILE_PASSWD_E_FILE_NOT_LOCKED | passwd file couldn't be locked shared |
FILE_PASSWD_E_FILE_NOT_UNLOCKED | passwd file couldn't be unlocked (only if auth fails) |
FILE_PASSWD_E_FILE_NOT_CLOSED | passwd file couldn't be closed (only if auth fails) |
Parse the unix passwd file. (для разработчиков)
This usually happens in File_Passwd_Unix::load() .
Возвращает TRUE при удаче и PEAR_Error в обратном случае.
Returns PEAR_Error FILE_PASSWD_E_INVALID_FORMAT, if passwd file has illegal format.
Возвращает TRUE при удаче и PEAR_Error в обратном случае.
Таблица 38-1. Возможные значения PEAR_Error
Error Code | Summary |
---|---|
FILE_PASSWD_E_DIR_NOT_CREATED | directory in which the passwd file should reside couldn't be created |
FILE_PASSWD_E_FILE_NOT_OPENED | passwd file couldn't be opened in write mode |
FILE_PASSWD_E_FILE_NOT_LOCKED | passwd file couldn't be locked exclusively |
FILE_PASSWD_E_FILE_NOT_UNLOCKED | passwd file couldn't be unlocked |
FILE_PASSWD_E_FILE_NOT_CLOSED | passwd file couldn't be closed |
The username must start with an alphabetical character and must NOT contain any other characters than alphanumerics, the underline and dash.
If you use the 'name map' you should also use these naming in the supplied extra array, because your values would get mixed up if they are in the wrong order, which is always true if you DON'T use the 'name map'!
So be warned and USE the 'name map'!
If the passwd file is shadowed, the user will be added though, but with an 'x' as password, and a PEAR_Error will be returned, too.
the name of the user to add
the password of the user to add
extra properties of user to add
Возвращает TRUE при удаче и PEAR_Error в обратном случае.
Таблица 38-1. Возможные значения PEAR_Error
Error Code | Summary |
---|---|
FILE_PASSWD_E_ALREADY_EXISTS | user already exists |
FILE_PASSWD_E_INVALID_CHARS | username contains illegal characters |
FILE_PASSWD_E_INVALID_CHARS | any of the extra proporties contains a colon |
FILE_PASSWD_E_INVALID_ENC_MODE | actual encryption mode is not supported |
FILE_PASSWD_E_UNDEFINED | if passwd file is shadowed |
You shouldn't modify the password of the user with this method, use File_Passwd_Unix::changePasswd() instead.
You should use this method only if the 'name map' is used, too.
the user to modify
an associative array of properties to modify
Возвращает TRUE при удаче и PEAR_Error в обратном случае.
Таблица 38-1. Возможные значения PEAR_Error
Error Code | Summary |
---|---|
FILE_PASSWD_E_EXISTS_NOT | user doesn't exists |
FILE_PASSWD_E_INVALID_CHARS | any of the extra properties contains a colon |
the user whose password should be changed
the new plaintext password
Возвращает TRUE при удаче и PEAR_Error в обратном случае.
Таблица 38-1. Возможные значения PEAR_Error
Error Code | Summary |
---|---|
FILE_PASSWD_E_EXISTS_NOT | user doesn't exist |
FILE_PASSWD_INVALID_ENC_MODE | actual encryption mode is not supported |
FILE_PASSWD_UNDEFINED | if passwd file is shadowed |
the user whose password should be verified
the password to verify
Returns TRUE if passwords equal, FALSE if they don't or PEAR_Error on failure.
Таблица 38-1. Возможные значения PEAR_Error
Error Code | Summary |
---|---|
FILE_PASSWD_E_EXISTS_NOT | user doesn't exist |
FILE_PASSWD_E_INVALID_ENC_MODE | actual encryption mode isn't spported |
Whether to use the 'name map' of the extra properties or not.
Default Unix passwd files look like: user:password:user_id:group_id:gecos:home_dir:shell
The default 'name map' for properties except user and password looks like:
uid
gid
gecos
home
shell
Returns boolean TRUE if you set a value, or the actual value if called without param.
Set the 'name map' to use with the extra properties of the user.
This map is used for naming the associative array of the extra properties.
Возвращает TRUE при удаче и PEAR_Error в обратном случае.
Returns PEAR_Error FILE_PASSWD_E_PARAM_MUST_BE_ARRAY, if the supplied 'name map' was not of type array.
Set encryption mode to use.
Supported encryption modes are 'des' and 'md5'.
You can use the constants FILE_PASSWD_MD5 and FILE_PASSWD_DES for this purpose.
Возвращает TRUE при удаче и PEAR_Error в обратном случае.
Returns PEAR_Error FILE_PASSWD_E_INVALID_ENC_MODE, if supplied encryption mode is not supported.
Returns boolean whether passwords of this passwd file are shadowed in another file.
Generate a "Un*x" style password.
The encryption mode can be of any type File_Passwd provides, although FILE_PASSWD_MD5 and FILE_PASSWD_DES are the most common.
the plaintext password to encrypt
the encryption mode to use
the salt to use for encryption (usually empty)
Returns string encrypted password, or PEAR_Error FILE_PASSWD_E_INVALID_ENC_MODE if encryption mode is not supported.
Пример 38-1. File_Passwd_Unix::generatePassword()
|
Manipulate CVS pserver passwd files. (inherited methods)
path to passwd file
user to authenticate
plaintext password
Returns TRUE if authenticated, FALSE if not or PEAR_Error on failure.
Таблица 38-1. Возможные значения PEAR_Error
Error Code | Summary |
---|---|
FILE_PASSWD_E_NOT_EXISTS | passwd file doesn't exist |
FILE_PASSWD_E_FILE_NOT_OPENED | passwd file couldn't be opened in read mode |
FILE_PASSWD_E_FILE_NOT_LOCKED | passwd file couldn't be locked shared |
FILE_PASSWD_E_FILE_NOT_UNLOCKED | passwd file couldn't be unlocked (only if auth fails) |
FILE_PASSWD_E_FILE_NOT_CLOSED | passwd file couldn't be closed /only if auth fails) |
Parse the CVS passwd file. (для разработчиков)
This usually happens in File_Passwd_Cvs::load() .
Возвращает TRUE при удаче и PEAR_Error в обратном случае.
Returns PEAR_Error FILE_PASSWD_E_INVALID_FORMAT, if passwd file has invalid format.
Возвращает TRUE при удаче и PEAR_Error в обратном случае.
Таблица 38-1. Возможные значения PEAR_Error
Error Code | Summary |
---|---|
FILE_PASSWD_E_DIR_NOT_CREATED | directory in which the passwd file should reside couldn't be created |
FILE_PASSWD_E_FILE_NOT_OPENED | passwd file couldn't be opened in write mode |
FILE_PASSWD_E_FILE_NOT_LOCKED | passwd file couldn't be locked exclusively |
FILE_PASSWD_E_FILE_NOT_UNLOCKED | passwd file couldn't be unlocked |
FILE_PASSWD_E_FILE_NOT_CLOSED | passwd file couldn't be closed |
The username must start with an alphabetical character and must NOT contain any other characters than alphanumerics, the underline and dash.
the name of the user to add
the password of the user tot add
the systemuser this user maps to
Возвращает TRUE при удаче и PEAR_Error в обратном случае.
Таблица 38-1. Возможные значения PEAR_Error
Error Code | Summary |
---|---|
FILE_PASSWD_E_EXISTS_ALREADY | user already exists |
FILE_PASSWD_E_INVALID_CHARS | user or system_user contain illegal characters |
the user to change the system user for
the new system user name
Возвращает TRUE при удаче и PEAR_Error в обратном случае.
Таблица 38-1. Возможные значения PEAR_Error
Error Code | Summary |
---|---|
FILE_PASSWD_E_EXISTS_NOT | user doesn't exist |
FILE_PASSWD_E_INVALID_CHARS | system user contains illegal characters |
the user whose password should be changed
the new plaintext password
$return.success-pearerror;
Returns PEAR_Error FILE_PASSWD_E_EXISTS_ALREADY, if user already exists.
user whose password should be verified
the plaintext password that should be verified
Returns TRUE if passwords equal, FALSE if the don't or PEAR_Error on failure.
Returns PEAR_Error FILE_PASSWD_E_EXISTS_NOT, if user doesn't exist.
the plaintext password to encrypt
the salt to use for encryption (usually empty)
Пример 38-1. File_Passwd_Cvs::generatePassword()
|
Manipulate SMB server passwd files. (inherited methods)
path to passwd file
user to authenticate
plaintext password
encryption mode ('nt'|'lm') NTHASH or LMHASH
Returns TRUE if authenticated, FALSE if not or PEAR_Error on failure.
Таблица 38-1. Возможные значения PEAR_Error
Error Code | Summary |
---|---|
FILE_PASSWD_E_NOT_EXISTS | passwd file doesn't exist |
FILE_PASSWD_E_FILE_NOT_OPENED | passwd file couldn't be opened in read mode |
FILE_PASSWD_E_FILE_NOT_LOCKED | passwd file couldn't be locked shared |
FILE_PASSWD_E_FILE_NOT_UNLOCKED | passwd file couldn't be unlocked (only if auth fails) |
FILE_PASSWD_E_FILE_NOT_CLOSED | passwd file couldn't be closed /only if auth fails) |
FILE_PASSWD_E_INVALID_ENC_MODE | supplied encryption mode was invalid |
Parse the SMB passwd file. (для разработчиков)
This usually happens in File_Passwd_Smb::load() .
Возвращает TRUE при удаче и PEAR_Error в обратном случае.
Returns PEAR_Error FILE_PASSWD_E_INVALID_FORMAT, if passwd file has invalid format.
Возвращает TRUE при удаче и PEAR_Error в обратном случае.
Таблица 38-1. Возможные значения PEAR_Error
Error Code | Summary |
---|---|
FILE_PASSWD_E_DIR_NOT_CREATED | directory in which the passwd file should reside couldn't be created |
FILE_PASSWD_E_FILE_NOT_OPENED | passwd file couldn't be opened in write mode |
FILE_PASSWD_E_FILE_NOT_LOCKED | passwd file couldn't be locked exclusively |
FILE_PASSWD_E_FILE_NOT_UNLOCKED | passwd file couldn't be unlocked |
FILE_PASSWD_E_FILE_NOT_CLOSED | passwd file couldn't be closed |
the user/machine to add
the new plaintext password
additional properties of account:
userid
flags
lct
comment
whether to add an machine account
Возвращает TRUE при удаче и PEAR_Error в обратном случае.
Таблица 38-1. Возможные значения PEAR_Error
Error Code | Summary |
---|---|
FILE_PASSWD_E_EXISTS_ALREADY | account already exists |
FILE_PASSWD_E_INVALID_CHARS | user/machine name contains illegal characters |
Modify a certain user.
You shouldn't modify the password with this method, use File_Passwd_Smb::changePasswd() instead.
Возвращает TRUE при удаче и PEAR_Error в обратном случае.
Таблица 38-1. Возможные значения PEAR_Error
Error Code | Summary |
---|---|
FILE_PASSWD_E_EXISTS_NOT | account doesn't exist |
FILE_PASSWD_E_INVALID_PROPERTY | any supplied property was invalid |
Возвращает TRUE при удаче и PEAR_Error в обратном случае.
Returns PEAR_Error FILE_PASSWD_E_EXISTS_NOT, if user doesn't exist.
Returns TRUE if passwds equal, FALSE if they don't or PEAR_Error on failure.
Таблица 38-1. Возможные значения PEAR_Error
Error Code | Summary |
---|---|
FILE_PASSWD_E_EXISTS_NOT | user doesn't exist |
FILE_PASSWD_E_UNDEFINED | if account is disabled |
Verify the encrypted password of an user/machine.
We prefer NT-Hash instead of weak LAN-Manager-Hash.
Returns TRUE if passwds equal, FALSE if they don't or PEAR_Error on failure.
Таблица 38-1. Возможные значения PEAR_Error
Error Code | Summary |
---|---|
FILE_PASSWD_E_EXISTS_NOT | user doesn't exist |
FILE_PASSWD_E_UNDEFINED | if account is disabled |
Generate a "Samba" server style password.
The encryption mode can either be FILE_PASSWD_NT or FILE_PASSWD_LM.
Пример 38-1. File_Passwd_Smb::generatePassword()
|
Manipulate AuthUserFiles. (inherited methods)
path to passwd file
user to authenticate
plaintext password
des, sha or md5
Returns TRUE if authenticated, FALSE if not or PEAR_Error on failure.
Таблица 38-1. Возможные значения PEAR_Error
Error Code | Summary |
---|---|
FILE_PASSWD_E_NOT_EXISTS | passwd file doesn't exist |
FILE_PASSWD_E_FILE_NOT_OPENED | passwd file couldn't be opened in read mode |
FILE_PASSWD_E_FILE_NOT_LOCKED | passwd file couldn't be locked shared |
FILE_PASSWD_E_FILE_NOT_UNLOCKED | passwd file couldn't be unlocked (only if auth fails) |
FILE_PASSWD_E_FILE_NOT_CLOSED | passwd file couldn't be closed /only if auth fails) |
Parse the AuthUserFile. (для разработчиков)
This usually happens in File_Passwd_Authbasic::load() .
Возвращает TRUE при удаче и PEAR_Error в обратном случае.
Таблица 38-1. Возможные значения PEAR_Error
Error Code | Summary |
---|---|
FILE_PASSWD_E_INVALID_FORMAT | passwd file has invalid format |
Возвращает TRUE при удаче и PEAR_Error в обратном случае.
Таблица 38-1. Возможные значения PEAR_Error
Error Code | Summary |
---|---|
FILE_PASSWD_E_DIR_NOT_CREATED | directory in which the passwd file should reside couldn't be created |
FILE_PASSWD_E_FILE_NOT_OPENED | passwd file couldn't be opened in write mode |
FILE_PASSWD_E_FILE_NOT_LOCKED | passwd file couldn't be locked exclusively |
FILE_PASSWD_E_FILE_NOT_UNLOCKED | passwd file couldn't be unlocked |
FILE_PASSWD_E_FILE_NOT_CLOSED | passwd file couldn't be closed |
The username must start with an alphabetical character and must NOT contain any other characters than alphanumerics, the underline and dash.
Возвращает TRUE при удаче и PEAR_Error в обратном случае.
Таблица 38-1. Возможные значения PEAR_Error
Error Code | Summary |
---|---|
FILE_PASSWD_E_EXISTS_ALREADY | the user to add already exists |
FILE_PASSWD_E_INVALID_CHARS | the username to add contains illegal characters |
the user whose password should be changed
the new plaintext password
Возвращает TRUE при удаче и PEAR_Error в обратном случае.
Таблица 38-1. Возможные значения PEAR_Error
Error Code | Summary |
---|---|
FILE_PASSWD_E_EXISTS_NOT | the user to delete doesn't exist |
the user whose password should be verified
the plaintext password to verify
Returns TRUE if passwords equal, FALSE if they don't, or PEAR_Error on failure.
Таблица 38-1. Возможные значения PEAR_Error
Error Code | Summary |
---|---|
FILE_PASSWD_E_EXISTS_NOT | user doesn't exist |
FILE_PASSWD_E_INVALID_ENC_MODE | invalid encryption mode was supplied |
You can choose one of md5, sha or des.
ATTN: DES encryption not available on Win32!
Returns a PEAR_Error if a specific encryption mode is not supported.
Returns an array of supported encryption modes.
<pre> array + md5 + sha + des </pre>
ATTN: DES encryption not available on Win32!
Generate a password usable for "AuthBasic" authentication.
The encryption mode can either be FILE_PASSWD_DES, FILE_PASSWD_SHA or FILE_PASSWD_MD5.
the plaintext password to encrypt
the encryption mode to use
the salt to use for encryption (usually empty)
Returns string encrypted password, or PEAR_Error FILE_PASSWD_E_INVALID_ENC_MODE if encryption mode is not supported.
Пример 38-1. File_Passwd_Authbasic::generatePassword()
|
Manipulate AuthDigestFiles. (inherited methods)
path to passwd file
user to authenticate
plaintext password
the realm the user should be in
Returns TRUE if authenticated, FALSE if not or PEAR_Error on failure.
Таблица 38-1. Возможные значения PEAR_Error
Error Code | Summary |
---|---|
FILE_PASSWD_E_NOT_EXISTS | passwd file doesn't exist |
FILE_PASSWD_E_FILE_NOT_OPENED | passwd file couldn't be opened in read mode |
FILE_PASSWD_E_FILE_NOT_LOCKED | passwd file couldn't be locked shared |
FILE_PASSWD_E_FILE_NOT_UNLOCKED | passwd file couldn't be unlocked (only if auth fails) |
FILE_PASSWD_E_FILE_NOT_CLOSED | passwd file couldn't be closed (only if auth fails) |
Initialize a new object of File_Passwd_Authdigest with the specified path to the AuthDigestFile.
Parse the AuthDigestFile. (для разработчиков)
This usually happens in File_Passwd_Authdigest::load() .
Возвращает TRUE при удаче и PEAR_Error в обратном случае.
Таблица 38-1. Возможные значения PEAR_Error
Error Code | Summary |
---|---|
FILE_PASSWD_E_INVALID_FORMAT | AuthDigestFile has invalid format |
Возвращает TRUE при удаче и PEAR_Error в обратном случае.
Таблица 38-1. Возможные значения PEAR_Error
Error Code | Summary |
---|---|
FILE_PASSWD_E_DIR_NOT_CREATED | directory in which the passwd file should reside couldn't be created |
FILE_PASSWD_E_FILE_NOT_OPENED | passwd file couldn't be opened in write mode |
FILE_PASSWD_E_FILE_NOT_LOCKED | passwd file couldn't be locked exclusively |
FILE_PASSWD_E_FILE_NOT_UNLOCKED | passwd file couldn't be unlocked |
FILE_PASSWD_E_FILE_NOT_CLOSED | passwd file couldn't be closed |
Add an user to the AuthDigestFile.
$user and $realm must start with an alphabetical charachter and must NOT contain any other characters than alphanumerics, the underline and dash.
the user to add
the realm the user should be in
the plaintext password
Возвращает TRUE при удаче и PEAR_Error в обратном случае.
Таблица 38-1. Возможные значения PEAR_Error
Error Code | Summary |
---|---|
FILE_PASSWD_E_EXISTS_ALREADY | user already exists in the supplied realm |
FILE_PASSWD_E_INVLAID_CHARS | user or realm contains illegal characters |
Change the password of a certain user in a specific realm.
This method in fact adds the user whith the new password after deleting the user.
the user whose password should be changed
the realm the user is in
the new plaintext password
Возвращает TRUE при удаче и PEAR_Error в обратном случае.
Таблица 38-1. Возможные значения PEAR_Error
Error Code | Summary |
---|---|
FILE_PASSWD_E_USER_NOT_IN_REALM | user doesn't exist in the supplied realm |
FILE_PASSWD_E_INVALID_CHARS | user or realm contains illegal characters |
the user whose password should be verified
the realm the user is in
the plaintext password to verify
Retruns TRUE if passwords equal, FALSE if they don't, or PEAR_Error on failure.
Таблица 38-1. Возможные значения PEAR_Error
Error Code | Summary |
---|---|
FILE_PASSWD_E_USER_NOT_IN_REALM | the specified user doesn't exist in the supplied realm |
Возвращает TRUE при удаче и PEAR_Error в обратном случае.
Таблица 38-1. Возможные значения PEAR_Error
Error Code | Summary |
---|---|
FILE_PASSWD_E_USER_NOT_IN_REALM | user doesn't exist in the supplied realm |
Returns array:
associative array of users of ONE realm if $inRealm was supplied <pre> realm1 + user1 => pass + user2 => pass + user3 => pass </pre>
associative array of all realms with all users <pre> array + realm1 => array + user1 =&gt; pass + user2 =&gt; pass + user3 =&gt; pass + realm2 => array + user3 =&gt; pass + realm3 => array + user1 =&gt; pass + user2 =&gt; pass </pre>
Returns TRUE if user is in realm, FALSE if not or PEAR_Error on failure.
Таблица 38-1. Возможные значения PEAR_Error
Error Code | Summary |
---|---|
FILE_PASSWD_E_EXISTS_NOT | specified realm doesn't exist |
the username
the realm the user is in
the plaintext password
Пример 38-1. File_Passwd_Authdigest::generatePassword()
|
This package offers methods for reading and writing IDv1-information tags of MP3 files.
Таблица 38-1. Constants
Name | Value | Meaning |
---|---|---|
PEAR_MP3_ID_FNO | 1 | Error code: file not found |
PEAR_MP3_ID_NOMP3 | 4 | Error code: file is not a MP3 file |
PEAR_MP3_ID_RE | 2 | Error code: read error |
PEAR_MP3_ID_TNF | 3 | Error code: Tag not found |
Return the name of a genre number, if no genre number is specified the genre number found in the file will be used.
Name of the genre
The value to return in case of genre not found
Таблица 38-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
PEAR_MP3_ID_FNO | "Unable to open $file" | The provide file name could not be opened | The file is currently write protected or doesn't exists. |
PEAR_MP3_ID_RE | "Unable to see to end - 128 of $file" or "Unable to see to end of $file" | A read error occured | The file is too short or empty - not a MP3 file or a corrupted one. |
Таблица 38-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
PEAR_MP3_ID_FNO | "Unable to open $file" | The provide file name could not be opened | The file is currently write protected or doesn't exists. |
PEAR_MP3_ID_RE | "Unable to see to end - 128 of $file" or "Unable to see to end of $file" | A read error occured | The file is too short or empty - not a MP3 file or a corrupted one. |
Sets a field
Таблица 38-1. Possible names of tags are:
Tag | Meaning |
---|---|
name | Title of the content |
artists | Name of band or artist |
album | Name of the album |
year | publishing year of the album or song |
comment | song comment |
track | the number of the track |
genre | genre of the song |
genreno | Number of the genre |
Name of the tag to set or hash with the key as fieldname
the value to set
Таблица 38-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
PEAR_MP3_ID_NOMP3 | "No mpeg frame found" | The file have no MP3 file structure. | The file is not a MP3 file. |
Таблица 38-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
PEAR_MP3_ID_FNO | "Unable to open $file" | The provide file name could not be opened | The file is currently write protected or doesn't exists. |
PEAR_MP3_ID_RE | "Unable to see to end - 128 of $file" or "Unable to see to end of $file" | A read error occured | The file is too short or empty - not a MP3 file or a corrupted one. |
Package for generating Excel spreadsheets
Spreadsheet_Excel_Writer is a tool for creating Excel files without the need for COM components. The files generated by the current version of Spreadsheet_Excel_Writer correspond to the Excel 5 (BIFF5) format, so all functionality until that version of Excel (but not beyond) should be available.
The most common use for Spreadsheet_Excel_Writer will be spitting out large (or not so large) amounts of information in the form of a spreadsheet, which is easy to manipulate with a fairly ubiquitous spreadsheet program such as Excel (or OpenOffice).
So let's cut to the chase and see how this is done:
Пример 38-1. Typical usage
|
The first thing you should notice, is that we created a workbook before any worksheets. All worksheets are contained within a workbook, and a workbook may contain several worksheets.
Another important thing, which you should have in mind when programming with Spreadsheet_Excel_Writer, is that ampersand sign (&) that appears when we created our worksheet. That ampersand means we are referencing a Worksheet object instead of copying it. If you don't know what that means, don't worry, all you have to remember is to always use ampersands when calling addWorksheet() for creating a worksheet, or addFormat() for creating a format.
You may have noticed also the following line:
// sending HTTP headers $workbook->send('test.xls'); |
For example, if we wanted to save the same spreadsheet we created in our first example to a file named 'test.xls', we would do it like so:
Пример 38-2. Saving to a regular file
|
If you would like to learn about formatting (fonts, cell color, text alignment, etc...) with Spreadsheet_Excel_Writer, you can check the formatting tutorial here.
A format is an object of type Spreadsheet_Excel_Writer_Format. This format can be applied to cells inside a spreadsheet so that these cells inherit the properties of the format (text alignment, background color, border colors, etc...).
Formats can't be created directly by a new call. You have to create a format using the addFormat() method from a Workbook, which associates your Format with this Workbook (you can't use the Format with another Workbook).
Let's see how addFormat() is used:
Пример 38-1. addFormat usage
|
There, we just created a bold format. Notice the ampersand sign (&) that appears when we created our format. If you don't create your format like that it will appear as if all the format's properties you set are ignored.
Well, we just created our first format, but we didn't use it. Not very smart. So let's do something useful with a format.
Let's say you want to make your regular data filled spreadsheet. Only this
time, when you proudly present your beautiful creation to your boss, the
thing you most dread happens:
Pointy haired boss - Mmmmhhh, seems OK. You - Yes, I added those totals as you
requested. Pointy haired boss - Mmmmhhh, you know, there's
going to be a lot of customers using this spreadsheet... You - So... Pointy haired boss - Mmmmhhh, what do you think of
changing the style for those headers there? You - ...
Of course it won't be just those headers: "why don't we center this title
here?", "Could you merge those cells over there?", "what do you think of
using the company's colors for those titles?".
There are a number of ways for dealing with this situation, but in this tutorial we will stick to the one which will keep your job.
So let's begin work on the spreadsheet for DotCom.com.
Пример 38-2. First example
|
There. Now all of those VC's out there are going to be calling like crazy asking for an oportunity to invest on DotCom.com. Wait a minute. These are not regular VC's we are talking about. These are very selective guys who wouldn't trust their money to the first start-up they happen to see on the internet. I know! Let's put the company's colors in there!
Пример 38-3. Second example
|
If you just tested the previous example you might have noticed that the title would need several cells to be seen correctly, but the format we applied only works for the first cell. So our title does not look very nice.
What can we do to fix that? Well, you could tell your boss that the title looks ok to you, and that he really needs to visit an ophthalmologist. Or you could use cell merging in order to make the title spread over several cells.
For this you have to use the setAlign() method with 'merge' as argument, and create some empty cells so the title can 'use' them as a sort of background (there will be a better way to do this in a future version of Spreadsheet_Excel_Writer).
Applying merging to our example script, we would have this:
Пример 38-4. Merging cells
|
Calls finalization methods for the workbook. This method should always be the last one to be called on every workbook.
Add a new worksheet to the Excel workbook. If no name is given the name of the worksheet will be Sheeti with i in [1..].
Пример 38-1. Using &addWorksheet()
|
Add a new format to the Excel workbook. Also, pass any properties to the Format constructor. Valid properties are:
Align
Bold
Bottom
Top
Left
Right
Border
BorderColor
BottomColor
TopColor
RightColor
LeftColor
FgColor
BgColor
Color
Pattern
Underline
TextRotation
Size
NumFormat
Script
Пример 38-1. Using &addFormat()
|
Sets the temp dir used for storing the OLE file. Use this method if you don't have the right to write in the default temporary dir.
Пример 38-1. Using &setTempDir()
|
Change the RGB components of the elements in the colour palette. The new color, defined by the given RGB components, will "overwrite" the color previously defined for the given index.
integer $index - colour index
integer $red - red RGB value [0-255]
integer $green - green RGB value [0-255]
integer $blue - blue RGB value [0-255]
Пример 38-1. Using setCustomColor()
|
It allows writing for different charsets by setting the worksheet's "current" charset. It has been tested for UTF-8, ISO-8859-7. It requires iconv for any charset other than UTF-16LE.
string $encoding - The encoding. It suports all encodings supported by php's iconv() function.
Пример 38-1. Using setInputEncoding()
|
Set this worksheet as the active worksheet, i.e. the worksheet that is displayed when the workbook is opened. Also set it as selected.
Set this worksheet as the first visible sheet. This is necessary when there are a large number of worksheets and the activated worksheet is not visible on the screen.
Set the worksheet protection flag to prevent accidental modification and to hide formulas if the locked and hidden format properties have been set.
integer $firstcol - first column on the range
integer $lastcol - last column on the range
float $width - width to set
mixed $format - The optional XF format to apply to the columns
integer $hidden - The optional hidden atribute
Пример 38-1. Using setColumn()
|
integer $first_row - first row in the selected quadrant
integer $first_column - first column in the selected quadrant
integer $last_row - last row in the selected quadrant
integer $last_column - last column in the selected quadrant
Set panes and mark them as frozen. One can use this method to mark certain regions in the worksheet so that they are "frozen" in the sense that when scrolling through the worksheet these regions are not affected by the scrolling and remain where they are on the screen. This is the same functionality as provided by Microsoft Excel through the + menu command.
array $panes - This is the only parameter received and is composed of the following: 0 => Vertical split position, 1 => Horizontal split position 2 => Top row visible 3 => Leftmost column visible 4 => Active pane
Пример 38-1. Using freezePanes()
If one needs to further specify the scrolling region, the following syntax can be used:
|
array $panes - This is the only parameter received and is composed of the following: 0 => Vertical split position, 1 => Horizontal split position 2 => Top row visible 3 => Leftmost column visible 4 => Active pane
Пример 38-1. Using repeatRows()
|
integer $first_col - First column to repeat
integer $last_col - Last column to repeat. Optional.
integer $first_row - First row of the area to print
integer $first_col - First column of the area to print
integer $last_row - Last row of the area to print
integer $last_col - Last column of the area to print
Пример 38-1. Using hideGridlines()
|
Store the vertical and horizontal number of pages that will define the maximum area printed. It doesn't seem to work with OpenOffice.
integer $width - Maximun width of printed area in pages
integer $height - Maximun heigth of printed area in pages
Store the horizontal page breaks on a worksheet (for printing). The breaks represent the row after which the break is inserted.
Store the vertical page breaks on a worksheet (for printing). The breaks represent the column after which the break is inserted.
integer $row - The row of the cell we are writing to
integer $col - The column of the cell we are writing to
mixed $token - What we are writing
mixed $format - The optional format to apply to the cell
Write a double to the specified row and column (zero indexed). An integer can be written as a double. Excel will display an integer. $format is optional. Returns 0 : normal termination -2 : row or column out of range
integer $row - Zero indexed row
integer $col - Zero indexed column
float $num - The number to write
mixed $format - The optional XF format
Write a string to the specified row and column (zero indexed). NOTE: there is an Excel 5 defined limit of 255 characters. $format is optional. Returns 0 : normal termination -1 : insufficient number of arguments -2 : row or column out of range -3 : long string truncated to 255 chars
integer $row - Zero indexed row
integer $col - Zero indexed column
string $str - The string to write
mixed $format - The XF format for the cell
Writes a note associated with the cell given by the row and column. NOTE records don't have a length limit.
integer $row - Zero indexed row
integer $col - Zero indexed column
string $note - The note to write
Write a blank cell to the specified row and column (zero indexed). A blank cell is used to specify formatting without adding a string or a number. A blank cell without a format serves no purpose. Therefore, we don't write a BLANK record unless a format is specified. This is mainly an optimisation for the write_row() and write_col() methods. Returns 0 : normal termination (including no format) -1 : insufficient number of arguments -2 : row or column out of range
integer $row - Zero indexed row
integer $col - Zero indexed column
mixed $format - The XF format
Пример 38-1. Using writeBlank()
|
Write a formula to the specified row and column (zero indexed). In case of error it will write the error message (instead of the formula) in the corresponding row and column.
integer $row - Zero indexed row
integer $col - Zero indexed column
string $formula - The formula text string
mixed $format - The optional XF format
integer - 0 for normal termination, -1 for an error in the formula, -2 for row or column out of range.
Эта функция не должна вызываться статически.
Formulas must start with an equal sign ('=').
Arguments given to an Excel function should be separated by comas (','), not by semicolons (';').
Пример 38-1. Using writeFormula()
|
Write a hyperlink. This is comprised of two elements: the visible label and the invisible link. The visible label is the same as the link unless an alternative string is specified. The label is written using the writeString() method. Therefore the 255 characters string limit applies. $string and $format are optional and their order is interchangeable. The hyperlink can be to a http, ftp, mail, internal sheet, or external directory url. Returns 0 : normal termination -1 : insufficient number of arguments -2 : row or column out of range -3 : long string truncated to 255 chars
integer $row - Row
integer $col - Column
string $url - URL string
string $string - Alternative label
mixed $format - The cell format
integer $row - The row to set
integer $height - Height we are giving to the row. Use NULL to set XF without setting height
mixed $format - XF format we are giving to the row
This is an Excel97/2000 method. It is required to perform more complicated merging than the normal setAlign('merge'). It merges the area given by its arguments.
integer $first_row - First row of the area to merge
integer $first_col - First column of the area to merge
integer $last_row - Last row of the area to merge
integer $last_col - Last column of the area to merge
Insert a 24bit bitmap image in a worksheet. The main record required is IMDATA but it must be proceeded by a OBJ record to define its position.
integer $row - The row we are going to insert the bitmap into
integer $col - The column we are going to insert the bitmap into
string $bitmap - The bitmap filename
integer $x - The horizontal position (offset) of the image inside the cell.
integer $y - The vertical position (offset) of the image inside the cell.
integer $scale_x - The horizontal scale
integer $scale_y - The vertical scale
This method sets the properties for outlining and grouping. The defaults correspond to Excel's defaults.
integer $row - Row for the cell to convert (0-indexed).
integer $col - Column for the cell to convert (0-indexed).
Пример 38-1. Using rowcolToCell()
|
string $location - alignment for the cell
Horizontal Alignments (pick one): left, center, right, fill, justify, merge, equal_space.
Vertical Alignments (pick one): top, vcenter, bottom, vjustify, vequal_space.
To implement a combination of Horizontal and Vertical Alignments, call this method two times.
Пример 38-1. Using setAlign()
|
Пример 38-1. Using setVAlign()
|
string $location - alignment for the cell
left, center, right, fill, justify, merge, equal_space.
Пример 38-1. Using setHAlign()
|
Sets the boldness of the text. Bold has a range 100..1000. 0 (400) is normal. 1 (700) is bold.
integer $weight - Weight for the text, 0 maps to 400 (normal text) 1 maps to 700 (bold text). Valid range is: 100-1000 It's Optional, default is 1 (bold).
Пример 38-1. Using setBottom()
|
Пример 38-1. Using setTop()
|
Пример 38-1. Using setLeft()
|
Пример 38-1. Using setRight()
|
mixed $color - The color we are setting. Either a string (like 'blue'), or an integer (range is [8...63]).
Please see the "Using colors" section of the manual for more information.
Пример 38-1. Using setBorderColor()
|
mixed $color - either a string (like 'blue'), or an integer (range is [8...63]).
Please see the "Using colors" section of the manual for more information.
mixed $color - either a string (like 'blue'), or an integer (range is [8...63]).
Please see the "Using colors" section of the manual for more information.
mixed $color - either a string (like 'blue'), or an integer (range is [8...63]).
Please see the "Using colors" section of the manual for more information.
mixed $color - either a string (like 'blue'), or an integer (range is [8...63]).
Please see the "Using colors" section of the manual for more information.
Sets the cell's "foreground color".
The term "foreground color" is misleading. Here, "foreground" means the top layer of a cell's background. To set the color of a cell's contents, use the setColor() method.
The color actually seen may depend on the pattern and background color being used.
The example entitled "How background and foreground colors interact with patterns" is very helpful.
mixed $color - either a string (like 'blue'), or an integer (range is [8...63]).
See the "Using colors" section, below, for more information.
The following colors can be defined by name: black, white, red, green, blue, yellow, magenta and cyan.
To learn what the other indexed colors look like, read Color Palette and the 56 Excel ColorIndex Colors. Beware that the color indexes listed there are displaced by 1 with respect to those used by Spreadsheet_Excel_Writer.
If the predifined colors don't meet your requirements, use the setCustomColor() method.
Пример 38-1. Using setFgColor()
|
Sets the cell's "background color".
The term "background color" is misleading. Here, "background" means the bottom layer of a cell's background.
This method only comes into play when creating patterns via the setPattern() method. In general, chances are you are more interested in using the setFgColor() method.
The example entitled "How background and foreground colors interact with patterns" is very helpful.
mixed $color - either a string (like 'blue'), or an integer (range is [8...63]).
Please see the "Using colors" section of the manual for more information.
Пример 38-1. Using setBgColor()
|
mixed $color - either a string (like 'blue'), or an integer (range is [8...63]).
Please see the "Using colors" section of the manual for more information.
Sets the fill pattern attribute of a cell. Use in combination with the setBgColor() and setFgColor() methods.
The example entitled "How background and foreground colors interact with patterns" is very helpful.
integer $arg - Optional. Defaults to 1. Meaningful values are: 0-18. 0 = no background. 1 = solid "background" using the color set by setFgColor().
Пример 38-1. How background and foreground colors interact with patterns
|
integer $underline - The value for underline. Possible values are 1 => underline, 2 => double underline.
Пример 38-1. Using setUnderline()
|
Пример 38-1. Using setSize()
|
integer $angle - The rotation angle for the text (clockwise). Possible values are: 0, 90, 270 and -1 for stacking top-to-bottom.
Sets the numeric format. It can be date, time, currency, etc... The following table lists possible values for $num_format and the corresponding types that a numeric format expects as arguments.
Таблица 38-1. Numeric formats and types
0 | Decimal | The amount of zeros specifies the amount of digits that will be shown |
0.00 | Decimal | The amount of zeros after the decimal dot specifies the amount of decimal digits that will be shown |
#.## | Decimal | The amount of sharp signs after the decimal dot specifies the maximum amount of decimal digits that will be shown |
0% | Percent | The amount of zeros specifies the amount of digits that will be shown. |
0.000% | Percent | The amount of zeros after the decimal dot specifies the amount of decimal digits that will be shown. |
$#.#;[Red]($#.#) | Currency | Zeros and sharp signs have the same meaning as in other formats. |
??/?? | Fraction | The amount of question signs in the denominator determines its precision (maximum amount of digits in the denominator). |
# ??/?? | Fraction | A fraction with an integer part. Zeros and sharp signs are used for defining the integer part, and they have the same meaning as in other formats. |
0.00E+# | Scientific | In scientific notation base and exponent are formated according to the same rules applied to decimals. For scientific notation zeros and sharp signs appear to be equivalent. |
D-MMM-YY | Date | A date represented in the given notation. Month can be a one or two digits month, or a three letter month. Year can have 2 or 4 digits. The argument to be formated as a date is considered to be the number of days since December 30 1899 (Excel's day zero). For dates preceding day zero, negative numbers can be used. |
D/M/YYYY h:mm:ss | Date/Time | A date represented in the given notation. The argument to be formated as a date is considered to be the number of days since Excel's day zero. |
h:mm:ss AM/PM | Time | A time represented in the given notation. Be careful, the argument to be formated as a time has to be given in days. For example an argument of 0.5 would be presented as '12:00:00 PM'. |
The information here presented comes from OpenOffice.org's Documentation of the Microsoft Excel File Format (http://sc.openoffice.org/excelfileformat.pdf).
Пример 38-1. Using setNumFormat()
|
integer $script - The value for script type. Possible values are 1 => superscript, 2 => subscript.
Пример 38-1. Using setScript()
|
string $font_family - The font family name. Possible values are: 'Times New Roman', 'Arial', 'Courier'.
Пример 38-1. Using setFontFamily()
|
Предоставляет пакеты для работы с файлами и файловой системой.
Archive_Tar provides an API for handling (compressed) Tar archives.
The constructor declares a new Archive_Tar object, identifying it by the name of the tar file.
string $tarname - the name of the tar archive to work with
mixed $compress - if TRUE, indicates that the archive is compressed (using gzip). if NULL the archive is not compressed, if 'gz' or 'bz2', indicates that the archive is compressed with gzip or bz2. For compatibility reason the boolean value TRUE means 'gz'.
This method adds files and directories to an existing archive. If the archive does not exist, it attempts to create it. The files and directories listed are added at the end of the archive, even if a file with the same name is already archived.
mixed $filelist - an array of filenames and directory names, or a single string with names separated by a single blank space. For each directory added in the archive, the files and sub-directories are also added.
Таблица 39-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
NULL | "Invalid file list" | The argument for the function is not correct formatted or build. | Check for typing mistakes in the argument |
Пример 39-1. Add files to a compressed archive
|
This methods add files and directories listed in filelist at the end of the existing archive.
If the archive does not exists it attempts to create it. If a file or directory is already in the archive it will only be added at the end of the archive. There is no update of the existing archived file or directory. However while extracting the archive, the last file will replace the first one. This results in a none optimization of the archive size. If a file or directory does not exists, it is ignored.
mixed $filelist - an array of filenames and directory names, or a single string with names separated by a single blank space.
string $add_dir - a string which contains a path to be added to the memorized path of each element in the list.
string $remove_dir - a string which contains a path to be removed from the memorized path of each element in the list, when relevant.
The path indicated in add_dir will be added at the beginning of the memorized path of each file/directory listed. However it can be set to empty ''. The adding of a path is done after the removing of path. The path add/remove ability enables the user to prepare an archive for extraction in a different path than the original path.
Таблица 39-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
NULL | "Invalid file list" | The argument for the function is not correctly formatted or build. | Check for typing mistakes in the argument |
NULL | "Unable to open in write mode file name" | The file permissions for an existing file do not allow writing or the file is locked. | Check permissions and possible competive programs using the file. |
NULL | "Invalid file list" | Archive is empty or corrupted | |
NULL | "File filename does not exist" | A file you want to add to the archive does not exist. | Check for typing mistakes in the function argument. |
NULL | "Directory dirname can not be read" | A directory or a file in it you want to add to the archive does not exists or the permissions for reading the directory does not allow access. | Check for typing mistakes in the function argument and permissions. |
NULL | "Unable to open file filenamein binary read mode" | The file to add to the archive could not be read. | Check for typing mistakes in the function argument and file permissions. |
Пример 39-1. Add files to a compressed archive in a new directory
|
Пример 39-2. Add files to a compressed archive moving to a new directory
|
Пример 39-3. Add files to a compressed archive moving to a new directory (especially for Windows)
|
On Windows system, Windows path format can be used. However if the files are using a Windows path, the $remove_dir parameter must also be in Windows path format. The $add_dir parameter can be in Windows or Unix path format.
This method creates the archive file and adds the listed files or directories.
If a file with the same tar name exists and is writable, it is replaced by the new tar archive (it is not an 'add', but a 'create'). If a file exists and is write-protected or is a folder, the method raises a PEAR_Error.
mixed $filelist - an array of filenames and directory names, or a single string with names separated by a single blank space. For each directory added in the archive, the files and sub-directories are also added.
Таблица 39-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
NULL | "Invalid file list" | The argument for the function is not correct formatted or build. | Check for typing mistakes in the argument |
Пример 39-1. Creating an archive
|
Пример 39-2. Creating a compressed archive, use a string as create() argument
|
This method creates the archive file and adds the listed files or directories.
If the file already exists and is writable, it is replaced by the new tar. It is a 'create' and not a 'add'. If the file exists and is read-only or is a directory, it is not replaced.
mixed $filelist - an array of filenames and directory names, or a single string with names separated by a single blank space.
string $add_dir - contains a path to be added to the memorized path of each element in the list.
string $remove_dir - contains a path to be removed from the memorized path of each element in the list, when relevant. Default is an empty string.
Таблица 39-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
NULL | "Invalid file list" | The argument for the function is not correctly formatted or build. | Check for typing mistakes in the argument |
Пример 39-1. Create a new compressed archive in a new directory
|
Пример 39-2. Create a new compressed archive in a new directory (especially for Windows)
|
Extracts the files from the archive into the given path.
While extracting a file: If the file already exists it is replaced without looking for last modification date. If the file already exists and is write protected, the extraction is aborted. If a directory with the same name already exists, the extraction is aborted.
However the result can be a partial extraction that may need to be manually cleaned.
Таблица 39-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
NULL | " Unable to open in read mode archive " | The file is exclusively locked by another application. | Check for other applications working on the file. This can not be caused by a competive processing the archive with Archive_Tar |
NULL | " Unable to open in write mode archive " | The file is locked by another application. | Check for other applications working on the file. This maybe caused by a competive processing the archive with Archive_Tar |
NULL | " Invalid extract mode mode " | Implementation error | Should not occur, please set up a bug report. |
NULL | " Directory name already exists as a file " | A file is marked up as directory in the archive. | Maybe a corrupted archive. |
NULL | " File name already exists as a directory " | A directoy is marked up as file in the archive. | Maybe a corrupted archive. |
NULL | " File name already exists and is write protected. " | The archive contains a file which already exists in the destination dir and can not be overwritten. | Extract the archive to an empty directory. |
NULL | " Unable to create path for name " | One or more new nested directories could not be created in the destination directory. | Ensure that the destination directory and all nested directories have the required permissions. |
NULL | " Unable to create directory name " | A directory could not be created in the destination directory. | Ensure that the destination directory has the required permissions. |
NULL | " Error while opening name in write binary mode " | The file could not be created. | The file is possibly locked. |
NULL | " Extracted file filename does not have the correct file size filesize (size expected). Archive may be corrupted. " | Read the message. | Read the message. |
Пример 39-1. Extract compressed archive
|
This method extracts only the files from the archive that are indicated in the $filelist. These files are extracted in the current directory or in the directory indicated by the optional $path parameter.
string $filelist - an array of filenames and directory names, or a single string with names separated by a single blank space.
string $path - the path of the directory where the files and/or directory need to by extracted.
string $remove_path - part of the memorized path that can be removed if present at the beginning of the files or directories path.
Таблица 39-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
NULL | " Unable to open in read mode archive " | The file is exclusively locked by another application. | Check for other applications working on the file. This can not be caused by a competive processing the archive with Archive_Tar |
NULL | " Unable to open in write mode archive " | The file is locked by another application. | Check for other applications working on the file. This maybe caused by a competive processing the archive with Archive_Tar |
NULL | " Invalid extractlist mode mode " | Implementation error | Should not occur, please set up a bug report. |
NULL | " Directory name already exists as a file " | A file is marked up as directory in the archive. | Maybe a corrupted archive. |
NULL | " File name already exists as a directory " | A directoy is marked up as file in the archive. | Maybe a corrupted archive. |
NULL | " File name already exists and is write protected. " | The archive contains a file which already exists in the destination dir and can not be overwritten. | Extract the archive to an empty directory. |
NULL | " Unable to create path for name " | One or more new nested directories could not be created in the destination directory. | Ensure the destination directory and all nested directories have the required permissions. |
NULL | " Unable to create directory name " | A directory could not be created in the destination directory. | Ensure the destination directory has the required permissions. |
NULL | " Error while opening name in write binary mode " | The file could not be created. | The file is maybe locked. |
NULL | " Extracted file filename does not have the correct file size filesize (size expected). Archive may be corrupted. " | Read the message. | Read the message. |
Пример 39-1. Extract compressed archive
|
This method extracts all the content of the archive in the directory indicated by path. When relevant the memorized path of the files or directories can be modified by removing the remove_path path at the beginning of the file or directory path.
While extracting a file: If the file already exists it is replaced without looking for last modification date. If the file already exists and is write protected, the extraction is aborted. If a directory with the same name already exists, the extraction is aborted.
While extracting a directory, if a file with the same name already exists, the extraction is aborted. While extracting a file/directory if the destination directory exist and is write protected, or does not exist but can not be created, the extraction is aborted. If after extraction an extracted file does not show the correct stored file size, the extraction is aborted.
string $path - the path of the directory where the files and/or directories need to by extracted.
string $remove_path - part of the memorized path that can be removed if present at the beginning of the files or directories path.
Таблица 39-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
NULL | " Unable to open in read mode archive " | The file is exclusive locked by another application. | Check for other applications working on the file. This can not be caused by a competive processing the archive with Archive_Tar |
NULL | " Unable to open in write mode archive " | The file is locked by another application. | Check for other applications working on the file. This maybe caused by a competive processing the archive with Archive_Tar |
NULL | " Invalid extractmodify mode mode " | Implementation error | Should not occur, please set up a bug report. |
NULL | " Directory name already exists as a file " | A file is marked up as directory in the archive. | Maybe a corrupted archive. |
NULL | " File name already exists as a directory " | A directoy is marked up as file in the archive. | Maybe a corrupted archive. |
NULL | " File name already exists and is write protected. " | The archive contains a file which already exists in the destination dir and can not be overwritten. | Extract the archive to an empty directory. |
NULL | " Unable to create path for name " | One or more new nested directories could not be created in the destination directory. | Ensure the destination directory and all nested directories have the required rights. |
NULL | " Unable to create directory name " | A directory could not be created in the destination directory. | Ensure the destination directory has the required rights. |
NULL | " Error while opening name in write binary mode " | The file could not be created. | The file is maybe locked. |
NULL | " Extracted file filename does not have the correct file size filesize (size expected). Archive may be corrupted. " | Read the message. | Read the message. |
Пример 39-1. Extract compressed archive into a new directory ignoring the old one
|
Пример 39-2. Extract compressed archive into a new directory ignoring the old one (especilly for Windows)
|
array - each array entry represents a file or folder. The array is not sorted, so the index shows the position of the file or directory in the archive.
Each entry contains the following information:
$file['filename'] - Name and path of the file/dir.
$file['mode'] - File permissions (result of fileperms())
$file['uid'] - user id
$file['gid'] - group id
$file['size'] - filesize
$file['mtime'] - Last modification time (result of filemtime())
$file['typeflag'] - empty for file, "5" for directory
Таблица 39-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
NULL | " Unable to open in read mode archive " | The file is exclusively locked by another application. | Check for other applications working on the file. This can not be caused by a competive processing the archive with Archive_Tar |
NULL | " Invalid listcontent mode mode " | Implementation error | Should not occur, please set up a bug report. |
NULL | " Directory name already exists as a file " | A file is marked up as directory in the archive. | Maybe a corrupted archive. |
NULL | " File name already exists as a directory " | A directoy is marked up as file in the archive. | Maybe a corrupted archive. |
NULL | " File name already exists and is write protected. " | The archive contains a file which already exists in the destination dir and can not be overwritten. | Extract the archive to an empty directory. |
NULL | " Unable to create path for name " | One or more new nested directories could not be created in the destination directory. | Ensure the destination directory and all nested directories have the required rights. |
NULL | " Unable to create directory name " | A directory could not be created in the destination directory. | Ensure the destination directory has the required rights. |
NULL | " Error while opening name in write binary mode " | The file could not be created. | The file is maybe locked. |
NULL | " Extracted file filename does not have the correct file size filesize (size expected). Archive may be corrupted. " | Read the message. | Read the message. |
Пример 39-1. List archive content
|
This method extracts the file identified by path from the archive and returns it as a string. It does not use temporary files.
Таблица 39-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
NULL | " Unable to open in read mode archive " | The file is exclusive locked by another application. | Check for other applications working on the file. This can not be caused by a competive processing the archive with Archive_Tar |
NULL | " Invalid extractinstring mode mode " | Implementation error | Should not occur, please set up a bug report. |
NULL | " Error while opening name in write binary mode " | The file could not be created. | The file is maybe locked. |
NULL | " Extracted file filename does not have the correct file size filesize (size expected). Archive may be corrupted. " | Read the message. | Read the message. |
Пример 39-1. Extract a file in a string
|
This method adds the string content in the archive like a file with full filename filename.
If the archive does not exists it attempts to create it.
string $filename - the path and filename that will be associated with the added string in the archive.
string $content - the string to add in the archive as a file.
Таблица 39-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
NULL | "Unable to open in write mode file name" | The file permissions for an existing file do not allow writing or the file is locked. | Check permissions and possible competive programs using the file. |
NULL | "Unable to open file filenamein binary read mode" | The file to add to the archive could not be read. | Check for typing mistakes in the function argument and file permissions. |
Пример 39-1. Add a string in a compressed archive
|
Common file and directory routines
File provides an easy interface to PHP's builtin file and directory functions, plus some functions to deal with paths.
Пример 39-1. Using File
|
Using this mode, opened files will be truncated first and then new data will be written to them.
Пример 39-1. Using File::write()
|
Пример 39-1. Using File::close()
|
Пример 39-1. Using File::getTempDir()
|
Пример 39-1. Using File::getTempFile()
|
This method checks whether the supplied path is an absolute path (eg. "/foo/bar" or "C:\foo\bar").
Пример 39-1. Using File::isAbsolute()
This short example will output the string 'Path is absolute'. |
require_once 'File.php'; |
mixed File::read
(string $filename [, int $size = FILE_DEFAULT_READSIZE [, mixed $lock = FALSE]])
File::read() reads a specific amount of bytes from a specified file and returns them to the user.
string $filename - the file to read from
int $size - the number of bytes to read from the file (defaults to FILE_DEFAULT_READSIZE)
mixed $lock - lock type to use, FALSE if none
mixed - this function returns the requested bytes from the file if there were no errors, FALSE if it reached EOF or a PEAR_Error object if an error has occured during reading from file.
Таблица 39-1. Возможные значения PEAR_Error
Error Code | Error Value | Meaning | Solution |
---|---|---|---|
NULL | "File does not exist: $filename" | The file $filename does not exist. | Check if the path that is passed to the function is correct. |
NULL | "Failed to open file: $filename" | There are few possible things that might cause that error, usually it's caused by wrong permissions or bad sectors on the harddisk. | Check the permissions of the file (ls -l {file} on UNIX systems) and change them so the file is readable by PHP, check if the harddisk is working properly and has no bad sectors. |
Пример 39-1. Using File::read()
|
Пример 39-1. Using File::readChar()
|
Пример 39-1. Using File::readLine()
|
Пример 39-1. Using File::rewind()
|
If the path is absolute, this method returns the processed path, otherwise, it returns the path untouched.
Пример 39-1. Using File::skipRoot()
This example prints out home/foo/bar. |
string $path - the path name where the leading separator should be removed from.
string $separator - optional string that defines the separator. This parameter defaults to the value of the constant DIRECTORY_SEPARATOR that is pre-defined by PHP.
This methods returns the given path name without a leading directory separator.
Пример 39-1. Using File::stripLeadingSeparators()
This example will print home/foo/lala/. |
string $path - the path name where the trailing separator should be removed from.
string $separator - optional string that defines the separator. This parameter defaults to the value of the constant DIRECTORY_SEPARATOR that is pre-defined by PHP.
This methods returns the given path name without a trailing directory separator.
Пример 39-1. Using File:stripTrailingSeparators()
This example will print /home/foo/lala. |
Пример 39-1. Using File::unlock()
|
require_once 'File.php'; |
mixed File::write
(string $filename, string $char [, string $mode = FILE_MODE_APPEND [, mixed $lock = FALSE]])
Пример 39-1. Using File::write()
|
require_once 'File.php'; |
mixed File::writeChar
(string $filename, string $char [, string $mode = FILE_MODE_APPEND [, mixed $lock = FALSE]])
Пример 39-1. Using File::writeChar()
|
require_once 'File.php'; |
mixed File::writeLine
(string $filename, string $line [, string $mode = FILE_MODE_APPEND [, string $crlf = "\n" [, mixed $lock = FALSE]]])
Пример 39-1. Using File::writeLine()
|
Commonly needed functions to search for files and directories
All search functions use $pattern parameter to specify match for filenames. Format of the $pattern depends on value of another parameter - $pattern_type.
If value of $pattern_type is 'php', then the pattern is case-sensitive string which follows the conventions of the ereg_*-functions.
In case of 'perl' pattern type it must follow the preg_*-functions pattern format. It is recommended to use 'perl', because it is faster.
The last 'shell' mode is most simple and should be familiar to everybody with basic computer skills. It is as easy as windows approach, but has some additional concepts borrowed from the FAR Manager software. The text of the following chapter is copy/paste from it's documentation.
File masks are used to select single files and folders or groups of them. Masks may contain common valid file name symbols, wildcards ('*' and '?') and special expressions:
* | any number of characters; |
? | any single character; |
[c,x-z] | any character enclosed by the brackets. Both separate characters and character intervals are allowed. |
You may enter several file masks separated with commas or semicolons. For example, to select all the documents, you can specify *.doc,*.txt,*.wri in search pattern.
You may use exclude masks. An exclude mask is one or multiple file masks that must not be matched by the files matching the mask. The exclude mask is delimited from the main mask by the character '|'.
Usage examples of exclude masks:
*.cpp
All files with the extension cpp.
*.*|*.bak,*.tmp
All files except for the files with extensions bak and tmp.
*.*|
This mask has an error - the character | is entered, but the mask itself is not specified.
*.*|*.bak|*.tmp
Also an error - the character | may not be contained in the mask more than once.
|*.bak
The same as *|*.bak
'shell' match mode is available from version 1.2.0 of File_Find
$pattern - a string containing the pattern to search the directory for.
$dirpath - a string containing the directory path to search.
$pattern_type - a string containing the type of pattern matching functions to use (can either be 'php', 'perl' or 'shell').
The format of the $pattern depends on the $pattern_type-value. For more information see search methods
array - an array contains all filenames and name of subdirectories, which matches the pattern. Or a PEAR_Error.
Таблица 39-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
NULL | " Cannot open directory " | The given directory could not be opend. | Check typing and directory permissions. This can not be caused by a competive processing the archive with Archive_Tar |
Пример 39-1. Find all PHP files in current directory
|
array - a two element array, the first element containing a list of all the directories, the second element containing a list of all the files.
Пример 39-1. Get the map of a directory
The above example will output something similar to:
|
Map the directory tree given by the directory_path parameter. Depending on maxrecursion you get the content of the directory and the content of the subdirectories too.
string $directory - contains the directory path that you want to map
integer $maxrecursion - defines the deep of recursive mapping of subdirectories
integer $count - can be ignored - internal parameter to track recursion level
array - a multidimensional array containing all subdirectories and their files
Пример 39-1. Get the content of a directory including the content of subdirectories
The above example will output something similar to:
|
$pattern - a string containing the pattern to search the directory for.
$dirpath - a string containing the directory path to search.
$pattern_type - a string containing the type of pattern matching functions to use (can either be 'php', 'perl' or 'shell').
The format of the $pattern depends on the $pattern_type-value. For more information see search methods
$fullpath - whether the string should be matched against the full path or only against the filename
$match - can be either 'files', 'directories' or 'both' to specify the kind of list to return
Provides an API for managing SAMBA passwd-style files
SAMBA is a free implementation of CIFS/SMB. The password encryption on Unix and Windows is different, therefore SAMBA must have his own file where the passwords are encrypted either as NT-Hash and/or as LAN-Manager-Hash. LAN-Manager-Hashes are weak and shouldn't be used anymore, NT-Hashes are based on MD4, but no salt is used, therefore users with the same passwords have the same NT-Hash. In this file are also stored machine accounts, if the SAMBA server acts as PDC, such entries ends with $.
Пример 39-1. Using File_SMBPasswd::load()
|
Get the value of file property. This property contains the filename of the current smbpasswd file.
Get the value of accounts property. This property contains all accounts of the current smbpasswd file.
string $user - username to be added
int $userid - userid of the user
string $lmhash - LAN-Manager-Hash
string $nthash - NT-Hash
string $comment - comment
string $flags - flags
Эта функция не должна вызываться статически.
Note that the user to be added must already exist in the systems password file.
File_SMBPasswd::modAccountEncrypted() |
File_SMBPasswd::modUser() |
File_SMBPasswd::modAccount() |
Пример 39-1. Using File_SMBPasswd::addAccountEncrypted()
|
This method works in the same way as File_SMBPasswd::addAccountEncrypted() , except the password has to be given as plaintext. The encryption is done internaly.
string $user - username to be added
int $userid - userid of the user
string $pass - plaintext-password
string $comment - comment
string $flags - flags
Эта функция не должна вызываться статически.
Note that the user to be added must already exist in the system password file.
File_SMBPasswd::addUser() |
File_SMBPasswd::addMachine() |
File_SMBPasswd::addAccountEncrypted() |
Пример 39-1. Using File_SMBPasswd::addAccount()
|
This method works in the same way as File_SMBPasswd::addAccount() , except the flags are forced representing a user-account.
string $user - username to be added
int $userid - userid of the user
string $pass - plaintext-password
string $comment - comment
Эта функция не должна вызываться статически.
Note that the user to be added must already exist in the system password file.
File_SMBPasswd::addAccount() |
File_SMBPasswd::addMachine() |
File_SMBPasswd::addAccountEncrypted() |
Пример 39-1. Using File_SMBPasswd::addUser()
|
This method works in the same way as File_SMBPasswd::addAccount() , except the flags are forced representing a machine-account, a $ is implicitely added to the machinename.
string $machine - machinename to be added
int $userid - userid of the user
string $comment - comment
Эта функция не должна вызываться статически.
Note that the machine to be added must already exist in the system password file.
File_SMBPasswd::addAccount() |
File_SMBPasswd::addUser() |
File_SMBPasswd::addAccountEncrypted() |
Пример 39-1. Using File_SMBPasswd::addMachine()
|
string $user - username to be added
int $userid - userid of the user
string $nthash - new NT-Hash
string $lmhash - new LM-Hash
string $comment - comment
string $flags - flags
Эта функция не должна вызываться статически.
Note that the user to be added must already exist in the system password file.
Пример 39-1. Using File_SMBPasswd::modAccountEncrypted()
|
This method works in the same way as File_SMBPasswd::modAccountEncrypted() , except the password has to be given as plaintext. The encryption is done internaly.
string $user - username to be modified
int $userid - userid of the user
string $pass - plaintext-password
string $comment - comment
string $flags - flags
File_SMBPasswd::addAccount() |
File_SMBPasswd::modAccountEncrypted() |
File_SMBPasswd::modUser() |
Пример 39-1. Using File_SMBPasswd::modAccount()
|
string $user - username to be added
int $userid - userid of the user
string $pass - plaintext-password
string $comment - comment
string $flags - flags
Эта функция не должна вызываться статически.
Note that the user to be added must already exist in the system password file.
File_SMBPasswd::addAccount() |
File_SMBPasswd::modAccountEncrypted() |
File_SMBPasswd::modAccount() |
Пример 39-1. Using File_SMBPasswd::modUser()
|
Пример 39-1. Using File_SMBPasswd::delAccount()
|
Пример 39-1. Using File_SMBPasswd::delAccount()
|
This method verifies the given username and passwords against the entry in the loaded smbpasswd file. The given passwords must already be a valid NT-Hash or LM-Hash, whereas the LM-Hash is optional.
string $user - username to be verified
string $nthash - the NT-Hash
string $lmhash - the LM-Hash
Пример 39-1. Using File_SMBPasswd::verifyAccount()
|
This method verifies the given username and plaintext-password against the entry in the loaded smbpasswd file.
Пример 39-1. Using File_SMBPasswd::verifyAccount()
|
Пример 39-1. Using File_SMBPasswd::lock()
|
Пример 39-1. Using File_SMBPasswd::unlock()
|
Saves the contents of File_SMBPasswd object as a corresponding smbpasswd file on the disc. Save implicitely locks the file.
Пример 39-1. Using File_SMBPasswd::save()
|
Пример 39-1. Using File_SMBPasswd::printAccounts()
|
Provides an API for replacing text in files
With SearchReplace, you can replace a text in as many as desired files by another.
Пример 39-1. Typical usage
|
The example replaces all occurences of "Yes" with "No" in the given $files and in all files in the directory "/mail/". If a line in a file starts with one of the chars in $ignoreline, possible matches will be ignored.
You can do a new search without creating a new instance of the class.
Пример 39-2. Do a new search
|
File_SearchReplace supports different kinds of search functions. The type directly influence the format of the required $find-parameter
normal - default, the only type supporting the $IgnoreLines-parameter |
quick - use str_replace() |
preg - use preg_replace() |
ereg - use ereg_replace() |
mixed $find - the string/regex or array of strings/regexes to find
mixed $replace - the string/regex or array of strings/regexes to replace $find
array $files - the file(s) to perform this operation on.
array $directories - the directories to perform this operation on.
boolean $include_subdir - if performing on directories, whether to traverse subdirectories.
array $ignore_lines - ignore lines beginning with any of the strings in this array. This feature only works with the "normal" search.
Provides methods to create and manipulate .htaccess files.
File_HtAccess provides common methods to create and manipulate Apache / NCSA style .htaccess files. These files together with accompanying password files are used to protect webserver directories. Since File_HtAccess does not provide any means to manipulate or create password files you should use it together with File_Passwd.
The most common and the original purpose of .htaccess files is to create per-directory password protection of resources. With modern webservers there is vast amount of other things .htaccess files can do. These include: custom error pages, ip based access control, redirecting users automatically, denying directory listing and using different files as an index file.
File_HtAccess concentrates only to password protection of directories, although it is possible to use it to control other things mentioned above too.
A .htaccess file is built from the following basic directives. They differ a bit whether youre using Basic or Digest authentication.
Таблица 39-1. Directives
Directive | Purpose |
---|---|
AuthType | Authentication type being used, "Basic" or "Digest". |
AuthName | Authentication realm or name. |
AuthUserFile | Full path to password file if using Basic authentication. |
AuthGroupFile | Full path to group file if using Basic authentication. |
AuthDigestFile | Full path to password file if using Digest authentication. |
AuthDigestGroupFile | Full path to group file if using Digest authentication. |
Require | Requirements which must be met to grant access. |
File_HtAccess provides method accessor methods with corresponding names for each of these directives, such as getAuthType() and setAuthType().
A typical .htaccess file looks like this:
AuthName "Protected" AuthType Basic AuthUserFile /usr/local/apache/conf/users.dat require valid-user |
When a client requests resource protected with basic authentication webserver responds with a 401 Authentication Required header. When client receives 401 header it asks the user for username and password. If authentication succeeds, the protected resource will be sent to the client. Otherwise the access will be denied.
Even though the passwords are stored encrypted on serverside they are sent cleartext between client and server when using Basic authentication. With Digest authentication the passwords are never sent cleartext but as a MD5 digest instead. The caveat is, most browsers do not support Digest authentication.
string $file - filename to use. Defaults to .htaccess
array $params - a array of parameters which can be:
$params['authname'] - authname
$params['authtype'] - authtype
$params['authuserfile'] - authuserfile
$params['authgroupfile'] - authgroupfile
$params['require'] - require
$params['additional'] - additional
Пример 39-1. How to create new instance of File_HtAccess
|
Пример 39-1. Using File_HtAccess::load()
|
Пример 39-1. Using File_HtAccess::save()
|
Sets the value of require property.This overwrites the previous value. If you need to add a value (user) to require use File_HtAccess::addRequire() instead. Using this method you can control which users will be able to access the protected resources.
mixed $require - value the requre property to be set to. Can be given as a string or an array. If given as a string separate multiple values with a space.
Пример 39-1. Using File_HtAccess::setRequire()
|
Adds a value (user) into require property. Using this method you can control which users will be able to access the protected resources.
Пример 39-1. Using File_HtAccess::addRequire()
|
Remove a value (user) from require property. Using this method you can control which users will be able to access the protected resources.
Пример 39-1. Using File_HtAccess::delRequire()
|
Get the value(s) of require property as an array. Require property contains the usernames or groups users who are allowed to access protected resources. Value valid-user means all users listed in password file are allowed to access.
string $type - if 'string' return value will be a string with usernames separated by a space character. Otherwise return value will be an array(). Defaults to an array.
Пример 39-1. Using File_HtAccess::getrequire()
|
Set the values of objects properties as defined by hash given as a parameter. You can use this method as an alternative to passing property values in constructor .
$params['authname'] - authname
$params['authtype'] - authtype
$params['authuserfile'] - authuserfile
$params['authgroupfile'] - authgroupfile
$params['require'] - require
$params['additional'] - additional
Пример 39-1. Using File_HtAccess::setProperties()
|
Sets the value of authuserfile property. AuthUserFile is the password file which contains username:password pairs for Basic authentication. You must give full path to the password file in order for it to work.
Пример 39-1. Using File_HtAccess::setAuthUserFile()
|
Sets the value of authgroupfile property. AuthGroupFile a file containing names of the groups and usernames belonging to the group. You must give full path to the group file in order for it to work.
Пример 39-1. Using File_HtAccess::setauthgroupfile()
|
Sets the value of authtype property. Almost allways you will be using Basic authentication. Since most browsers don't yet support Digest authentication you should only use Digest if you can control what browsers will be accessing the resources.
Пример 39-1. Using File_HtAccess::setAuthType()
|
Sets the value of authdigestfile property. AuthDigestFile is the password file which contains username:realm:password pairs for Digest authentication. You must give full path to the password file in order for it to work.
Пример 39-1. Using File_HtAccess::setauthdigestfile()
|
Provides useful packages for the PHP-Gtk extension.
Setting up GtkWidgets to accept files via Drag'n'Drop in a very easy way.
Gtk_FileDrop provides an easy interface to set up GtkWidgets to receive files via Drag'n'Drop. Widgets can be told to accept a number of MIME-Types as well as a number of file extensions. Values of widgets can automatically be set when drops with valid files occur, or a callback function can be specified which is invoked in this case.
Now one may think that the whole setup process is really simple and would not need a class like this to make widgets accept files. That is right. The setup for making widgets accept drops is an ease - but there are two more steps to do:
Make the widget accept only some types of files
Convert the dropped filenames to usable filenames
The first item is not so hard to implement; we do this by either checking the file extension, or using the MIME_Type package to get the mime type. (Note: * is supported).
The second item is the main problem as all applications seem to ignore the standard for file name exchange and cook their own soup (so using their own format) when passing the file names. This package knows the differences and converts the dropped strings into usable local filenames, regardless of the format the source application uses. For a deeper insight in this topic you should read the PHP-Gtk FileDrop tutorial.
Замечание: A note about Mozilla/Firefox: Mozilla provides file names only with mime type text/plain only instead of text/uri-list. If we would accept this type as well, the problem arises that every text could be dropped - if it is a file or not. That's why the decision was made not to accept drops from Mozilla.
By default, the dropped files are displayed in the widget, e.g. if you drop a file over a GtkEntry, the text value of the widget will be overwritten to the filename.
As not all widgets have such simple values, Gtk_FileDrop has built-in support for a number of widget classes and acts different on different types.
Таблица 40-1. Widget support
Widget class | Action taken |
---|---|
GtkEntry | Entry value is replaced with first file |
GtkLabel | Label text is replaced with first file |
GtkButton | Label text is replaced with first file if the first and only child is a GtkLabel |
GtkToggleButton | Label text is replaced with first file if the first and only child is a GtkLabel |
GtkRadioButton | Label text is replaced with first file if the first and only child is a GtkLabel |
GtkCheckButton | Label text is replaced with first file if the first and only child is a GtkLabel |
GtkCombo | The entry text is replaced with the first file. The list is not affected. |
GtkFileSelection | File name of the file dialog is set to the first dropped file. The directory is changed to the directory name of the file, and the file name (without directory) is set in the file name entry. |
GtkList | Every accepted file is appended at the end of the list. |
Beside the automatic actions, you can specify a callback as the third parameter of the attach function which is called with the widget itself and an array of accepted files as parameters.
Пример 40-1. General setup
Here we set up the array of accepted file types: The widget shall accept files with MIME-Type text/html, text/plain and files ending with .dat. After this we set up the $widget to accept this files. |
Пример 40-2. Accepting directories
The MIME type inode/directory has to be used if the widget shall accept directories. |
Замечание: When a file is dropped over a widget which accepts directories only, the directory of the filename is used.
Пример 40-3. Setup with callback
In this example we use a callback function to print out all dropped files to the console. Further we determine the fourth parameter as false which means that the widget's value is not changed automatically. To use the callback with objects, you pass an array with the reference of the object:
|
Пример 40-5. Working example
|
A class that creates a scrolling marquee.
Gtk_ScrollingLabel is a class that creates a pseudo-widget which makes scrolling text within a label easy. The text within the label can be set to scroll from left to right, right to left, or bounce within the boundries of the label. The speed of the scrolling text can also be controlled. There are also built in methods to make the text pause or stop when the user moves the mouse over the label and start up again when the mouse leaves the label space.
Getting started with Gtk_ScrollingLabel is easy. All you need to do is instantiate the class, add it to a window, and start the scrolling. Take at look at the example below.
Пример 40-1. Simple Setup
|
Returns the full text of the label. The full text is the text that was set on construction or with setFullText() not just what is currently visible.
Returns the label's style widget. This lets you make changes to the style to alter the look and feel of the widget. You can change the font of the display, the color of the background, etc.
Returns the length of the visible area in characters. The length of the visible area is the maximum number of characters that are visible at one time.
Stops the label from scrolling but does not reset the label text to the begining. If you want the label to stop scrolling and return to its original position (blank), use stopScroll().
If $bounce is true, the text will scroll to the left until the first character hits the left edge of the visible window then it will scroll back to the right. When the last character hits the right edge of the visible window the text will scroll back to the left again.
If all of the scrolling text cannot be viewed at once, making the text bounce will have an undesired result. Therefore it is suggested that the length of the text always be at least one character less than the maximum viewable string length.
boolean $bounce - Whether or not the text should change direction when it hits a label edge.
setStartSignal() will make the event box listen for the signal $signal and will envoke startScroll() when ever it is heard. The signal should be a signal that GtkEventBox listens for normally or a button press event.
startScroll() will make the text begin scrolling in the direction given by calling setDirection(). If the text is scrolling left to right (GTK_SCROLLINGLABEL_RIGHT), the current character position is set to the end of the text. This means that the last character of the label will be the first character shown. If the text is scrolling right to left (GTK_SCROLLINGLABEL_LEFT), the current character position is set to zero. This means that first character shown will be a blank space.
This method is best used when connected to an event.
Begins scrolling the label from its current position. unPause() is different from startScroll() in that it does not reset the label to the begining of the text.
Provides a simple GUI to examine PHP variables, for example complex arrays or objects.
The GUI consists of two parts: a tree on the left side, displaying the values/objects/arrays that have subkeys/subvalues, and a list with scalar key-value pairs on the right side.
To use it, just include Gtk/VarDump.php and call the constructor with the variable to be dumped.
Пример 40-7. Inspecting a variable with Gtk_VarDump
|
Provides useful packages for the PHP-Gtk2 extension.
The package provides a simple dialogbox for text input.
Gtk2_EntryDialog provides a dialog with a message and one single text input field, and some buttons like OK and Cancel. The class tries to make it as easy as possible to get the text from the user with only a few lines of code, while keeping the full power of the GtkDialog class.
The most easy way to retrieve the text with one line of code is using the get() static method.
Creates a new entry dialog instance. After creating it, you can modify it and finally use the run() to show it and await the input.
You might want to use a more simple constructor, e.g. get() or new_simple()
<?php require_once 'Gtk2/EntryDialog.php'; $id = new Gtk2_EntryDialog( null, //parent window 0, //flags (GtkDialogFlags) Gtk::MESSAGE_QUESTION, //type of message Gtk::BUTTONS_OK_CANCEL, //which buttons shall be there 'What\'s your name?', //the message 'Don\'t know' //The default text ); $answer = $id->run(); $id->destroy(); if ($answer == Gtk::RESPONSE_OK) { echo 'The name is: '; var_dump($id->get_text()); } else { echo "You cancelled\r\n"; } ?> |
Parent window (can be null).
Dialog flags (use 0 as default)
Message type (e.g. Gtk::MESSAGE_QUESTION)
Buttons to show (e.g. Gtk::BUTTONS_OK)
Message to display.
Default text for the entry.
Simplified constructor with not so much parameters.
Message type is Gtk::MESSAGE_QUESTION, the flags will be Gtk::DIALOG_MODAL if the parent is set. Only one button, OK, will be visible.
<?php require_once 'Gtk2/EntryDialog.php'; $id = Gtk2_EntryDialog::new_simple( 'What\'s your name?', //the message 'Don\'t know' //The default text ); $answer = $id->run(); $id->destroy(); if ($answer == Gtk::RESPONSE_OK) { echo 'The name is: '; var_dump($id->get_text()); } else { echo "You cancelled\r\n"; } ?> |
Message to display.
Default text for the entry.
Parent window (can be null).
Creates a dialog with the given parameters, runs it, and returns the text set. If the user cancelled the dialog, this method returns FALSE. In any other case (even when the text is empty), the a string with the text is returned.
<?php require_once 'Gtk2/EntryDialog.php'; $text = Gtk2_EntryDialog::get( 'What\'s your name?', //the message 'Don\'t know' //The default text ); if ($text !== false) { echo 'The name is: '; var_dump($text); } else { echo "You cancelled\r\n"; } ?> |
Message to display.
Default text for the entry.
Parent window (can be null).
Catches and displays PHP errors, notices and warnings as well as PEAR Errors and uncaught exceptions.
Gtk2_ExceptionDump catches and displays common errors and warnings that can be produced in a PHP scripts: PHP errors, notices and warnings as well as PEAR Errors and uncaught exceptions. They are displayed in a Gtk2 window with a tree view, providing the error message and the backtrace with passed parameters.
The most easy thing to do is letting the class handle everything automatically. You can decide which errors should be catched: All, PHP errors, PEAR errors or uncaught exceptions. The following methods need to be called statically to set up error handling:
setupExceptionHandler()
setupPearErrorHandler()
setupPhpErrorHandler()
setupAllHandlers()
Пример 41-1. Letting Gtk2_ExceptionDump handle all errors
|
If you don't want to let Gtk2_ExceptionDump handle errors automatically, you can display the window by hand, e.g. in a catch() statement.
Пример 41-2. Catching exceptions by hand
|
You can make use of the brain power that went into the development of Gtk2_ExceptionDump by embedding the stack trace treeview into your own application.
There class you want is Gtk2_ExceptionDump_Stack. It's a subclass of GtkTreeView and should be embedded in a GtkScrolledWindow if you use it. The constructor takes the exception object, but it can be omitted and set later by using setException().
Setting up GtkWidgets to accept files via Drag'n'Drop in a very easy way.
Gtk2_FileDrop provides an easy interface to set up GtkWidgets to receive files via Drag'n'Drop. Widgets can be told to accept a number of MIME-Types as well as a number of file extensions. Values of widgets can automatically be set when drops with valid files occur, or a callback function can be specified which is invoked in this case.
Now one may think that the whole setup process is really simple and would not need a class like this to make widgets accept files. That is right. The setup for making widgets accept drops is an ease - but there are two more steps to do:
Make the widget accept only some types of files
Convert the dropped filenames to usable filenames
The first item is not so hard to implement; we do this by either checking the file extension, or using the MIME_Type package to get the mime type. (Note: * is supported).
The second item is the main problem as all applications seem to ignore the standard for file name exchange and cook their own soup (so using their own format) when passing the file names. This package knows the differences and converts the dropped strings into usable local filenames, regardless of the format the source application uses. For a deeper insight in this topic you should read the PHP-Gtk FileDrop tutorial.
Замечание: A note about Mozilla/Firefox: Mozilla provides file names only with mime type text/plain only instead of text/uri-list. If we would accept this type as well, the problem arises that every text could be dropped - if it is a file or not. That's why the decision was made not to accept drops from Mozilla.
Замечание: Gtk2_FileDrop is the port of Gtk_FileDrop to PHP-Gtk2 and PHP5. Thus, it has identical methods and behaves the same.
By default, the dropped files are displayed in the widget, e.g. if you drop a file over a GtkEntry, the text value of the widget will be overwritten to the filename.
As not all widgets have such simple values, Gtk2_FileDrop has built-in support for a number of widget classes and acts different on different types.
Таблица 41-1. Widget support
Widget class | Action taken |
---|---|
GtkEntry | Entry value is replaced with first file |
GtkLabel | Label text is replaced with first file |
GtkButton | Label text is replaced with first file if the first and only child is a GtkLabel |
GtkToggleButton | Label text is replaced with first file if the first and only child is a GtkLabel |
GtkRadioButton | Label text is replaced with first file if the first and only child is a GtkLabel |
GtkCheckButton | Label text is replaced with first file if the first and only child is a GtkLabel |
GtkCombo | The entry text is replaced with the first file. The list is not affected. |
GtkFileSelection | File name of the file dialog is set to the first dropped file. The directory is changed to the directory name of the file, and the file name (without directory) is set in the file name entry. |
GtkList | Every accepted file is appended at the end of the list. |
Beside the automatic actions, you can specify a callback as the third parameter of the attach function which is called with the widget itself and an array of accepted files as parameters.
Пример 41-1. General setup
Here we set up the array of accepted file types: The widget shall accept files with MIME-Type text/html, text/plain and files ending with .dat. After this we set up the $widget to accept this files. |
Пример 41-2. Accepting directories
The MIME type inode/directory has to be used if the widget shall accept directories. |
Замечание: When a file is dropped over a widget which accepts directories only, the directory of the filename is used.
Пример 41-3. Setup with callback
In this example we use a callback function to print out all dropped files to the console. Further we determine the fourth parameter as false which means that the widget's value is not changed automatically. To use the callback with objects, you pass an array with the reference of the object:
|
Пример 41-5. Working example
|
Gtk2_IndexedComboBox is meant to be as easy to use as possible, and to have an API similar to the combo boxes created with GtkComboBox::new_text(). You can directly add key/value pairs to the widget instead of using the model (which is possible, too). Retrieving the currently selected key can be done with a single method call.
Both keys and values can be strings, thus allowing integers implicitly. This is very useful if you need a widget to select some row ID from a database, but want to display some descriptive string. By default, a single GtkCellRendererText is used as cell renderer.
In this example, we will create a combo box, add an array of key/value pairs and display the currently selected pair in a label.
Пример 41-1. Simple Gtk2_IndexedComboBox example
|
At first, we create a new combo widget object. You already could pass the array of data in the constructor if you wanted to, but here we use the set_array() method to do this. After providing the data, entry with id 2 is made active/pre-selected.
Whenever the selection changes, the example displays the selected key and value in a label below the combo box. We use get_active_key() to retrieve the key, and get_active_text() to retrieve the value.
While designing your user interface with Glade is really convenient and easy, it doesn't allow you to use custom classes as this combo here. Thanks to the MVC model in Gtk2, you still can use this class's power by using the same model as Gtk2_IndexedComboBox uses internally: Gtk2_IndexedComboBox_Model.
Пример 41-1. Glade file to use
|
Пример 41-2. PHP code
|
The important thing to remember is that you need to setup your own cell renderer, and tell it which column in the model shall be displayed. Beside that, you just do the normal model-creation-and-setting via set_model().
All data manipulation methods of Gtk2_IndexedComboBox you saw in the previous example are available in the model, Gtk2_IndexedComboBox_Model. Only get_active_key() and get_active_text() cannot be used on the model, since this doesn't know anything about selections. Retrieve the selected GtkTreeIter by combining the calls of get_active() and get_iter(), and pass this iter object to get_key() and get_text().
Gtk2_IndexedComboBox automatically creates the model and sets up the cell renderer when instantiating the widget. You may pass an array of key/value pairs to the constructor if you like to, but also can set them later.
The currently selected (active) key can be retrieved via get_active_key(), the selected (active) value by using get_active_text(). You can preselect a certain key with set_active_key().
If you don't like the renderer or want to change it or its attributes, use get_cell_renderer() and set_cell_renderer().
All other methods to retrieve/store data are convenience methods that act as proxy to the model. For example, Gtk2_IndexedComboBox' method set_array() internally calls the same method on the model, Gtk2_IndexedComboBox_Model. This allows you to quickly add some data to the combo without getting the model first and acting on it.
The model class is the data storage for your key/value pairs. It contains two columns, both are of type Gtk::TYPE_STRING and can hold text and numbers. The first is used for the keys, the values are stored in the second column.
The class has several method that allow you to store data in the model: The classis set_array() takes an associative array of key/value pairs. Once set, you can use append_array() and prepend_array() to add new data after or before the current values. You also have the possibility to use insert_array() that takes the position as first, and the data array as second parameter.
Beside the *_array methods, you can add single key/value pairs by using append() and prepend() which take the key as first, and the value as second parameter. insert() wants an additional position number as first parameter, and key/value as second and third.
To delete data from the model, use remove_key(). After finishing your data manipulation, you can retrieve the full associative array of key/value pairs via get_array().
To obtain the key or value of a certain GtkTreeIter (that you got e.g. from the model by using get_iter()), use get_key() and get_text().
Provides a simple GUI to enable the user to edit php.ini values.
This package will be useful for PHP-GTK 2 based applications which require the user to make changes to php.ini. The class can parse any existing ini file, or create new ones. Parsing of existing files is currently a little inefficient, suggestions for improvement are welcome. New files and files previously generated by Gtk2_PHPConfig are parsed at a good speed though.
The interface displays all available configuration sections on the left pane, and their corresponding options in the top right pane. The bottom right pane displays the description of the option selected and the facility to change the value of that option.
Пример 41-1. Simple Configuration GUI
This example is actually the gtk2_phpconfig executable found in /usr/bin (for *nix systems) after installation of the Gtk2_PHPConfig package. The example script accepts a single optional argument, i.e. the location of the ini file to edit. If not provided, a new file will be created. Gtk2_PHPConfig extends GtkWindow and can be treated as an application by itself. Hence, the methods used internally are of no significance to the end user. However, you may refer to the API documentation if you are interested in customization or just understanding how the package works. |
A class that creates a scrolling marquee.
Gtk2_ScrollingLabel is a class that creates a pseudo-widget which makes scrolling text within a label easy. The text within the label can be set to scroll from left to right, right to left, or bounce within the boundries of the label. The speed of the scrolling text can also be controlled. There are also built in methods to make the text pause or stop when the user moves the mouse over the label and start up again when the mouse leaves the label space.
Getting started with Gtk2_ScrollingLabel is easy. All you need to do is instantiate the class, add it to a window, and start the scrolling. Take at look at the example below.
Пример 41-1. Simple Setup
|
Returns the full text of the label. The full text is the text that was set on construction or with setFullText() not just what is currently visible.
Returns the label's style widget. This lets you make changes to the style to alter the look and feel of the widget. You can change the font of the display, the color of the background, etc.
Returns the length of the visible area in characters. The length of the visible area is the maximum number of characters that are visible at one time.
Stops the label from scrolling but does not reset the label text to the begining. If you want the label to stop scrolling and return to its original position (blank), use stopScroll().
If $bounce is true, the text will scroll to the left until the first character hits the left edge of the visible window then it will scroll back to the right. When the last character hits the right edge of the visible window the text will scroll back to the left again.
If all of the scrolling text cannot be viewed at once, making the text bounce will have an undesired result. Therefore it is suggested that the length of the text always be at least one character less than the maximum viewable string length.
boolean $bounce - Whether or not the text should change direction when it hits a label edge.
setStartSignal() will make the event box listen for the signal $signal and will envoke startScroll() when ever it is heard. The signal should be a signal that GtkEventBox listens for normally or a button press event.
startScroll() will make the text begin scrolling in the direction given by calling setDirection(). If the text is scrolling left to right (GTK2_SCROLLINGLABEL_RIGHT), the current character position is set to the end of the text. This means that the last character of the label will be the first character shown. If the text is scrolling right to left (GTK2_SCROLLINGLABEL_LEFT), the current character position is set to zero. This means that first character shown will be a blank space.
This method is best used when connected to an event.
Begins scrolling the label from its current position. unPause() is different from startScroll() in that it does not reset the label to the begining of the text.
Provides a simple GUI to examine PHP variables, for example complex arrays or objects.
Gtk2_VarDump is a simple GUI to examine PHP variables, for example complex arrays or objects. It displays the variable and all sub-variables/array keys/sub-objects in the left pane (a GtkTreeView), and the actual values in a list view on the right side.
The class is very easy to use: Just include the file, and call the static display method with the variable you want to have dumped.
Пример 41-1. Showing a variable with Gtk2_VarDump
|
Gtk2_VarDump consists of two main parts: A tree on the left, displaying the structure of the variable-to-dump, and a list on the right side, showing the keys and their values. They are arranged on a pane, which itself is contained in the main window.
Now you might want to dump some variables yourself, but integrate this display directly into your own application - without opening a new window for that. Gtk2_VarDump is prepared for that; you can re-use the existing classes.
Gtk2_VarDump_Pane is the container for both tree and list. You can use instantiate it, add it to your interface and call the setVariable() method to display the contents of the variable. The method takes the variable as first parameter, and a user-definable title as optional second parameter.
Gtk2_VarDump_Tree is an descendant of GtkTreeView, and as usual without any scrollbars. Remember to add it to a GtkScrolledWindow. The class has, as Gtk2_VarDump_Pane does, a setVariable() method that takes the variable to be displayed and an optional title that is used for the root element.
The tree has another method: setList() is used to set the list widget that shall display the values. Be sure that the list widget also provides a setVariable() method. Whenever the selection in the tree changes, the list's setVariable() method is called.
Предоставляет пакеты для создания и работы с HTML.
The HTML_Crypt provides methods to encrypt text, which can be later be decrypted using JavaScript on the client side.
This is very useful to prevent spam robots collecting email addresses from your site, included is a method to add mailto links to the text being generated.
Пример 42-1. A basic example to encrypt an email address
|
The "encryption" function is basically works like ROT13, with the difference that the $offset setting replaces the 13. It is also limited to ASCII characters between 32 and 127 (included). Other characters will not be encrypted.
This is a simple HTML form generator. It supports all the HTML form element types including file uploads, may return or print the form, just individual form elements or the full form in "table mode" with a fixed layout.
This is a simple HTML form generator. It supports all the HTML form element types including file uploads, may return or print the form, just individual form elements or the full form in "table mode" with a fixed layout.
Generally one can use HTML_Form in HTML based projects of any form. But especially when using the package in "table mode" one may soon run into design problems, because the table that is created by HTML_Form cannot be equipped with CSS or other ways to control their look. Thus the main usage area of HTML_Form are sites where design does not play the most important role but where it is necessary to get fast results while keeping the code clean at the same time. (Examples are back office websites or places like pear.php.net, where the package is used at a lot of places.)
Пример 42-1. Basic example
|
The above example code creates a HTML form that only contains a single textfield with the name "name" and with the label "What's your name" and a submit button labeled "Go, Go".
Creating a form in "table mode" means that the package returns the complete form in a fixed width table. Whilst this does not work very well for most frontend websites, it is a very convenient way to create forms during development phase or for backend systems where the design does not matter (much).
Пример 42-1. Creating a form
|
This will display a table where the left column holds the labels of the different fields. In the right column the different fields are placed.
Apart from retrieving the table as a whole, one can also use the API of HTML_Form to directly display single form tags.
Пример 42-2. Directly displaying form tags
|
The above example will print the HTML markup being necessary to render a text input field. It will not print the surrounding <form /> tag or something else!
Similar to displaying form tags with the display*() functions HTML_Form can also return the tag instead of printing it.
Пример 42-3. Returning form tags
|
The variable $str now contains HTML markup like <input type="password" name="password" />.
With the HTML_Menu class one can easily create and maintain a navigation structure for websites, configuring it via a multidimensional hash structure. Different modes for the HTML output are supported.
The menu structure is defined by a multidimensional hash. This makes it quite easy to generate and traverse:
Пример 42-1. Menu multidimensional hash
|
The menu entries can also contain custom keys. If such keys are present, then they will be used by renderers in creating the output (this usually means that the content of such a key will be assigned to the template placeholder with the same name).
HTML_Menu supports five output modes: 'tree' (default), 'rows', 'urhere', 'prevnext' and 'sitemap'. Lets use the array defined above as menu structure assuming that element 'Menu item 1.2' is currently active and try each menu type.
Possible menu types
This type of the menu mostly follows the internal structure of the menu hash. Different levels of the menu are marked by indentation, only the elements leading to the active item or immediately following it are shown.
This is quite similar to 'tree' type, only different levels are not marked by indentation, but are shown on different rows of the menu.
This is so-called 'breadcrumb' navigation, allowing to easily understand your position within site hierarchy.
Пример 42-4. Output for menu type 'urhere'
|
This is the menu often used in documentation (including the PEAR manual), the links lead to previous, next and parent entries of the current entry.
This is 'tree' type menu, but with all entries shown.
Пример 42-7. Very basic usage example
|
Initializes the menu, sets the menu structure, type and variable to use for determining the current URL. All parameters are optional and can be set later by corresponding methods.
Menu type: 'tree', 'rows', 'urhere', 'prevnext', 'sitemap'
Environment variable to use for determining the current URL.
Use this if you do not want to extract current URL from some environment variable (e.g. $_SERVER['PHP_SELF']) but rather use some custom logic to determine it.
This method uses HTML_Menu_DirectRenderer for its work. The renderer is used with default templates, you should use the render() method if you want to customize the output.
All logic to actually create the output is contained in the renderer. render() just calls the appropriate method to traverse the menu structure.
throws PEAR_Error. If the renderer is not designed to handle this type of menu, it will throw an error.
This is useful if you have relative URLs in the menu description structure. This prefix will be appended to the URLs from this structure and the result will be compared to "current" URL.
This method uses HTML_Menu_DirectRenderer for its work. The renderer is used with default templates, you should use the render() method if you want to customize the output.
This class defines methods that should be implemented by child classes to provide necessary output logic. You only need to read its description if you intend to write your own renderer.
HTML_Menu_Renderer
Таблица 42-1. Classes that extend HTML_Menu_Renderer
Class | Summary |
---|---|
HTML_Menu_ArrayRenderer | The renderer that creates an array of visible menu entries. |
HTML_Menu_DirectRenderer | The renderer that generates HTML for the menu all by itself. |
HTML_Menu_DirectTreeRenderer | The "direct" renderer for 'tree' and 'sitemap' menu types where level is represented by tags nesting. |
HTML_Menu_SigmaRenderer | The renderer that uses HTML_Template_Sigma instance for menu output. |
HTML_Menu_SigmaTreeRenderer | HTML_Template_Sigma-based renderer for 'tree' and 'sitemap' type menus, where menu level is represented by tag nesting. |
Element being rendered
Current depth in the tree structure
Type of the element (one of HTML_MENU_ENTRY_* constants)
This renderer directly generates the menu HTML, thus the name. It is loosely based on HTML_Menu 1.0 code, but while it was needed to subclass HTML_Menu to customize its output, HTML_Menu_DirectRenderer has built-in methods for changing menu appearance.
HTML_Menu_DirectRenderer
HTML_Menu_DirectRenderer Inherited Methods
Таблица 42-1. Inherited from HTML_Menu_Renderer
Method Name | Summary |
---|---|
HTML_Menu_Renderer::finishLevel() | Finish the tree level (for types 'tree' and 'sitemap') |
HTML_Menu_Renderer::finishMenu() | Finish the menu |
HTML_Menu_Renderer::finishRow() | Finish the row in the menu |
HTML_Menu_Renderer::renderEntry() | Renders the element of the menu |
HTML_Menu_Renderer::setMenuType() | Sets the type of the menu being rendered. |
The template should contain at least the {title} placeholder, can also contain {url} and {indent} placeholders, depending on entry type. Default templates are:
array( HTML_MENU_ENTRY_INACTIVE => '<td>{indent}<a href="{url}">{title}</a></td>', HTML_MENU_ENTRY_ACTIVE => '<td>{indent}<b>{title}</b></td>', HTML_MENU_ENTRY_ACTIVEPATH => '<td>{indent}<b><a href="{url}">{title}</a></b></td>', HTML_MENU_ENTRY_PREVIOUS => '<td><a href="{url}"><< {title}</a></td>', HTML_MENU_ENTRY_NEXT => '<td><a href="{url}">{title} >></a></td>', HTML_MENU_ENTRY_UPPER => '<td><a href="{url}">^ {title} ^</a></td>', HTML_MENU_ENTRY_BREADCRUMB => '<td><a href="{url}">{title}</a> >> </td>' ); |
either type (one of HTML_MENU_ENTRY_* constants) or an array 'type' => 'template'
template for this entry type if $type is not an array
These are the strings that will be prepended and appended to HTML generated for menu rows on each call to finishMenu(). Defaults are
'<table border="1">' |
'</table>' |
this will be prepended to the rows HTML
this will be appended to the rows HTML
These are the strings that will be prepended and appended to HTML generated for menu entries on each call to finishRow(). Defaults are
'<tr>' |
'</tr>' |
this will be prepended to the entries HTML
this will be appended to the entries HTML
The renderer is designed to output only the menus of type 'tree' and 'sitemap'. It shows the level of the menu by tags nesting, not by outputting some indentation and is able to output e.g. nested HTML lists:
<ul> <li>Menu item 1 <ul> <li>Menu item 1.1</li> <li>Menu item 1.2</li> </ul> </li> <li>Menu item 2</li> </ul> |
Idea and initial code contributed by Uwe Mindrup.
HTML_Menu_DirectTreeRenderer
HTML_Menu_DirectTreeRenderer Inherited Methods
Таблица 42-1. Inherited from HTML_Menu_Renderer
Method Name | Summary |
---|---|
HTML_Menu_Renderer::finishLevel() | Finish the tree level (for types 'tree' and 'sitemap') |
HTML_Menu_Renderer::finishMenu() | Finish the menu |
HTML_Menu_Renderer::finishRow() | Finish the row in the menu |
HTML_Menu_Renderer::renderEntry() | Renders the element of the menu |
HTML_Menu_Renderer::setMenuType() | Sets the type of the menu being rendered. |
The template should contain at least the {title} placeholder, can also contain {url} placeholder. Default templates are:
array( HTML_MENU_ENTRY_INACTIVE => '<a href="{url}">{title}</a>', HTML_MENU_ENTRY_ACTIVE => '<strong>{title}</strong>', HTML_MENU_ENTRY_ACTIVEPATH => '<a href="{url}"><em>{title}</em></a>' ); |
either type (one of HTML_MENU_ENTRY_* constants) or an array 'type' => 'template'
template for this entry type if $type is not an array
These are the strings that will be prepended and appended to HTML generated for menu entries. Defaults are
'<li>' |
'</li>' |
this will be prepended to the entries HTML
this will be appended to the entries HTML
These are the strings that will be prepended and appended to HTML generated for menu level. Defaults are
'<ul>' |
'</ul>' |
this will be prepended to the rows HTML
this will be appended to the rows HTML
The resultant array can be used with e.g. a template engine to produce a completely custom menu look.
All menu types except 'rows' are "rendered" into a one-dimensional array of entries:
array( 'entry1', ... 'entryN' ) |
array( array('entry 1 for row 1', ..., 'entry M_1 for row 1'), ... array('entry 1 for row N', ..., 'entry M_N for row 1') ) |
Here entry is
array( 'url' => url element of menu entry 'title' => title element of menu entry 'level' => entry's depth in the tree structure 'type' => type of entry, one of HTML_MENU_ENTRY_* constants ) |
HTML_Menu_ArrayRenderer
HTML_Menu_ArrayRenderer Inherited Methods
Таблица 42-1. Inherited from HTML_Menu_Renderer
Method Name | Summary |
---|---|
HTML_Menu_Renderer::finishLevel() | Finish the tree level (for types 'tree' and 'sitemap') |
HTML_Menu_Renderer::finishMenu() | Finish the menu |
HTML_Menu_Renderer::finishRow() | Finish the row in the menu |
HTML_Menu_Renderer::renderEntry() | Renders the element of the menu |
HTML_Menu_Renderer::setMenuType() | Sets the type of the menu being rendered. |
This renderer uses HTML_Template_Sigma for actual HTML generation. This will allow you to easily plug HTML_Menu into your site's structure if you are using this template engine.
The renderer offers more possibilites for output customization than HTML_Menu_DirectRenderer.
The renderer may also work with HTML_Template_IT instance, but as menu templates tend to have lots of blocks, HTML_Template_Sigma's cache feature will give a significant performance improvement.
This minimal template will allow output of any available menu type:
<!-- BEGIN mu_menu_loop --> <table cellpadding="2" cellspacing="0" border="1"> <!-- BEGIN mu_row_loop --> <tr> <!-- BEGIN mu_entry_loop --> <!-- BEGIN mu_inactive --> <td><!-- BEGIN mu_inactive_indent --> <!-- END mu_inactive_indent --><a href="{mu_url}">{mu_title}</a></td> <!-- END mu_inactive --> <!-- BEGIN mu_active --> <td><!-- BEGIN mu_active_indent --> <!-- END mu_active_indent --><strong>{mu_title}</strong></td> <!-- END mu_active --> <!-- BEGIN mu_activepath --> <td><!-- BEGIN mu_activepath_indent --> <!-- END mu_activepath_indent --><a href="{mu_url}"><strong>{mu_title}</strong></a></td> <!-- END mu_activepath --> <!-- BEGIN mu_previous --> <td><a href="{mu_url}"><<< {mu_title}</a></td> <!-- END mu_previous --> <!-- BEGIN mu_next --> <td><a href="{mu_url}">{mu_title} >>></a></td> <!-- END mu_next --> <!-- BEGIN mu_upper --> <td><a href="{mu_url}">^ {mu_title} ^</a></td> <!-- END mu_upper --> <!-- BEGIN mu_breadcrumb --> <td><a href="{mu_url}">{mu_title}</a> >>></td> <!-- END mu_breadcrumb --> <!-- END mu_entry_loop --> </tr> <!-- END mu_row_loop --> </table> <!-- END mu_menu_loop --> |
Note that blocks and placeholders in the template have mu_ prefix. This is done to prevent name conflicts with existing blocks and placeholders, mu_ is the default prefix, another prefix can be passed to class constructor.
Blocks in the template (without prefix)
If present, this block will be parse()'d after outputting the current menu or (in case of 'rows' type) current menu level. If menu type is 'rows' and %level%_menu_loop block is present, it will be parse()'d instead.
If present, this block will be parse()'d after outputting the current menu row. If menu type is 'rows' and %level%_row_loop block is present, it will be parse()'d instead.
This block should always be present and should be a parent for all menu entries' blocks. It is used to implement "flow", to render entries one after another.
If menu type is 'rows' and %level%_entry_loop block is present, it will be used instead.
These blocks are used to output menu entries, they correspond to possible entry types. Each block should contain a {title} placeholder and may also contain {url} placeholder and indent block
If menu type is either of 'tree', 'sitemap' or 'rows' and %level%_%entry type% block exists, it will be used instead.
If present, these blocks are used to indent the entries inside tree-type menus ('tree' and 'sitemap').
HTML_Menu_SigmaRenderer
HTML_Menu_SigmaRenderer Inherited Methods
Таблица 42-1. Inherited from HTML_Menu_Renderer
Method Name | Summary |
---|---|
HTML_Menu_Renderer::finishLevel() | Finish the tree level (for types 'tree' and 'sitemap') |
HTML_Menu_Renderer::finishMenu() | Finish the menu |
HTML_Menu_Renderer::finishRow() | Finish the row in the menu |
HTML_Menu_Renderer::renderEntry() | Renders the element of the menu |
HTML_Menu_Renderer::setMenuType() | Sets the type of the menu being rendered. |
Sets the template object to use and sets prefix for template blocks and placeholders. We use prefix to avoid name collisions with existing template blocks and it is customisable to allow output of several menus into one template.
template object to use for output
prefix for template blocks and placeholders
The renderer generates outpu similar to that of HTML_Menu_DirectTreeRenderer but offers more possibilites for output customization.
The renderer may also work with HTML_Template_IT instance, but as menu templates tend to have lots of blocks, HTML_Template_Sigma's cache feature will give a significant performance improvement.
This is the minimal template for HTML_Menu_SigmaTreeRenderer, containing all the required blocks:
<!-- BEGIN mu_tree_loop --> <!-- BEGIN mu_level_open --> <ul> <!-- END mu_level_open --> <!-- BEGIN mu_entry_open --> <li> <!-- END mu_entry_open --> <!-- BEGIN mu_active --> <strong>{mu_title}</strong> <!-- END mu_active --> <!-- BEGIN mu_inactive --> <a href="{mu_url}">{mu_title}</a> <!-- END mu_inactive --> <!-- BEGIN mu_activepath --> <a href="{mu_url}"><em>{mu_title}</em></a> <!-- END mu_activepath --> <!-- BEGIN mu_entry_close --> </li> <!-- END mu_entry_close --> <!-- BEGIN mu_level_close --> </ul> <!-- END mu_level_close --> <!-- END mu_tree_loop --> |
Note that blocks and placeholders in the template have mu_ prefix. This is done to prevent name conflicts with existing blocks and placeholders, mu_ is the default prefix, another prefix can be passed to class constructor.
Blocks in the template (without prefix)
This block should always be present and should be a parent for all other blocks. It is used to implement "flow", to render entries one after another.
These blocks will be used on start and end of each menu level. If level-specific blocks %level%_level_open and %level%_level_close are present, they will be used instead.
These blocks will be used on start and end of each menu entry. If level-specific blocks %level%_entry_open and %level%_entry_close are present, they will be used instead.
These blocks are used to output menu entries, they correspond to possible entry types. Each block should contain a {title} placeholder and may also contain {url} placeholder. As usual, if other keys are present in original menu array they will be assigned to corresponding placeholders in the template.
If level-specific block %level%_%entry type% exists, it will be used instead.
HTML_Menu_SigmaTreeRenderer
HTML_Menu_SigmaTreeRenderer Inherited Methods
Таблица 42-1. Inherited from HTML_Menu_Renderer
Method Name | Summary |
---|---|
HTML_Menu_Renderer::finishLevel() | Finish the tree level (for types 'tree' and 'sitemap') |
HTML_Menu_Renderer::finishMenu() | Finish the menu |
HTML_Menu_Renderer::finishRow() | Finish the row in the menu |
HTML_Menu_Renderer::renderEntry() | Renders the element of the menu |
HTML_Menu_Renderer::setMenuType() | Sets the type of the menu being rendered. |
Sets the template object to use and sets prefix for template blocks and placeholders. We use prefix to avoid name collisions with existing template blocks and it is customisable to allow output of several menus into one template.
template object to use for output
prefix for template blocks and placeholders
Together with menu (3) and the (userland) cache you can use this browser to generate simple fusebox like applications / content systems.
Let the menubrowser scan your document root and generate a menu (3) structure hash which maps the directory structure, pass it to menu's setMethod() and optionally wrap the cache around all this to save script runs. If you do so, it looks like this:
// document root directory define('DOC_ROOT', '/home/server/www.example.com/');
// instantiate the menubrowser $browser = new menubrowser(DOC_ROOT);
// instantiate menu (3) $menu = new menu($browser->getMenu());
// output the sitemap $menu->show('sitemap');
Now, use e.g. simple XML files to store your content and additional menu informations (title!). Subclass exploreFile() depending on your file format.
Directory to scan
Filename of index pages
Suffix for files containing the additional data
directory to scan
entry id - used only for recursion
??? - used only for recursion
You should subclass this method to make it work with your own file formats. I used a simple XML format to store the content.
Таблица 42-1. Constants defined in Menu.php
Name | Value | Line Number | Meaning |
---|---|---|---|
HTML_MENU_ENTRY_ACTIVE | 1 | 26 | Active menu entry, the one having the current URL as 'url' attribute |
HTML_MENU_ENTRY_ACTIVEPATH | 2 | 27 | Ancestor of the active menu entry |
HTML_MENU_ENTRY_BREADCRUMB | 6 | 31 | Ancestor of the active menu entry, for menu type 'urhere' |
HTML_MENU_ENTRY_INACTIVE | 0 | 25 | Default menu entry |
HTML_MENU_ENTRY_NEXT | 4 | 29 | "Next" menu entry (for menu type 'prevnext') |
HTML_MENU_ENTRY_PREVIOUS | 3 | 28 | "Previous" menu entry (for menu type 'prevnext') |
HTML_MENU_ENTRY_UPPER | 5 | 30 | "Up" menu entry (for menu type 'prevnext') |
The PEAR::HTML_QuickForm package provides methods for creating, validating, processing HTML forms.
QuickForm is a convenience library for dealing with HTML forms. It provides Javascript and server-side form validation, and is customizable and extensible in many ways. QuickForm consists of multiple files. The main file is QuickForm.php and should be installed in your pear/HTML directory. The other important files are element.php, which handles all methods relative to form elements, and group.php, which deals with methods relative to groups of elements in the form. Both are located in your HTML/QuickForm directory along with the other form objects. input.php contains a common class for all the elements of input type (text, password...). QuickForm has objects for all the common form elements: select, text, password, checkbox, file, submit, reset, button, image, radio, hidden, textarea. QuickForm provides the possibility to create your own elements as long as you comply with the common API.
The purpose of this tutorial is to give the new users of QuickForm an overview of its features and usage patterns. It describes a small subset of available functionality, but points to the parts of the documentation that give a more in-depth overview.
There also exists a somewhat bigger tutorial on QuickForm usage made by Keith Edmunds.
Пример 42-1. Basic QuickForm usage
|
Lets review this example step by step.
The line
$form = new HTML_QuickForm('firstForm'); |
You might guess that
$form->setDefaults(array( 'name' => 'Joe User' )); |
Our form will consist of three elements:
$form->addElement('header', null, 'QuickForm tutorial example'); $form->addElement('text', 'name', 'Enter your name:', array('size' => 50, 'maxlength' => 255)); $form->addElement('submit', null, 'Send'); |
The line
$form->applyFilter('name', 'trim'); |
Next we define a rule for the name field:
$form->addRule('name', 'Please enter your name', 'required', null, 'client'); |
We now have the form built and rules defined and need to decide whether to process it or display:
if ($form->validate()) { // Do some stuff } |
If the form is validated we need to process the values
echo '<h1>Hello, ' . htmlspecialchars($form->exportValue('name')) . '!</h1>'; exit; |
The last line is pretty easy:
$form->display(); |
You now should have an understanding of basic QuickForm functionality, but there are many more features in the package, each of them deserving a separate tutorial. This section will give a short overview of them and point you to the complete documentation.
Groups allow to combine several individual elements into one entity and to use it as one element. This is also used to create pseudo-elements like date and hierselect.
QuickForm offers a lot of possibilities to customize form layout and appearance. Form output is done via renderers - special classes containing necessary logic. There are renderers that directly output HTML and those that use template engines for this.
And finally, you can extend QuickForm by adding your own element types, rules and renderers.
This document is based on questions asked on PEAR general mailing list. You are encouraged to search the list archives to find more verbose answers and examples.
1. The forms I generate with HTML_QuickForm cannot be submitted. When I look at the page's HTML source, I see something like <formArray>.
Recent versions of HTML_QuickForm package require HTML_Common package version 1.2.1 (CVS revision 1.8 in HTML/Common.php) to work properly. If (and only if) an older version of HTML_Common is loaded, these symptoms occur.
Please note that
$ pear list |
2. When I pass some GET parameters to the script containing a form, QuickForm thinks that the form was already submitted, displaying validation errors.
Constructor of HTML_QuickForm accepts a $trackSubmit parameter. Setting this to TRUE will make QuickForm check whether the form was actually submitted. This also helps if you have several forms defined on one page.
Date element is essentially a group of selects, you define the structure of this group in the 'format' option when creating the element:
$form->addElement('date', 'foo', 'The date:', array('format' => 'Y m d')); |
$form->setDefaults(array( 'foo' => array('Y' => 2004, 'm' => 9, 'd' => 29) )); |
To ease using it with database-backed applications, date element also accepts Unix timestamps (generated by mktime()) and strings. The strings are processed by strtotime() functions, so consider its limitations.
4. I receive weird "Call to a member function on a non-object" or "Undefined function" errors, especially when dealing with groups.
These errors tend to appear when you have something which is not a HTML_QuickForm_element in the $elements array passed to addGroup(). This "something" is usually either a PEAR_Error instance (check for these or setup a handler) or, if register_globals is switched on in php.ini, some submitted values (clear the array before adding elements to it).
QuickForm does add a 'name' attribute to the <form> tag, which is invalid in XHTML Strict. Quickform does not depend on that attribute since release 3.2.2, and it's only kept for backwards compatibility. If you desire XHTML Strict compliance and your code does not depend on said attribute, you can remove it via removeAttribute() method.
If your element is a file upload, you should use 'uploadedfile' rule instead.
If your element is a group, you should use addGroupRule() method instead of addRule(). This applies to group-based elements like 'date' and 'hierselect' as well.
7. How do I change * denotes required field and Invalid information entered. / Please correct these fields. validation messages?
You should use setRequiredNote() and setJsWarnings() methods, respectively.
As of release 3.2.5, HTML_QuickForm knows 23 element types that can be created via createElement() and added to the form via addElement(). These can be divided into two big groups: standard HTML elements and custom elements.
Standard HTML elements
Class for <input type="button" /> elements, HTML_QuickForm_button
Class for <input type="checkbox" /> elements, HTML_QuickForm_checkbox
Class for <input type="file" /> elements, HTML_QuickForm_file
Class for <input type="hidden" /> elements, HTML_QuickForm_hidden
Class for <input type="image" /> elements, HTML_QuickForm_image
Class for <input type="password" /> elements, HTML_QuickForm_password
Class for <input type="radio" /> elements, HTML_QuickForm_radio
Class for <input type="reset" /> elements, HTML_QuickForm_reset
Class for <select> elements, HTML_QuickForm_select. The class allows loading of <option> elements from array or database.
Class for <input type="submit" /> elements, HTML_QuickForm_submit
Class for <input type="text" /> elements, HTML_QuickForm_text
Class for <textarea> elements, HTML_QuickForm_textarea
Class for <button> elements, HTML_QuickForm_xbutton
Custom element types
Class for an advanced checkbox type field, HTML_QuickForm_advcheckbox. Basically this fixes a problem that HTML has had where checkboxes can only pass a single value (the value of the checkbox when checked).
Class for a text field with autocompletion feature, HTML_QuickForm_autocomplete. The element looks like a normal HTML input text element that at every keypressed javascript event, searches the array of options for a match and autocompletes the text in case of match.
Class for a group of elements used to input dates (and times), HTML_QuickForm_date
Class for a form element group, HTML_QuickForm_group. QuickForm allows grouping of several elements into one entity and using this entity as a new element.
Class for adding headers to the form, HTML_QuickForm_header
This class, HTML_QuickForm_hiddenselect, behaves as a select element, but instead of creating a <select> it creates hidden elements for all values already selected with setDefaults() or setConstants().
Class to dynamically create "chained" HTML <select> elements, HTML_QuickForm_hierselect. Choosing an option in the first <select> changes the available options of the second select and so on.
Deprecated. A pseudo-element used for adding raw HTML to form, HTML_QuickForm_html. Intended for use with the default renderer only, template-based ones may (and probably will) completely ignore this.
Class for a link type field, HTML_QuickForm_link
Class for static data, HTML_QuickForm_static
HTML_QuickForm has improved a lot since version 2.x. With the addition of a new renderer layer, a lot of methods that were located in the main QuickForm class were actually duplicates of methods in the renderers. Those methods were kept to give user time to adjust their code. With release 3.2 they will be removed, making QuickForm class much lighter and consistent.
At the same time, file upload validation was moved to the file element as this is a more appropriate place.
Removed methods
QuickForm related
HTML_QuickForm::getAttributesString()
HTML_QuickForm::addElementGroup()
HTML_QuickForm::addHeader()
HTML_QuickForm::addData()
Renderer related
HTML_QuickForm::setElementTemplate()
HTML_QuickForm::setHeaderTemplate()
HTML_QuickForm::setFormTemplate()
HTML_QuickForm::setRequiredNoteTemplate()
HTML_QuickForm::clearAllTemplates()
HTML_QuickForm_group::setElementTemplate()
HTML_QuickForm_group::setGroupTemplate()
File upload related
HTML_QuickForm::isUploadedFile()
HTML_QuickForm::getUploadedFile()
HTML_QuickForm::moveUploadedFile()
$form->getAttributes(true); |
Arguments order was changed to conform to the way elements are usually added to QuickForm by addElement(). Use HTML_QuickForm::addGroup() instead and swap the element label with the element name.
A header is now considered like any other element. There is a new HTML_QuickForm_header element that extends HTML_QuickForm_static. Just use
$form->addElement('header', $header_name, $header_text); |
If you absolutely need this feature, use
$form->addElement('html', $data) |
Those methods are now handled by the renderers. How to use these methods depends on your choice of renderer. With QuickForm default renderer, you can use these methods like that:
$form =& new HTML_QuickForm('myform'); $renderer =& $form->defaultRenderer(); $renderer->setFormTemplate('<table><form{attributes}>{content}</form></table>'); $renderer->setHeaderTemplate('<tr><td colspan="2"><b>{header}</b></td></tr>'); $renderer->setGroupTemplate('<table><tr>{content}</tr></table>'); $renderer->setGroupElementTemplate('<td>{element}<br /><!-- BEGIN required -->*<!-- END required -->{label}</td>'); |
File-related methods and rules have been moved to the file element HTML_QuickForm_file because it makes more sense this way and you don't have to include upload-related code if you are not using uploads. You have access to these methods like that:
$form = new HTML_QuickForm('myform'); $file =& $form->addElement('file', 'myfile', 'Your file:'); $form->addRule('myfile', 'Cannot exceed 1776 bytes', 'maxfilesize', 1776); if ($file->isUploadedFile()) { $file->moveUploadedFile('/tmp', 'testfile.txt'); } |
$file =& $form->getElement('myfile'); if ($file->isUploadedFile()) { $fileInfo = $file->getValue(); } |
This section describes the available subpackages for HTML_QuickForm, e.g. custom elements or renderers.
A custom element that emulates via two select boxes a select box that allows selecting of multiple options.
If you use the Tableless renderer (see below, HTML_QuickForm_Renderer_Tableless), this subpackage replaces the default client-side validation with a JavaScript alert window by dynamic (using DHTML) error messages that are printed directly above each erroneous element. (documentation)
This is another custom element. It creates an HTML input text element that at every keypressed javascript event, returns a list of options in a dynamic dropdown select box (especially useful to emulate a select box with a huge number of options). This element uses the AJAX technology.
This is a replacement for the default renderer of HTML_QuickForm that uses only XHTML and CSS but no table tags, and generates fully valid XHTML output. (documentation)
This section describes some packages that makes working with HTML_QuickForm easier, either in the case of working with databases or in the case of forms that have multiple pages.
FormBuilder aids in rapid application development using the packages DB_DataObject and HTML_QuickForm. (documentation)
This is a package that builds on PEAR DB and MDB2 to abstract datatypes and automate table creation, data validation, insert, update, delete, and select. It combines these with HTML_QuickForm to automatically generate input forms that match the table column definitions. (documentation)
If you want to create forms with multiple pages, this is the right package for you. It is an implementation of a PageController pattern. (documentation)
You can find more packages that have optional or required dependencies on HTML_QuickForm on the package site.
To be written.
Form's name.
(optional) Form's method
(optional) Form's action
(optional) Form's target
(optional) Extra attributes for <form> tag
(optional) Whether to track if the form was submitted by adding a special hidden field. If the name of such field is not present in the $_GET or $_POST values, the form will be considered as not submitted.
Adds an element into the form. If $element is a string representing an element type, then this method accepts variable number of parameters, their meaning and count depending on element type.
Parameters starting from second will be passed to the element's constructor, consult the docs for the appropriate element to find out which parameters to pass.
Таблица 42-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
QUICKFORM_UNREGISTERED_ELEMENT | Element '$element' does not exist in HTML_QuickForm::_loadElement() | Tried to add an element of unknown type | Check the type name spelling or use HTML_QuickForm::registerElementType() |
QUICKFORM_INVALID_ELEMENT_NAME | Element 'elementName' already exists in HTML_QuickForm::addElement() | Tried to add an element having a name of an existing element, but of different type | Choose a different name for an element |
Creates a new form element of the given type. This method accepts variable number of parameters, their meaning and count depending on $elementType.
Parameters starting from second will be passed to the element's constructor, consult the docs for the appropriate element to find out which parameters to pass.
Таблица 42-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
QUICKFORM_UNREGISTERED_ELEMENT | Element '$element' does not exist in HTML_QuickForm::_loadElement() | Tried to create an element of unknown type | Check the type name spelling or use HTML_QuickForm::registerElementType() |
Таблица 42-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
QUICKFORM_NONEXIST_ELEMENT | Element '$element' does not exist in HTML_QuickForm::getElement() | Tried to get a non-existant element | Check the element's name spelling |
Inserts a new element right before the other element.
It is not possible to check whether the $element is already added to the form, therefore if you want to move the existing form element to a new position, you'll have to use removeElement():
$form->insertElementBefore($form->removeElement('foo', false), 'bar'); |
Element to insert (instance of HTML_QuickForm_element)
Name of the element before which the new one is inserted
Таблица 42-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
QUICKFORM_INVALID_ELEMENT_NAME | Several elements named $nameAfter exist in HTML_QuickForm::insertElementBefore() | Several elements named $nameAfter (e.g.: radios) exist in the form. The method does not handle this case. | Insert before some other element. Consider adding a dummy element with a unique name. |
QUICKFORM_INVALID_ELEMENT_NAME | Element '$elementName' already exists in HTML_QuickForm::insertElementBefore() | Element exists with the same name as $element but of different type | Give some other name to the inserted element. |
QUICKFORM_NONEXIST_ELEMENT | Element $nameAfter does not exist in HTML_QuickForm::insertElementBefore() | Tried to insert before a non-existant element | Check the element's name spelling |
Tells whether a result is an error (i.e. whether $value is an instance of HTML_QuickForm_Error).
Returns whether or not the form element type is supported. New types are added via HTML_QuickForm::registerElementType().
Registers a new element type. After that, elements of this type may be created via createElement() and added to form via addElement().
Name of element type
Include path for element type
Element class name
The element name
TRUE if rules for this element are to be removed too
Таблица 42-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
QUICKFORM_NONEXIST_ELEMENT | Element '$elementName' does not exist in HTML_QuickForm::removeElement() | Tried to remove a non-existant element | Check the element's name spelling |
Updates Attributes for one or more elements
Внимание |
This may not work for groups and group-based elements (date, hierselect). To ensure proper behaviour, you should update attributes of grouped elements manually. |
To be written
This is a base class for all QuickForm elements. It defines the API that is implemented by all the child classes representing actual form elements. You should use these elements, there is no need to directly instantiate HTML_QuickForm_element.
If you would like to create your own element to use with QuickForm, you should extend this class or one of its descendants and make sure to implement all methods defined here. There is also toHtml() method defined in HTML_Common that should be implemented.
HTML_Common
HTML_QuickForm_element
Таблица 42-1. Classes that extend HTML_QuickForm_element
Class | Summary |
---|---|
HTML_QuickForm_group | HTML class for a form element group |
HTML_QuickForm_input | Base class for input form elements |
HTML_QuickForm_select | Class to dynamically create an HTML SELECT |
HTML_QuickForm_static | HTML class for static data |
HTML_QuickForm_textarea | HTML class for a textarea type field |
Name of the element
Label(s) for the element
Associative array of tag attributes or HTML attributes name="value" pairs
This method rarely needs to be called directly, it is usually called from HTML_QuickForm::accept() method.
an instance of HTML_QuickForm_Renderer subclass
Whether an element is required
An error message associated with an element
This method is not intended to be called directly. It is called by HTML_QuickForm::exportValue() and HTML_QuickForm::exportValues() methods.
The method first tries to find a value for itself in a passed array, if such a value is not found it takes the display value via getValue(). It then filters out the values that cannot possibly be submitted by this element and returns the result.
array of submitted values to search
whether to return the value as associative array
When the element is displayed after the call to freeze(), only its value is displayed without the input tags, thus the element cannot be edited. If persistant freeze is set, then hidden field containing the element value will be output, too.
Замечание: This method makes sense only with the elements that actually are editable in the first place. It has no effect on buttons, images, hidden fields, static content and the like.
see unfreeze(), isFrozen(), setPersistantFreeze(), getFrozenHtml(), HTML_QuickForm::freeze(), HTML_QuickForm::isFrozen().
Пример 42-1. Freezing the text element
|
Пример 42-2. Output
|
This method returns the HTML for the element in frozen state. There is rarely a need to call it directly.
Замечание: This method is not intended to be called directly.
If you are creating your own element, you should override this method and create handlers for each of available QuickForm events.
QuickForm events
This event is sent by HTML_QuickForm::addElement() method when adding a new element to the form. Its handler should usually send 'createElement' and 'updateValue' events.
This event is sent by HTML_QuickForm::createElement() method after the element object is instantiated. Its handler should usually call class constructor using the contents of $arg as parameters.
The event is sent by HTML_QuickForm_group::setValue() method to each of the grouped elements. The handler generally should set the element's value to $arg.
The event is sent by QuickForm when the element is added to the form and when form default and constant values are set. The handler for this event is the most complex one: it should search for element's value within form's constant, submit (if applicable) and default values (in that order) and set the element's value to the found one.
Label is a description text that will be displayed near the element. Some renderers can handle multiple labels for the element.
Sets whether an element value should be kept in an hidden field when the element is frozen or not.
see freeze(), isFrozen(), setPersistantFreeze(), getFrozenHtml(), HTML_QuickForm::freeze(), HTML_QuickForm::isFrozen().
Since <input> elements have very similar HTML representations, they have this common base class. You don't need to instantiate it directly, use one of the child classes.
HTML_Common
HTML_QuickForm_input
Таблица 42-1. Classes that extend HTML_QuickForm_input
Class | Summary |
---|---|
HTML_QuickForm_button | HTML class for a button type element |
HTML_QuickForm_checkbox | HTML class for a checkbox type field |
HTML_QuickForm_file | HTML class for a file type element |
HTML_QuickForm_hidden | HTML class for a hidden type element |
HTML_QuickForm_image | HTML class for a image type element |
HTML_QuickForm_password | HTML class for a password type field |
HTML_QuickForm_radio | HTML class for a radio type element |
HTML_QuickForm_reset | HTML class for a reset type element |
HTML_QuickForm_submit | HTML class for a submit type element |
HTML_QuickForm_text | HTML class for a text field |
HTML_QuickForm_input Inherited Methods
Таблица 42-2. Inherited from HTML_QuickForm_element
Method Name | Summary |
---|---|
Constructor HTML_QuickForm_element::HTML_QuickForm_element() | Class constructor |
HTML_QuickForm_element::accept() | Accepts a renderer |
HTML_QuickForm_element::apiVersion() | Returns the current API version |
HTML_QuickForm_element::exportValue() | Returns a 'safe' element's value |
HTML_QuickForm_element::freeze() | Freeze the element so that only its value is returned |
HTML_QuickForm_element::getFrozenHtml() | Returns the value of field without HTML tags |
HTML_QuickForm_element::getLabel() | Returns display text for the element |
HTML_QuickForm_element::getName() | Returns the element name |
HTML_QuickForm_element::getType() | Returns element type |
HTML_QuickForm_element::getValue() | Returns the value of the form element |
HTML_QuickForm_element::isFrozen() | Returns whether or not the element is frozen |
HTML_QuickForm_element::onQuickFormEvent() | Called by HTML_QuickForm whenever form event is made on this element |
HTML_QuickForm_element::setLabel() | Sets display text for the element |
HTML_QuickForm_element::setName() | Sets the input field name |
HTML_QuickForm_element::setPersistantFreeze() | Sets wether an element value should be kept in an hidden field when the element is frozen or not |
HTML_QuickForm_element::setValue() | Sets the value of the form element |
HTML_QuickForm_element::unfreeze() | Unfreezes the form element |
Input field name attribute
Label(s) for the input field
Either a typical HTML attribute string or an associative array
HTML_Common
HTML_QuickForm_button
HTML_QuickForm_button Inherited Methods
Таблица 42-1. Inherited from HTML_QuickForm_input
Method Name | Summary |
---|---|
Constructor HTML_QuickForm_input::HTML_QuickForm_input() | Class constructor |
HTML_QuickForm_input::exportValue() | We don't need values from button-type elements (except submit) and files |
HTML_QuickForm_input::getName() | Returns the element name |
HTML_QuickForm_input::getValue() | Returns the value of the form element |
HTML_QuickForm_input::onQuickFormEvent() | Called by HTML_QuickForm whenever form event is made on this element |
HTML_QuickForm_input::setName() | Sets the input field name |
HTML_QuickForm_input::setType() | Sets the element type |
HTML_QuickForm_input::setValue() | Sets the value of the form element |
Таблица 42-2. Inherited from HTML_QuickForm_element
Method Name | Summary |
---|---|
Constructor HTML_QuickForm_element::HTML_QuickForm_element() | Class constructor |
HTML_QuickForm_element::accept() | Accepts a renderer |
HTML_QuickForm_element::apiVersion() | Returns the current API version |
HTML_QuickForm_element::exportValue() | Returns a 'safe' element's value |
HTML_QuickForm_element::freeze() | Freeze the element so that only its value is returned |
HTML_QuickForm_element::getFrozenHtml() | Returns the value of field without HTML tags |
HTML_QuickForm_element::getLabel() | Returns display text for the element |
HTML_QuickForm_element::getName() | Returns the element name |
HTML_QuickForm_element::getType() | Returns element type |
HTML_QuickForm_element::getValue() | Returns the value of the form element |
HTML_QuickForm_element::isFrozen() | Returns whether or not the element is frozen |
HTML_QuickForm_element::onQuickFormEvent() | Called by HTML_QuickForm whenever form event is made on this element |
HTML_QuickForm_element::setLabel() | Sets display text for the element |
HTML_QuickForm_element::setName() | Sets the input field name |
HTML_QuickForm_element::setPersistantFreeze() | Sets wether an element value should be kept in an hidden field when the element is frozen or not |
HTML_QuickForm_element::setValue() | Sets the value of the form element |
HTML_QuickForm_element::unfreeze() | Unfreezes the form element |
(optional)Input field name attribute
(optional)Input field value
(optional)Either a typical HTML attribute string or an associative array
HTML_Common
HTML_QuickForm_checkbox
Таблица 42-1. Classes that extend HTML_QuickForm_checkbox
Class | Summary |
---|---|
HTML_QuickForm_advcheckbox | HTML class for an advanced checkbox type field |
HTML_QuickForm_checkbox Inherited Methods
Таблица 42-2. Inherited from HTML_QuickForm_input
Method Name | Summary |
---|---|
Constructor HTML_QuickForm_input::HTML_QuickForm_input() | Class constructor |
HTML_QuickForm_input::exportValue() | We don't need values from button-type elements (except submit) and files |
HTML_QuickForm_input::getName() | Returns the element name |
HTML_QuickForm_input::getValue() | Returns the value of the form element |
HTML_QuickForm_input::onQuickFormEvent() | Called by HTML_QuickForm whenever form event is made on this element |
HTML_QuickForm_input::setName() | Sets the input field name |
HTML_QuickForm_input::setType() | Sets the element type |
HTML_QuickForm_input::setValue() | Sets the value of the form element |
Таблица 42-3. Inherited from HTML_QuickForm_element
Method Name | Summary |
---|---|
Constructor HTML_QuickForm_element::HTML_QuickForm_element() | Class constructor |
HTML_QuickForm_element::accept() | Accepts a renderer |
HTML_QuickForm_element::apiVersion() | Returns the current API version |
HTML_QuickForm_element::exportValue() | Returns a 'safe' element's value |
HTML_QuickForm_element::freeze() | Freeze the element so that only its value is returned |
HTML_QuickForm_element::getFrozenHtml() | Returns the value of field without HTML tags |
HTML_QuickForm_element::getLabel() | Returns display text for the element |
HTML_QuickForm_element::getName() | Returns the element name |
HTML_QuickForm_element::getType() | Returns element type |
HTML_QuickForm_element::getValue() | Returns the value of the form element |
HTML_QuickForm_element::isFrozen() | Returns whether or not the element is frozen |
HTML_QuickForm_element::onQuickFormEvent() | Called by HTML_QuickForm whenever form event is made on this element |
HTML_QuickForm_element::setLabel() | Sets display text for the element |
HTML_QuickForm_element::setName() | Sets the input field name |
HTML_QuickForm_element::setPersistantFreeze() | Sets wether an element value should be kept in an hidden field when the element is frozen or not |
HTML_QuickForm_element::setValue() | Sets the value of the form element |
HTML_QuickForm_element::unfreeze() | Unfreezes the form element |
(optional)Input field name attribute
(optional)Input field label
(optional)Checkbox display text
(optional)Either a typical HTML attribute string or an associative array
Returns TRUE if checkbox has a "checked" attribute, FALSE otherwise. getValue() is an alias for this method. Thus the only value checkbox element can have in QuickForm is TRUE.
This sets or removes the element's "checked" attribute based on $checked value. setValue() is an alias for this method.
This means the text that would be displayed with the checkbox, automatically enclosed in <label> tags. The label in QuickForm's sense is set via setLabel().
Alongside the usual element's methods, the class has special methods for working with uploaded files. When the class is included it also registers rules for validating the uploaded files.
HTML_Common
HTML_QuickForm_file
HTML_QuickForm_file Inherited Methods
Таблица 42-1. Inherited from HTML_QuickForm_input
Method Name | Summary |
---|---|
Constructor HTML_QuickForm_input::HTML_QuickForm_input() | Class constructor |
HTML_QuickForm_input::exportValue() | We don't need values from button-type elements (except submit) and files |
HTML_QuickForm_input::getName() | Returns the element name |
HTML_QuickForm_input::getValue() | Returns the value of the form element |
HTML_QuickForm_input::onQuickFormEvent() | Called by HTML_QuickForm whenever form event is made on this element |
HTML_QuickForm_input::setName() | Sets the input field name |
HTML_QuickForm_input::setType() | Sets the element type |
HTML_QuickForm_input::setValue() | Sets the value of the form element |
Таблица 42-2. Inherited from HTML_QuickForm_element
Method Name | Summary |
---|---|
Constructor HTML_QuickForm_element::HTML_QuickForm_element() | Class constructor |
HTML_QuickForm_element::accept() | Accepts a renderer |
HTML_QuickForm_element::apiVersion() | Returns the current API version |
HTML_QuickForm_element::exportValue() | Returns a 'safe' element's value |
HTML_QuickForm_element::freeze() | Freeze the element so that only its value is returned |
HTML_QuickForm_element::getFrozenHtml() | Returns the value of field without HTML tags |
HTML_QuickForm_element::getLabel() | Returns display text for the element |
HTML_QuickForm_element::getName() | Returns the element name |
HTML_QuickForm_element::getType() | Returns element type |
HTML_QuickForm_element::getValue() | Returns the value of the form element |
HTML_QuickForm_element::isFrozen() | Returns whether or not the element is frozen |
HTML_QuickForm_element::onQuickFormEvent() | Called by HTML_QuickForm whenever form event is made on this element |
HTML_QuickForm_element::setLabel() | Sets display text for the element |
HTML_QuickForm_element::setName() | Sets the input field name |
HTML_QuickForm_element::setPersistantFreeze() | Sets wether an element value should be kept in an hidden field when the element is frozen or not |
HTML_QuickForm_element::setValue() | Sets the value of the form element |
HTML_QuickForm_element::unfreeze() | Unfreezes the form element |
Input field name attribute
Input field label
(optional)Either a typical HTML attribute string or an associative array
Returns the information about the file upload, as in the $_FILES array. Note that while there exists a setValue() method, the method does nothing at all. The file element does not have a value if the form was not submitted.
Destination directory path
New file name (if not given, original file name will be used).
HTML_Common
HTML_QuickForm_hidden
HTML_QuickForm_hidden Inherited Methods
Таблица 42-1. Inherited from HTML_QuickForm_input
Method Name | Summary |
---|---|
Constructor HTML_QuickForm_input::HTML_QuickForm_input() | Class constructor |
HTML_QuickForm_input::exportValue() | We don't need values from button-type elements (except submit) and files |
HTML_QuickForm_input::getName() | Returns the element name |
HTML_QuickForm_input::getValue() | Returns the value of the form element |
HTML_QuickForm_input::onQuickFormEvent() | Called by HTML_QuickForm whenever form event is made on this element |
HTML_QuickForm_input::setName() | Sets the input field name |
HTML_QuickForm_input::setType() | Sets the element type |
HTML_QuickForm_input::setValue() | Sets the value of the form element |
Таблица 42-2. Inherited from HTML_QuickForm_element
Method Name | Summary |
---|---|
Constructor HTML_QuickForm_element::HTML_QuickForm_element() | Class constructor |
HTML_QuickForm_element::accept() | Accepts a renderer |
HTML_QuickForm_element::apiVersion() | Returns the current API version |
HTML_QuickForm_element::exportValue() | Returns a 'safe' element's value |
HTML_QuickForm_element::freeze() | Freeze the element so that only its value is returned |
HTML_QuickForm_element::getFrozenHtml() | Returns the value of field without HTML tags |
HTML_QuickForm_element::getLabel() | Returns display text for the element |
HTML_QuickForm_element::getName() | Returns the element name |
HTML_QuickForm_element::getType() | Returns element type |
HTML_QuickForm_element::getValue() | Returns the value of the form element |
HTML_QuickForm_element::isFrozen() | Returns whether or not the element is frozen |
HTML_QuickForm_element::onQuickFormEvent() | Called by HTML_QuickForm whenever form event is made on this element |
HTML_QuickForm_element::setLabel() | Sets display text for the element |
HTML_QuickForm_element::setName() | Sets the input field name |
HTML_QuickForm_element::setPersistantFreeze() | Sets wether an element value should be kept in an hidden field when the element is frozen or not |
HTML_QuickForm_element::setValue() | Sets the value of the form element |
HTML_QuickForm_element::unfreeze() | Unfreezes the form element |
(optional)Input field name attribute
(optional)Input field value
(optional)Either a typical HTML attribute string or an associative array
HTML_Common
HTML_QuickForm_image
HTML_QuickForm_image Inherited Methods
Таблица 42-1. Inherited from HTML_QuickForm_input
Method Name | Summary |
---|---|
Constructor HTML_QuickForm_input::HTML_QuickForm_input() | Class constructor |
HTML_QuickForm_input::exportValue() | We don't need values from button-type elements (except submit) and files |
HTML_QuickForm_input::getName() | Returns the element name |
HTML_QuickForm_input::getValue() | Returns the value of the form element |
HTML_QuickForm_input::onQuickFormEvent() | Called by HTML_QuickForm whenever form event is made on this element |
HTML_QuickForm_input::setName() | Sets the input field name |
HTML_QuickForm_input::setType() | Sets the element type |
HTML_QuickForm_input::setValue() | Sets the value of the form element |
Таблица 42-2. Inherited from HTML_QuickForm_element
Method Name | Summary |
---|---|
Constructor HTML_QuickForm_element::HTML_QuickForm_element() | Class constructor |
HTML_QuickForm_element::accept() | Accepts a renderer |
HTML_QuickForm_element::apiVersion() | Returns the current API version |
HTML_QuickForm_element::exportValue() | Returns a 'safe' element's value |
HTML_QuickForm_element::freeze() | Freeze the element so that only its value is returned |
HTML_QuickForm_element::getFrozenHtml() | Returns the value of field without HTML tags |
HTML_QuickForm_element::getLabel() | Returns display text for the element |
HTML_QuickForm_element::getName() | Returns the element name |
HTML_QuickForm_element::getType() | Returns element type |
HTML_QuickForm_element::getValue() | Returns the value of the form element |
HTML_QuickForm_element::isFrozen() | Returns whether or not the element is frozen |
HTML_QuickForm_element::onQuickFormEvent() | Called by HTML_QuickForm whenever form event is made on this element |
HTML_QuickForm_element::setLabel() | Sets display text for the element |
HTML_QuickForm_element::setName() | Sets the input field name |
HTML_QuickForm_element::setPersistantFreeze() | Sets wether an element value should be kept in an hidden field when the element is frozen or not |
HTML_QuickForm_element::setValue() | Sets the value of the form element |
HTML_QuickForm_element::unfreeze() | Unfreezes the form element |
(optional)Element name attribute
(optional)Image source
(optional)Either a typical HTML attribute string or an associative array
HTML_Common
HTML_QuickForm_password
HTML_QuickForm_password Inherited Methods
Таблица 42-1. Inherited from HTML_QuickForm_input
Method Name | Summary |
---|---|
Constructor HTML_QuickForm_input::HTML_QuickForm_input() | Class constructor |
HTML_QuickForm_input::exportValue() | We don't need values from button-type elements (except submit) and files |
HTML_QuickForm_input::getName() | Returns the element name |
HTML_QuickForm_input::getValue() | Returns the value of the form element |
HTML_QuickForm_input::onQuickFormEvent() | Called by HTML_QuickForm whenever form event is made on this element |
HTML_QuickForm_input::setName() | Sets the input field name |
HTML_QuickForm_input::setType() | Sets the element type |
HTML_QuickForm_input::setValue() | Sets the value of the form element |
Таблица 42-2. Inherited from HTML_QuickForm_element
Method Name | Summary |
---|---|
Constructor HTML_QuickForm_element::HTML_QuickForm_element() | Class constructor |
HTML_QuickForm_element::accept() | Accepts a renderer |
HTML_QuickForm_element::apiVersion() | Returns the current API version |
HTML_QuickForm_element::exportValue() | Returns a 'safe' element's value |
HTML_QuickForm_element::freeze() | Freeze the element so that only its value is returned |
HTML_QuickForm_element::getFrozenHtml() | Returns the value of field without HTML tags |
HTML_QuickForm_element::getLabel() | Returns display text for the element |
HTML_QuickForm_element::getName() | Returns the element name |
HTML_QuickForm_element::getType() | Returns element type |
HTML_QuickForm_element::getValue() | Returns the value of the form element |
HTML_QuickForm_element::isFrozen() | Returns whether or not the element is frozen |
HTML_QuickForm_element::onQuickFormEvent() | Called by HTML_QuickForm whenever form event is made on this element |
HTML_QuickForm_element::setLabel() | Sets display text for the element |
HTML_QuickForm_element::setName() | Sets the input field name |
HTML_QuickForm_element::setPersistantFreeze() | Sets wether an element value should be kept in an hidden field when the element is frozen or not |
HTML_QuickForm_element::setValue() | Sets the value of the form element |
HTML_QuickForm_element::unfreeze() | Unfreezes the form element |
(optional)Input field name attribute
(optional)Input field label
(optional)Either a typical HTML attribute string or an associative array
HTML_Common
HTML_QuickForm_radio
HTML_QuickForm_radio Inherited Methods
Таблица 42-1. Inherited from HTML_QuickForm_input
Method Name | Summary |
---|---|
Constructor HTML_QuickForm_input::HTML_QuickForm_input() | Class constructor |
HTML_QuickForm_input::exportValue() | We don't need values from button-type elements (except submit) and files |
HTML_QuickForm_input::getName() | Returns the element name |
HTML_QuickForm_input::getValue() | Returns the value of the form element |
HTML_QuickForm_input::onQuickFormEvent() | Called by HTML_QuickForm whenever form event is made on this element |
HTML_QuickForm_input::setName() | Sets the input field name |
HTML_QuickForm_input::setType() | Sets the element type |
HTML_QuickForm_input::setValue() | Sets the value of the form element |
Таблица 42-2. Inherited from HTML_QuickForm_element
Method Name | Summary |
---|---|
Constructor HTML_QuickForm_element::HTML_QuickForm_element() | Class constructor |
HTML_QuickForm_element::accept() | Accepts a renderer |
HTML_QuickForm_element::apiVersion() | Returns the current API version |
HTML_QuickForm_element::exportValue() | Returns a 'safe' element's value |
HTML_QuickForm_element::freeze() | Freeze the element so that only its value is returned |
HTML_QuickForm_element::getFrozenHtml() | Returns the value of field without HTML tags |
HTML_QuickForm_element::getLabel() | Returns display text for the element |
HTML_QuickForm_element::getName() | Returns the element name |
HTML_QuickForm_element::getType() | Returns element type |
HTML_QuickForm_element::getValue() | Returns the value of the form element |
HTML_QuickForm_element::isFrozen() | Returns whether or not the element is frozen |
HTML_QuickForm_element::onQuickFormEvent() | Called by HTML_QuickForm whenever form event is made on this element |
HTML_QuickForm_element::setLabel() | Sets display text for the element |
HTML_QuickForm_element::setName() | Sets the input field name |
HTML_QuickForm_element::setPersistantFreeze() | Sets wether an element value should be kept in an hidden field when the element is frozen or not |
HTML_QuickForm_element::setValue() | Sets the value of the form element |
HTML_QuickForm_element::unfreeze() | Unfreezes the form element |
Input field name attribute
Label(s) for a field
Text to display near the radio
Input field value
Either a typical HTML attribute string or an associative array
This means the text that would be displayed with the radio, automatically enclosed in <label> tags. The label in QuickForm's sense is set via setLabel().
HTML_Common
HTML_QuickForm_reset
HTML_QuickForm_reset Inherited Methods
Таблица 42-1. Inherited from HTML_QuickForm_input
Method Name | Summary |
---|---|
Constructor HTML_QuickForm_input::HTML_QuickForm_input() | Class constructor |
HTML_QuickForm_input::exportValue() | We don't need values from button-type elements (except submit) and files |
HTML_QuickForm_input::getName() | Returns the element name |
HTML_QuickForm_input::getValue() | Returns the value of the form element |
HTML_QuickForm_input::onQuickFormEvent() | Called by HTML_QuickForm whenever form event is made on this element |
HTML_QuickForm_input::setName() | Sets the input field name |
HTML_QuickForm_input::setType() | Sets the element type |
HTML_QuickForm_input::setValue() | Sets the value of the form element |
Таблица 42-2. Inherited from HTML_QuickForm_element
Method Name | Summary |
---|---|
Constructor HTML_QuickForm_element::HTML_QuickForm_element() | Class constructor |
HTML_QuickForm_element::accept() | Accepts a renderer |
HTML_QuickForm_element::apiVersion() | Returns the current API version |
HTML_QuickForm_element::exportValue() | Returns a 'safe' element's value |
HTML_QuickForm_element::freeze() | Freeze the element so that only its value is returned |
HTML_QuickForm_element::getFrozenHtml() | Returns the value of field without HTML tags |
HTML_QuickForm_element::getLabel() | Returns display text for the element |
HTML_QuickForm_element::getName() | Returns the element name |
HTML_QuickForm_element::getType() | Returns element type |
HTML_QuickForm_element::getValue() | Returns the value of the form element |
HTML_QuickForm_element::isFrozen() | Returns whether or not the element is frozen |
HTML_QuickForm_element::onQuickFormEvent() | Called by HTML_QuickForm whenever form event is made on this element |
HTML_QuickForm_element::setLabel() | Sets display text for the element |
HTML_QuickForm_element::setName() | Sets the input field name |
HTML_QuickForm_element::setPersistantFreeze() | Sets wether an element value should be kept in an hidden field when the element is frozen or not |
HTML_QuickForm_element::setValue() | Sets the value of the form element |
HTML_QuickForm_element::unfreeze() | Unfreezes the form element |
(optional)Input field name attribute
(optional)Input field value
(optional)Either a typical HTML attribute string or an associative array
The highlight of this class is that it allows populating the options from associative array or from the database.
HTML_Common
HTML_QuickForm_select
Таблица 42-1. Classes that extend HTML_QuickForm_select
Class | Summary |
---|---|
HTML_QuickForm_hiddenselect | Creates hidden elements with select's values |
HTML_QuickForm_select Inherited Methods
Таблица 42-2. Inherited from HTML_QuickForm_element
Method Name | Summary |
---|---|
Constructor HTML_QuickForm_element::HTML_QuickForm_element() | Class constructor |
HTML_QuickForm_element::accept() | Accepts a renderer |
HTML_QuickForm_element::apiVersion() | Returns the current API version |
HTML_QuickForm_element::exportValue() | Returns a 'safe' element's value |
HTML_QuickForm_element::freeze() | Freeze the element so that only its value is returned |
HTML_QuickForm_element::getFrozenHtml() | Returns the value of field without HTML tags |
HTML_QuickForm_element::getLabel() | Returns display text for the element |
HTML_QuickForm_element::getName() | Returns the element name |
HTML_QuickForm_element::getType() | Returns element type |
HTML_QuickForm_element::getValue() | Returns the value of the form element |
HTML_QuickForm_element::isFrozen() | Returns whether or not the element is frozen |
HTML_QuickForm_element::onQuickFormEvent() | Called by HTML_QuickForm whenever form event is made on this element |
HTML_QuickForm_element::setLabel() | Sets display text for the element |
HTML_QuickForm_element::setName() | Sets the input field name |
HTML_QuickForm_element::setPersistantFreeze() | Sets wether an element value should be kept in an hidden field when the element is frozen or not |
HTML_QuickForm_element::setValue() | Sets the value of the form element |
HTML_QuickForm_element::unfreeze() | Unfreezes the form element |
Select name attribute
Label(s) for the select
Data to be used to populate options
Either a typical HTML attribute string or an associative array
Display text for the OPTION
Value for the OPTION
Either a typical HTML attribute string or an associative array
If select has a multiple attribute present, then this method returns the name with brackets appended, else the result is identical to getName().
This method is a simulated overloaded method. The arguments, other than the first are optional and only mean something depending on the type of the first argument.
If the first argument is an array then all arguments are passed in order to loadArray(). If the first argument is a DB_Result then all arguments are passed in order to loadDbResult(). If the first argument is a string or a DB connection then all arguments are passed in order to loadQuery().
Options source currently supports assoc array or DB_result
(optional) See function detail
(optional) See function detail
(optional) See function detail
(optional) See function detail
Associative array of options
(optional) Array or comma delimited string of selected values
If no column names are specified the first two columns of the result are used as the text and value columns respectively.
DB_result object
(optional) Name of column to display as the OPTION text
(optional) Name of column to use as the OPTION value
(optional) Array or comma delimited string of selected values
If no column names are specified the first two columns of the result are used as the text and value columns respectively.
Either an existing DB connection or a valid dsn
SQL query string
(optional) Name of column to display as the OPTION text
(optional) Name of column to use as the OPTION value
(optional) Array or comma delimited string of selected values
This method just adds or removes the multiple attribute of select depending on $multiple value.
This method is an alias for setValue(). For multiple selects you can pass either an array or a comma delimited string of values.
HTML_Common
HTML_QuickForm_submit
HTML_QuickForm_submit Inherited Methods
Таблица 42-1. Inherited from HTML_QuickForm_input
Method Name | Summary |
---|---|
Constructor HTML_QuickForm_input::HTML_QuickForm_input() | Class constructor |
HTML_QuickForm_input::exportValue() | We don't need values from button-type elements (except submit) and files |
HTML_QuickForm_input::getName() | Returns the element name |
HTML_QuickForm_input::getValue() | Returns the value of the form element |
HTML_QuickForm_input::onQuickFormEvent() | Called by HTML_QuickForm whenever form event is made on this element |
HTML_QuickForm_input::setName() | Sets the input field name |
HTML_QuickForm_input::setType() | Sets the element type |
HTML_QuickForm_input::setValue() | Sets the value of the form element |
Таблица 42-2. Inherited from HTML_QuickForm_element
Method Name | Summary |
---|---|
Constructor HTML_QuickForm_element::HTML_QuickForm_element() | Class constructor |
HTML_QuickForm_element::accept() | Accepts a renderer |
HTML_QuickForm_element::apiVersion() | Returns the current API version |
HTML_QuickForm_element::exportValue() | Returns a 'safe' element's value |
HTML_QuickForm_element::freeze() | Freeze the element so that only its value is returned |
HTML_QuickForm_element::getFrozenHtml() | Returns the value of field without HTML tags |
HTML_QuickForm_element::getLabel() | Returns display text for the element |
HTML_QuickForm_element::getName() | Returns the element name |
HTML_QuickForm_element::getType() | Returns element type |
HTML_QuickForm_element::getValue() | Returns the value of the form element |
HTML_QuickForm_element::isFrozen() | Returns whether or not the element is frozen |
HTML_QuickForm_element::onQuickFormEvent() | Called by HTML_QuickForm whenever form event is made on this element |
HTML_QuickForm_element::setLabel() | Sets display text for the element |
HTML_QuickForm_element::setName() | Sets the input field name |
HTML_QuickForm_element::setPersistantFreeze() | Sets wether an element value should be kept in an hidden field when the element is frozen or not |
HTML_QuickForm_element::setValue() | Sets the value of the form element |
HTML_QuickForm_element::unfreeze() | Unfreezes the form element |
Input field name attribute
Input field value
Either a typical HTML attribute string or an associative array
HTML_Common
HTML_QuickForm_text
Таблица 42-1. Classes that extend HTML_QuickForm_text
Class | Summary |
---|---|
HTML_QuickForm_autocomplete | HTML class for a text field with autocompletion feature |
HTML_QuickForm_text Inherited Methods
Таблица 42-2. Inherited from HTML_QuickForm_input
Method Name | Summary |
---|---|
Constructor HTML_QuickForm_input::HTML_QuickForm_input() | Class constructor |
HTML_QuickForm_input::exportValue() | We don't need values from button-type elements (except submit) and files |
HTML_QuickForm_input::getName() | Returns the element name |
HTML_QuickForm_input::getValue() | Returns the value of the form element |
HTML_QuickForm_input::onQuickFormEvent() | Called by HTML_QuickForm whenever form event is made on this element |
HTML_QuickForm_input::setName() | Sets the input field name |
HTML_QuickForm_input::setType() | Sets the element type |
HTML_QuickForm_input::setValue() | Sets the value of the form element |
Таблица 42-3. Inherited from HTML_QuickForm_element
Method Name | Summary |
---|---|
Constructor HTML_QuickForm_element::HTML_QuickForm_element() | Class constructor |
HTML_QuickForm_element::accept() | Accepts a renderer |
HTML_QuickForm_element::apiVersion() | Returns the current API version |
HTML_QuickForm_element::exportValue() | Returns a 'safe' element's value |
HTML_QuickForm_element::freeze() | Freeze the element so that only its value is returned |
HTML_QuickForm_element::getFrozenHtml() | Returns the value of field without HTML tags |
HTML_QuickForm_element::getLabel() | Returns display text for the element |
HTML_QuickForm_element::getName() | Returns the element name |
HTML_QuickForm_element::getType() | Returns element type |
HTML_QuickForm_element::getValue() | Returns the value of the form element |
HTML_QuickForm_element::isFrozen() | Returns whether or not the element is frozen |
HTML_QuickForm_element::onQuickFormEvent() | Called by HTML_QuickForm whenever form event is made on this element |
HTML_QuickForm_element::setLabel() | Sets display text for the element |
HTML_QuickForm_element::setName() | Sets the input field name |
HTML_QuickForm_element::setPersistantFreeze() | Sets wether an element value should be kept in an hidden field when the element is frozen or not |
HTML_QuickForm_element::setValue() | Sets the value of the form element |
HTML_QuickForm_element::unfreeze() | Unfreezes the form element |
(optional)Input field name attribute
(optional)Input field label
(optional)Either a typical HTML attribute string or an associative array
HTML_Common
HTML_QuickForm_textarea
HTML_QuickForm_textarea Inherited Methods
Таблица 42-1. Inherited from HTML_QuickForm_element
Method Name | Summary |
---|---|
Constructor HTML_QuickForm_element::HTML_QuickForm_element() | Class constructor |
HTML_QuickForm_element::accept() | Accepts a renderer |
HTML_QuickForm_element::apiVersion() | Returns the current API version |
HTML_QuickForm_element::exportValue() | Returns a 'safe' element's value |
HTML_QuickForm_element::freeze() | Freeze the element so that only its value is returned |
HTML_QuickForm_element::getFrozenHtml() | Returns the value of field without HTML tags |
HTML_QuickForm_element::getLabel() | Returns display text for the element |
HTML_QuickForm_element::getName() | Returns the element name |
HTML_QuickForm_element::getType() | Returns element type |
HTML_QuickForm_element::getValue() | Returns the value of the form element |
HTML_QuickForm_element::isFrozen() | Returns whether or not the element is frozen |
HTML_QuickForm_element::onQuickFormEvent() | Called by HTML_QuickForm whenever form event is made on this element |
HTML_QuickForm_element::setLabel() | Sets display text for the element |
HTML_QuickForm_element::setName() | Sets the input field name |
HTML_QuickForm_element::setPersistantFreeze() | Sets wether an element value should be kept in an hidden field when the element is frozen or not |
HTML_QuickForm_element::setValue() | Sets the value of the form element |
HTML_QuickForm_element::unfreeze() | Unfreezes the form element |
Input field name attribute
Label(s) for a field
Either a typical HTML attribute string or an associative array
This class is named 'xbutton' since the name 'button' was already taken by class representing an <input type="button" /> HTML element. Available since HTML_QuickForm release 3.2.3
HTML_Common
HTML_QuickForm_xbutton
HTML_QuickForm_xbutton Inherited Methods
Таблица 42-1. Inherited from HTML_QuickForm_element
Method Name | Summary |
---|---|
Constructor HTML_QuickForm_element::HTML_QuickForm_element() | Class constructor |
HTML_QuickForm_element::accept() | Accepts a renderer |
HTML_QuickForm_element::apiVersion() | Returns the current API version |
HTML_QuickForm_element::exportValue() | Returns a 'safe' element's value |
HTML_QuickForm_element::freeze() | Freeze the element so that only its value is returned |
HTML_QuickForm_element::getFrozenHtml() | Returns the value of field without HTML tags |
HTML_QuickForm_element::getLabel() | Returns display text for the element |
HTML_QuickForm_element::getName() | Returns the element name |
HTML_QuickForm_element::getType() | Returns element type |
HTML_QuickForm_element::getValue() | Returns the value of the form element |
HTML_QuickForm_element::isFrozen() | Returns whether or not the element is frozen |
HTML_QuickForm_element::onQuickFormEvent() | Called by HTML_QuickForm whenever form event is made on this element |
HTML_QuickForm_element::setLabel() | Sets display text for the element |
HTML_QuickForm_element::setName() | Sets the input field name |
HTML_QuickForm_element::setPersistantFreeze() | Sets wether an element value should be kept in an hidden field when the element is frozen or not |
HTML_QuickForm_element::setValue() | Sets the value of the form element |
HTML_QuickForm_element::unfreeze() | Unfreezes the form element |
(optional) Button name
(optional) Button content (HTML to add between <button></button> tags)
(optional) Either a typical HTML attribute string or an associative array
HTML class for an advanced checkbox type field. Basically this fixes a problem that HTML has had where checkboxes can only pass a single value (the value of the checkbox when checked). A value for when the checkbox is not checked cannot be passed, and furthermore the checkbox variable doesn't even exist if the checkbox was submitted unchecked.
It works by creating a hidden field with the passed-in name and creating the checkbox with no name, but with a javascript onclick which sets the value of the hidden field.
HTML_Common
HTML_QuickForm_advcheckbox
HTML_QuickForm_advcheckbox Inherited Methods
Таблица 42-1. Inherited from HTML_QuickForm_checkbox
Method Name | Summary |
---|---|
Constructor HTML_QuickForm_checkbox::HTML_QuickForm_checkbox() | Class constructor |
HTML_QuickForm_checkbox::exportValue() | Return true if the checkbox is checked, null if it is not checked (getValue() returns false) |
HTML_QuickForm_checkbox::getChecked() | Returns whether a checkbox is checked |
HTML_QuickForm_checkbox::getFrozenHtml() | Returns the value of field without HTML tags |
HTML_QuickForm_checkbox::getText() | Returns the checkbox text |
HTML_QuickForm_checkbox::getValue() | Returns the value of the form element |
HTML_QuickForm_checkbox::onQuickFormEvent() | Called by HTML_QuickForm whenever form event is made on this element |
HTML_QuickForm_checkbox::setChecked() | Sets whether a checkbox is checked |
HTML_QuickForm_checkbox::setText() | Sets the checkbox text |
HTML_QuickForm_checkbox::setValue() | Sets the value of the form element |
Таблица 42-2. Inherited from HTML_QuickForm_input
Method Name | Summary |
---|---|
Constructor HTML_QuickForm_input::HTML_QuickForm_input() | Class constructor |
HTML_QuickForm_input::exportValue() | We don't need values from button-type elements (except submit) and files |
HTML_QuickForm_input::getName() | Returns the element name |
HTML_QuickForm_input::getValue() | Returns the value of the form element |
HTML_QuickForm_input::onQuickFormEvent() | Called by HTML_QuickForm whenever form event is made on this element |
HTML_QuickForm_input::setName() | Sets the input field name |
HTML_QuickForm_input::setType() | Sets the element type |
HTML_QuickForm_input::setValue() | Sets the value of the form element |
Таблица 42-3. Inherited from HTML_QuickForm_element
Method Name | Summary |
---|---|
Constructor HTML_QuickForm_element::HTML_QuickForm_element() | Class constructor |
HTML_QuickForm_element::accept() | Accepts a renderer |
HTML_QuickForm_element::apiVersion() | Returns the current API version |
HTML_QuickForm_element::exportValue() | Returns a 'safe' element's value |
HTML_QuickForm_element::freeze() | Freeze the element so that only its value is returned |
HTML_QuickForm_element::getFrozenHtml() | Returns the value of field without HTML tags |
HTML_QuickForm_element::getLabel() | Returns display text for the element |
HTML_QuickForm_element::getName() | Returns the element name |
HTML_QuickForm_element::getType() | Returns element type |
HTML_QuickForm_element::getValue() | Returns the value of the form element |
HTML_QuickForm_element::isFrozen() | Returns whether or not the element is frozen |
HTML_QuickForm_element::onQuickFormEvent() | Called by HTML_QuickForm whenever form event is made on this element |
HTML_QuickForm_element::setLabel() | Sets display text for the element |
HTML_QuickForm_element::setName() | Sets the input field name |
HTML_QuickForm_element::setPersistantFreeze() | Sets wether an element value should be kept in an hidden field when the element is frozen or not |
HTML_QuickForm_element::setValue() | Sets the value of the form element |
HTML_QuickForm_element::unfreeze() | Unfreezes the form element |
(optional)Input field name attribute
(optional)Input field label
(optional)Text to put after the checkbox
(optional)Either a typical HTML attribute string or an associative array
(optional)Values to pass if checked or not checked
If $values is a string then it will be used for checked state. If it is an array, then $values[0] will be used for unchecked state and $values[1] for checked.
The element looks like a normal HTML input text element that at every keypressed javascript event searches the array of options for a match and autocompletes the text in case of match. This is similar to the browsers' behaviour when one enters the URL into the Address field.
HTML_Common
HTML_QuickForm_text
HTML_QuickForm_autocomplete Inherited Methods
Таблица 42-1. Inherited from HTML_QuickForm_text
Method Name | Summary |
---|---|
HTML_QuickForm_text::HTML_QuickForm_text() | Class constructor |
HTML_QuickForm_text::setMaxLength() | Sets maxlength of text field |
HTML_QuickForm_text::setSize() | Sets size of text field |
Таблица 42-2. Inherited from HTML_QuickForm_input
Method Name | Summary |
---|---|
Constructor HTML_QuickForm_input::HTML_QuickForm_input() | Class constructor |
HTML_QuickForm_input::exportValue() | We don't need values from button-type elements (except submit) and files |
HTML_QuickForm_input::getName() | Returns the element name |
HTML_QuickForm_input::getValue() | Returns the value of the form element |
HTML_QuickForm_input::onQuickFormEvent() | Called by HTML_QuickForm whenever form event is made on this element |
HTML_QuickForm_input::setName() | Sets the input field name |
HTML_QuickForm_input::setType() | Sets the element type |
HTML_QuickForm_input::setValue() | Sets the value of the form element |
Таблица 42-3. Inherited from HTML_QuickForm_element
Method Name | Summary |
---|---|
Constructor HTML_QuickForm_element::HTML_QuickForm_element() | Class constructor |
HTML_QuickForm_element::accept() | Accepts a renderer |
HTML_QuickForm_element::apiVersion() | Returns the current API version |
HTML_QuickForm_element::exportValue() | Returns a 'safe' element's value |
HTML_QuickForm_element::freeze() | Freeze the element so that only its value is returned |
HTML_QuickForm_element::getFrozenHtml() | Returns the value of field without HTML tags |
HTML_QuickForm_element::getLabel() | Returns display text for the element |
HTML_QuickForm_element::getName() | Returns the element name |
HTML_QuickForm_element::getType() | Returns element type |
HTML_QuickForm_element::getValue() | Returns the value of the form element |
HTML_QuickForm_element::isFrozen() | Returns whether or not the element is frozen |
HTML_QuickForm_element::onQuickFormEvent() | Called by HTML_QuickForm whenever form event is made on this element |
HTML_QuickForm_element::setLabel() | Sets display text for the element |
HTML_QuickForm_element::setName() | Sets the input field name |
HTML_QuickForm_element::setPersistantFreeze() | Sets wether an element value should be kept in an hidden field when the element is frozen or not |
HTML_QuickForm_element::setValue() | Sets the value of the form element |
HTML_QuickForm_element::unfreeze() | Unfreezes the form element |
(optional)Input field name attribute
(optional)Input field label
Autocomplete options
(optional)Either a typical HTML attribute string or an associative array
The strings in this array will be checked by the javascript function for a match with the text being typed. In case of a match the text will be autocompleted.
HTML_Common
HTML_QuickForm_date
HTML_QuickForm_date Inherited Methods
Таблица 42-1. Inherited from HTML_QuickForm_group
Method Name | Summary |
---|---|
Constructor HTML_QuickForm_group::HTML_QuickForm_group() | Class constructor |
HTML_QuickForm_group::accept() | Accepts a renderer |
HTML_QuickForm_group::exportValue() | As usual, to get the group's value we access its elements and call |
HTML_QuickForm_group::getElementName() | Returns the element name inside the group such as found in the html form |
HTML_QuickForm_group::getElements() | Gets the grouped elements |
HTML_QuickForm_group::getFrozenHtml() | Returns the value of field without HTML tags |
HTML_QuickForm_group::getGroupType() | Gets the group type based on its elements Will return 'mixed' if elements contained in the group are of different types. |
HTML_QuickForm_group::getName() | Returns the group name |
HTML_QuickForm_group::getValue() | Returns the value of the group |
HTML_QuickForm_group::onQuickFormEvent() | Called by HTML_QuickForm whenever form event is made on this element |
HTML_QuickForm_group::setElements() | Sets the grouped elements |
HTML_QuickForm_group::setName() | Sets the group name |
HTML_QuickForm_group::setValue() | Sets values for group's elements |
Таблица 42-2. Inherited from HTML_QuickForm_element
Method Name | Summary |
---|---|
Constructor HTML_QuickForm_element::HTML_QuickForm_element() | Class constructor |
HTML_QuickForm_element::accept() | Accepts a renderer |
HTML_QuickForm_element::apiVersion() | Returns the current API version |
HTML_QuickForm_element::exportValue() | Returns a 'safe' element's value |
HTML_QuickForm_element::freeze() | Freeze the element so that only its value is returned |
HTML_QuickForm_element::getFrozenHtml() | Returns the value of field without HTML tags |
HTML_QuickForm_element::getLabel() | Returns display text for the element |
HTML_QuickForm_element::getName() | Returns the element name |
HTML_QuickForm_element::getType() | Returns element type |
HTML_QuickForm_element::getValue() | Returns the value of the form element |
HTML_QuickForm_element::isFrozen() | Returns whether or not the element is frozen |
HTML_QuickForm_element::onQuickFormEvent() | Called by HTML_QuickForm whenever form event is made on this element |
HTML_QuickForm_element::setLabel() | Sets display text for the element |
HTML_QuickForm_element::setName() | Sets the input field name |
HTML_QuickForm_element::setPersistantFreeze() | Sets wether an element value should be kept in an hidden field when the element is frozen or not |
HTML_QuickForm_element::setValue() | Sets the value of the form element |
HTML_QuickForm_element::unfreeze() | Unfreezes the form element |
The $options parameter controls the element's appearance. It is an associative array of the form 'option name' => 'option value'.
Recognised option names
Language code to use for display. Default is 'en'.
date element supports many languages. If your one is not supported, send us the translation, we'll gladly include it.
Format string for the date, based on PHP's date() function. The following characters are recognised:
D => Short names of days l => Long names of days d => Day numbers M => Short names of months F => Long names of months m => Month numbers Y => Four digit year y => Two digit year h => 12 hour format H => 23 hour format i => Minutes s => Seconds a => am/pm A => AM/PM g => 12 hour format w/o leading zeroes W => week of the year |
Minimum year in year select. Default is 2001.
Maximum year in year select. Default is 2010.
On 'minYear' and 'maxYear': When 'minYear' > 'maxYear' the years in the select will be displayed in descending order.
Should an empty option be added to the top of each select box? Default is FALSE. This may be set for individual fields also, if one passes an array of the form array('format char' => TRUE, ..., 'another format char' => FALSE)
The value passed by the empty option. Default is ''.
The text displayed for the empty option. Default is ' '. This may be set for individual fields also, if one passes an array of the form array('format char' => 'some text', ..., 'another format char' => 'some other text')
Step to increase the option values by. Works for 'i' and 's' formats currently. Default is array('i' => 1, 's' => 1).
Element's name
Label(s) for an element
Options to control the element's display
Either a typical HTML attribute string or an associative array
This element is used for adding headers to the form. Unlike usual static elements, the headers are usually rendered using a special template.
HTML_Common
HTML_QuickForm_header
HTML_QuickForm_header Inherited Methods
Таблица 42-1. Inherited from HTML_QuickForm_static
Method Name | Summary |
---|---|
Constructor HTML_QuickForm_static::HTML_QuickForm_static() | Class constructor |
HTML_QuickForm_static::exportValue() | We override this here because we don't want any values from static elements |
HTML_QuickForm_static::getFrozenHtml() | Returns the value of field without HTML tags |
HTML_QuickForm_static::getName() | Returns the element name |
HTML_QuickForm_static::onQuickFormEvent() | Called by HTML_QuickForm whenever form event is made on this element |
HTML_QuickForm_static::setName() | Sets the element name |
HTML_QuickForm_static::setText() | Sets the text |
HTML_QuickForm_static::setValue() | Sets the text (uses the standard setValue call to emulate a form element. |
Таблица 42-2. Inherited from HTML_QuickForm_element
Method Name | Summary |
---|---|
Constructor HTML_QuickForm_element::HTML_QuickForm_element() | Class constructor |
HTML_QuickForm_element::accept() | Accepts a renderer |
HTML_QuickForm_element::apiVersion() | Returns the current API version |
HTML_QuickForm_element::exportValue() | Returns a 'safe' element's value |
HTML_QuickForm_element::freeze() | Freeze the element so that only its value is returned |
HTML_QuickForm_element::getFrozenHtml() | Returns the value of field without HTML tags |
HTML_QuickForm_element::getLabel() | Returns display text for the element |
HTML_QuickForm_element::getName() | Returns the element name |
HTML_QuickForm_element::getType() | Returns element type |
HTML_QuickForm_element::getValue() | Returns the value of the form element |
HTML_QuickForm_element::isFrozen() | Returns whether or not the element is frozen |
HTML_QuickForm_element::onQuickFormEvent() | Called by HTML_QuickForm whenever form event is made on this element |
HTML_QuickForm_element::setLabel() | Sets display text for the element |
HTML_QuickForm_element::setName() | Sets the input field name |
HTML_QuickForm_element::setPersistantFreeze() | Sets wether an element value should be kept in an hidden field when the element is frozen or not |
HTML_QuickForm_element::setValue() | Sets the value of the form element |
HTML_QuickForm_element::unfreeze() | Unfreezes the form element |
This class takes the same arguments as a select element, but instead of creating a <select> it creates hidden elements for all values already selected with setDefaults() or setConstants(). This is useful if you have a select ring that you don't want visible, but you need all selected values to be passed.
HTML_Common
HTML_QuickForm_hiddenselect
HTML_QuickForm_hiddenselect Inherited Methods
Таблица 42-1. Inherited from HTML_QuickForm_select
Method Name | Summary |
---|---|
Constructor HTML_QuickForm_select::HTML_QuickForm_select() | Class constructor |
HTML_QuickForm_select::addOption() | Adds a new OPTION to the SELECT |
HTML_QuickForm_select::apiVersion() | Returns the current API version |
HTML_QuickForm_select::exportValue() | We check the options and return only the values that _could_ have been |
HTML_QuickForm_select::getFrozenHtml() | Returns the value of field without HTML tags |
HTML_QuickForm_select::getMultiple() | Returns the select mutiple attribute |
HTML_QuickForm_select::getName() | Returns the element name |
HTML_QuickForm_select::getPrivateName() | Returns the element name (possibly with brackets appended) |
HTML_QuickForm_select::getSelected() | Returns an array of the selected values |
HTML_QuickForm_select::getSize() | Returns the select field size |
HTML_QuickForm_select::getValue() | Returns an array of the selected values |
HTML_QuickForm_select::load() | Loads options from different types of data sources |
HTML_QuickForm_select::loadArray() | Loads the options from an associative array |
HTML_QuickForm_select::loadDbResult() | Loads the options from DB_result object |
HTML_QuickForm_select::loadQuery() | Queries a database and loads the options from the results |
HTML_QuickForm_select::setMultiple() | Sets the select mutiple attribute |
HTML_QuickForm_select::setName() | Sets the input field name |
HTML_QuickForm_select::setSelected() | Sets the default values of the select box |
HTML_QuickForm_select::setSize() | Sets the select field size, only applies to 'multiple' selects |
HTML_QuickForm_select::setValue() | Sets the value of the form element |
Таблица 42-2. Inherited from HTML_QuickForm_element
Method Name | Summary |
---|---|
Constructor HTML_QuickForm_element::HTML_QuickForm_element() | Class constructor |
HTML_QuickForm_element::accept() | Accepts a renderer |
HTML_QuickForm_element::apiVersion() | Returns the current API version |
HTML_QuickForm_element::exportValue() | Returns a 'safe' element's value |
HTML_QuickForm_element::freeze() | Freeze the element so that only its value is returned |
HTML_QuickForm_element::getFrozenHtml() | Returns the value of field without HTML tags |
HTML_QuickForm_element::getLabel() | Returns display text for the element |
HTML_QuickForm_element::getName() | Returns the element name |
HTML_QuickForm_element::getType() | Returns element type |
HTML_QuickForm_element::getValue() | Returns the value of the form element |
HTML_QuickForm_element::isFrozen() | Returns whether or not the element is frozen |
HTML_QuickForm_element::onQuickFormEvent() | Called by HTML_QuickForm whenever form event is made on this element |
HTML_QuickForm_element::setLabel() | Sets display text for the element |
HTML_QuickForm_element::setName() | Sets the input field name |
HTML_QuickForm_element::setPersistantFreeze() | Sets wether an element value should be kept in an hidden field when the element is frozen or not |
HTML_QuickForm_element::setValue() | Sets the value of the form element |
HTML_QuickForm_element::unfreeze() | Unfreezes the form element |
Select name attribute
Label(s) for the select (not used)
Data to be used to populate options
Either a typical HTML attribute string or an associative array (not used)
Class to dynamically create "chained" HTML Select elements. Choosing an option in the first <select> changes the content of the second select and so on.
This element is considered as a group. Selects will be named groupName[0], groupName[1], ...
Пример 42-1. Creating a hierselect element based on values from a database table
|
Пример 42-2. Creating a hierselect element with three select elements
|
HTML_Common
HTML_QuickForm_hierselect
HTML_QuickForm_hierselect Inherited Methods
Таблица 42-1. Inherited from HTML_QuickForm_group
Method Name | Summary |
---|---|
Constructor HTML_QuickForm_group::HTML_QuickForm_group() | Class constructor |
HTML_QuickForm_group::accept() | Accepts a renderer |
HTML_QuickForm_group::exportValue() | As usual, to get the group's value we access its elements and call |
HTML_QuickForm_group::getElementName() | Returns the element name inside the group such as found in the html form |
HTML_QuickForm_group::getElements() | Gets the grouped elements |
HTML_QuickForm_group::getFrozenHtml() | Returns the value of field without HTML tags |
HTML_QuickForm_group::getGroupType() | Gets the group type based on its elements Will return 'mixed' if elements contained in the group are of different types. |
HTML_QuickForm_group::getName() | Returns the group name |
HTML_QuickForm_group::getValue() | Returns the value of the group |
HTML_QuickForm_group::onQuickFormEvent() | Called by HTML_QuickForm whenever form event is made on this element |
HTML_QuickForm_group::setElements() | Sets the grouped elements |
HTML_QuickForm_group::setName() | Sets the group name |
HTML_QuickForm_group::setValue() | Sets values for group's elements |
Таблица 42-2. Inherited from HTML_QuickForm_element
Method Name | Summary |
---|---|
Constructor HTML_QuickForm_element::HTML_QuickForm_element() | Class constructor |
HTML_QuickForm_element::accept() | Accepts a renderer |
HTML_QuickForm_element::apiVersion() | Returns the current API version |
HTML_QuickForm_element::exportValue() | Returns a 'safe' element's value |
HTML_QuickForm_element::freeze() | Freeze the element so that only its value is returned |
HTML_QuickForm_element::getFrozenHtml() | Returns the value of field without HTML tags |
HTML_QuickForm_element::getLabel() | Returns display text for the element |
HTML_QuickForm_element::getName() | Returns the element name |
HTML_QuickForm_element::getType() | Returns element type |
HTML_QuickForm_element::getValue() | Returns the value of the form element |
HTML_QuickForm_element::isFrozen() | Returns whether or not the element is frozen |
HTML_QuickForm_element::onQuickFormEvent() | Called by HTML_QuickForm whenever form event is made on this element |
HTML_QuickForm_element::setLabel() | Sets display text for the element |
HTML_QuickForm_element::setName() | Sets the input field name |
HTML_QuickForm_element::setPersistantFreeze() | Sets wether an element value should be kept in an hidden field when the element is frozen or not |
HTML_QuickForm_element::setValue() | Sets the value of the form element |
HTML_QuickForm_element::unfreeze() | Unfreezes the form element |
(optional)Input field name attribute
Замечание: If you are displaying several forms on one page, then hierselects in these forms should have unique names. In the other case the values for last hierselect with the same name will overwrite the values for the previous one. It is extremely difficult to cleanly fix this behaviour with current QuickForm architecture, therefore please rely on this workaround. See Request #5718.
(optional)Input field label in form
(optional)Either a typical HTML attribute string or an associative array.
String to separate the grouped elements
Sets the options for the select elements within hierselect. Note that the actual number of selects that will be displayed is governed by the number of the elements in the array passed to this function.
Array of options for the elements, having the following structure:
array( // options for the first element array( 'key_1' => 'value 1', 'key_2' => 'value 2', ... 'key_N' => 'value N', ), // options for the second element array( 'key_1' => array( 'key_1_1' => 'value 1.1', 'key_1_2' => 'value 1.2', ... 'key_1_M1' => 'value 1.M1' ), 'key_2' => array( 'key_2_1' => 'value 2.1', 'key_2_2' => 'value 2.2', ... 'key_2_M2' => 'value 2.M2' ), ... 'key_N' => array( 'key_N_1' => 'value N.1', 'key_N_2' => 'value N.2', ... 'key_N_MN' => 'value N.MN' ) ) // options for further elements ... ) |
Замечание: The options for subsequent elements should have keys for all options of the previous elements. Having a select without options is invalid HTML and will break hierselect's JavaScript. See also Bug #5218.
Пример 42-1. Setting the hierselect options
|
Format is standard key/value pairs for select elements. Example is available in the docs for setSecOptions().
This method has been deprecated. Use setOptions() instead.
Эта функция не должна вызываться статически.
Внимание |
Эта функция объявлена как deprecated. Это означает, что в будущих версиях пакета она может больше не поддерживаться. |
Deprecated in release 3.2.2
Sets the options for the secondary select. Options are passed as a two-dimensional array, where the first key is parent id and the second key is child id, as it is needed to know the parent option to which the secondary option relates.
This method has been deprecated. Use setOptions() instead.
Эта функция не должна вызываться статически.
Внимание |
Эта функция объявлена как deprecated. Это означает, что в будущих версиях пакета она может больше не поддерживаться. |
Deprecated in release 3.2.2
Пример 42-1. Setting the hierselect options
|
A pseudo-element used for adding raw HTML to form output. Its contents are output as is, without applying any element template.
Внимание |
This element is deprecated. No fixes and changes to its behaviour will be done and it will be removed in the next major version of the package. If you really need to add raw html to the form, you may consider using 'static' element instead. |
Внимание |
The element can be used with the Default Renderer only, all other Renderers completely ignore this. Consider using some template-based renderer instead of relying on this feature. |
HTML_Common
HTML_QuickForm_html
HTML_QuickForm_html Inherited Methods
Таблица 42-1. Inherited from HTML_QuickForm_static
Method Name | Summary |
---|---|
Constructor HTML_QuickForm_static::HTML_QuickForm_static() | Class constructor |
HTML_QuickForm_static::exportValue() | We override this here because we don't want any values from static elements |
HTML_QuickForm_static::getFrozenHtml() | Returns the value of field without HTML tags |
HTML_QuickForm_static::getName() | Returns the element name |
HTML_QuickForm_static::onQuickFormEvent() | Called by HTML_QuickForm whenever form event is made on this element |
HTML_QuickForm_static::setName() | Sets the element name |
HTML_QuickForm_static::setText() | Sets the text |
HTML_QuickForm_static::setValue() | Sets the text (uses the standard setValue call to emulate a form element. |
Таблица 42-2. Inherited from HTML_QuickForm_element
Method Name | Summary |
---|---|
Constructor HTML_QuickForm_element::HTML_QuickForm_element() | Class constructor |
HTML_QuickForm_element::accept() | Accepts a renderer |
HTML_QuickForm_element::apiVersion() | Returns the current API version |
HTML_QuickForm_element::exportValue() | Returns a 'safe' element's value |
HTML_QuickForm_element::freeze() | Freeze the element so that only its value is returned |
HTML_QuickForm_element::getFrozenHtml() | Returns the value of field without HTML tags |
HTML_QuickForm_element::getLabel() | Returns display text for the element |
HTML_QuickForm_element::getName() | Returns the element name |
HTML_QuickForm_element::getType() | Returns element type |
HTML_QuickForm_element::getValue() | Returns the value of the form element |
HTML_QuickForm_element::isFrozen() | Returns whether or not the element is frozen |
HTML_QuickForm_element::onQuickFormEvent() | Called by HTML_QuickForm whenever form event is made on this element |
HTML_QuickForm_element::setLabel() | Sets display text for the element |
HTML_QuickForm_element::setName() | Sets the input field name |
HTML_QuickForm_element::setPersistantFreeze() | Sets wether an element value should be kept in an hidden field when the element is frozen or not |
HTML_QuickForm_element::setValue() | Sets the value of the form element |
HTML_QuickForm_element::unfreeze() | Unfreezes the form element |
HTML_Common
HTML_QuickForm_link
HTML_QuickForm_link Inherited Methods
Таблица 42-1. Inherited from HTML_QuickForm_static
Method Name | Summary |
---|---|
Constructor HTML_QuickForm_static::HTML_QuickForm_static() | Class constructor |
HTML_QuickForm_static::exportValue() | We override this here because we don't want any values from static elements |
HTML_QuickForm_static::getFrozenHtml() | Returns the value of field without HTML tags |
HTML_QuickForm_static::getName() | Returns the element name |
HTML_QuickForm_static::onQuickFormEvent() | Called by HTML_QuickForm whenever form event is made on this element |
HTML_QuickForm_static::setName() | Sets the element name |
HTML_QuickForm_static::setText() | Sets the text |
HTML_QuickForm_static::setValue() | Sets the text (uses the standard setValue call to emulate a form element. |
Таблица 42-2. Inherited from HTML_QuickForm_element
Method Name | Summary |
---|---|
Constructor HTML_QuickForm_element::HTML_QuickForm_element() | Class constructor |
HTML_QuickForm_element::accept() | Accepts a renderer |
HTML_QuickForm_element::apiVersion() | Returns the current API version |
HTML_QuickForm_element::exportValue() | Returns a 'safe' element's value |
HTML_QuickForm_element::freeze() | Freeze the element so that only its value is returned |
HTML_QuickForm_element::getFrozenHtml() | Returns the value of field without HTML tags |
HTML_QuickForm_element::getLabel() | Returns display text for the element |
HTML_QuickForm_element::getName() | Returns the element name |
HTML_QuickForm_element::getType() | Returns element type |
HTML_QuickForm_element::getValue() | Returns the value of the form element |
HTML_QuickForm_element::isFrozen() | Returns whether or not the element is frozen |
HTML_QuickForm_element::onQuickFormEvent() | Called by HTML_QuickForm whenever form event is made on this element |
HTML_QuickForm_element::setLabel() | Sets display text for the element |
HTML_QuickForm_element::setName() | Sets the input field name |
HTML_QuickForm_element::setPersistantFreeze() | Sets wether an element value should be kept in an hidden field when the element is frozen or not |
HTML_QuickForm_element::setValue() | Sets the value of the form element |
HTML_QuickForm_element::unfreeze() | Unfreezes the form element |
(optional)Link label
(optional)Link href
(optional)Link display text
(optional)Either a typical HTML attribute string or an associative array
A static element is an element that cannot have a submit value and thus cannot change due to user input. Such elements are usually used to improve form presentation. Note that elements of HTML_QuickForm_static type are by default rendered inside the same template as the normal form elements.
HTML_Common
HTML_QuickForm_static
Таблица 42-1. Classes that extend HTML_QuickForm_static
Class | Summary |
---|---|
HTML_QuickForm_header | A pseudo-element used for adding headers to form |
HTML_QuickForm_html | A pseudo-element used for adding raw HTML to form |
HTML_QuickForm_link | HTML class for a link type field |
HTML_QuickForm_static Inherited Methods
Таблица 42-2. Inherited from HTML_QuickForm_element
Method Name | Summary |
---|---|
Constructor HTML_QuickForm_element::HTML_QuickForm_element() | Class constructor |
HTML_QuickForm_element::accept() | Accepts a renderer |
HTML_QuickForm_element::apiVersion() | Returns the current API version |
HTML_QuickForm_element::exportValue() | Returns a 'safe' element's value |
HTML_QuickForm_element::freeze() | Freeze the element so that only its value is returned |
HTML_QuickForm_element::getFrozenHtml() | Returns the value of field without HTML tags |
HTML_QuickForm_element::getLabel() | Returns display text for the element |
HTML_QuickForm_element::getName() | Returns the element name |
HTML_QuickForm_element::getType() | Returns element type |
HTML_QuickForm_element::getValue() | Returns the value of the form element |
HTML_QuickForm_element::isFrozen() | Returns whether or not the element is frozen |
HTML_QuickForm_element::onQuickFormEvent() | Called by HTML_QuickForm whenever form event is made on this element |
HTML_QuickForm_element::setLabel() | Sets display text for the element |
HTML_QuickForm_element::setName() | Sets the input field name |
HTML_QuickForm_element::setPersistantFreeze() | Sets wether an element value should be kept in an hidden field when the element is frozen or not |
HTML_QuickForm_element::setValue() | Sets the value of the form element |
HTML_QuickForm_element::unfreeze() | Unfreezes the form element |
Name of the element
(optional)Label
(optional)Display text
To be written.
array of elements composing the group
(optional) group name
(optional) group label
(optional) string or array of strings to separate elements
(optional) specify whether the group name should be used in the form element name: groupName[elementName] vs elementName
Таблица 42-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
QUICKFORM_INVALID_ELEMENT_NAME | Element '$elementName' already exists in HTML_QuickForm::addElement() | Tried to add a group having a name of an existing element | Choose a different name for a group |
Пример 42-1. Using addGroup()
|
Groups allow you to combine several individual elements into one entity and to use it as usual form element. Most of the group's methods use the methods of the grouped elements to do their job. For example, groups do not have values themselves, their setValue() and getValue() methods just call the appropriate methods of grouped elements to set and get their values.
Groups can be used both for visual grouping of the elements (e.g. putting "Submit" and "Reset" buttons on one line), grouping of the elements with the same name (e.g. groups of checkboxes and radiobuttons) and logical grouping of the elements (e.g. group for person's name consisting of two text fields for first and last name).
HTML_Common
HTML_QuickForm_group
Таблица 42-1. Classes that extend HTML_QuickForm_group
Class | Summary |
---|---|
HTML_QuickForm_date | Class for a group of elements used to input dates (and times). |
HTML_QuickForm_hierselect | Class to dynamically create two HTML Select elements The first select changes the content of the second select. |
HTML_QuickForm_group Inherited Methods
Таблица 42-2. Inherited from HTML_QuickForm_element
Method Name | Summary |
---|---|
Constructor HTML_QuickForm_element::HTML_QuickForm_element() | Class constructor |
HTML_QuickForm_element::accept() | Accepts a renderer |
HTML_QuickForm_element::apiVersion() | Returns the current API version |
HTML_QuickForm_element::exportValue() | Returns a 'safe' element's value |
HTML_QuickForm_element::freeze() | Freeze the element so that only its value is returned |
HTML_QuickForm_element::getFrozenHtml() | Returns the value of field without HTML tags |
HTML_QuickForm_element::getLabel() | Returns display text for the element |
HTML_QuickForm_element::getName() | Returns the element name |
HTML_QuickForm_element::getType() | Returns element type |
HTML_QuickForm_element::getValue() | Returns the value of the form element |
HTML_QuickForm_element::isFrozen() | Returns whether or not the element is frozen |
HTML_QuickForm_element::onQuickFormEvent() | Called by HTML_QuickForm whenever form event is made on this element |
HTML_QuickForm_element::setLabel() | Sets display text for the element |
HTML_QuickForm_element::setName() | Sets the input field name |
HTML_QuickForm_element::setPersistantFreeze() | Sets wether an element value should be kept in an hidden field when the element is frozen or not |
HTML_QuickForm_element::setValue() | Sets the value of the form element |
HTML_QuickForm_element::unfreeze() | Unfreezes the form element |
(optional)Group name
(optional)Group label
(optional)Group elements
(optional)Use a string for one separator, use an array to alternate the separators.
(optional)whether to change elements' names to the form $groupName[$elementName] or leave them as is.
Returns the name of an element inside the group. This is the name that will be shown in the form HTML output.
This section covers the methods QuickForm offers for managing form element's values and working with submitted values.
Sets constant form values. These values won't be overridden by either default (set via setDefaults()) or submitted (POST or GET) values.
values used to fill the form, array('element name' => 'element value')
(optional) filter(s) to apply to all default values
Таблица 42-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
QUICKFORM_INVALID_FILTER | Callback function does not exist in QuickForm::setConstants() | Tried to pass a name of a non-existant function as a callback | Check spelling |
Sets default form values. There are overriden by either constant (set via setConstants()) or submitted (POST or GET) values.
values used to fill the form, array('element name' => 'element value')
(optional) filter(s) to apply to all default values
Таблица 42-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
QUICKFORM_INVALID_FILTER | Callback function does not exist in QuickForm::setDefaults() | Tried to pass a name of a non-existant function as a callback | Check spelling |
Tells whether the form was already submitted. Using this method when $trackSubmit parameter of QuickForm's constructor is used is more reliable than checking whether form's submit values are empty.
This method first tries to find a cleaned-up submitted value, it will return a value set by setValue()/setDefaults()/setConstants() if submitted value does not exist for the given element.
The value that couldn't have possibly been submitted (e.g.: an option that is not present in <select> element's option list) is not considered valid and is not returned.
As the values returned by this method and by exportValues() are expected to be immediately processed and/or stored somewhere, values for file elements that obviously have special processing needs are not returned.
Таблица 42-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
QUICKFORM_NONEXIST_ELEMENT | Element '$element' does not exist in HTML_QuickForm::exportValue() | Tried to get a value of a non-existant element | Check the element's name spelling |
Returns the values for the form elements. First it tries to return filtered submitted values, if there were none then it takes the values set by setDefaults() or setConstants().
Unlike getSubmitValues(), this will return only the values corresponding to the elements added to the form and only the values that could actually be submitted: if we have 'Yes'/'No' radiobuttons 'Maybe' will not be considered a valid submit value. You also cannot get values for file elements via this method.
Array/string of element names, whose values we want. If not set then return all elements.
Таблица 42-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
QUICKFORM_NONEXIST_ELEMENT | Element '$element' does not exist in HTML_QuickForm::exportValue() | Tried to get a value of a non-existant element | Check the element's name spelling |
Returns the element's raw value such as submitted by the form (not filtered), set by setDefaults() or setConstants().
Таблица 42-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
QUICKFORM_NONEXIST_ELEMENT | Element '$element' does not exist in HTML_QuickForm::getElementValue() | Tried to get a value of a non-existant element | Check the element's name spelling |
Performs the form data processing. It actually calls the $callback passing the submitted values (and files, when $mergeFiles=TRUE) to it.
Callback, either function name or array(&$object, 'method')
Whether uploaded files should be processed too
Таблица 42-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
QUICKFORM_INVALID_PROCESS | Callback function does not exist in QuickForm::process() | Tried to pass a name of a non-existant function as a callback | Check spelling |
QuickForm also provides validation rules support. You can code your own validation rules, register them in QuickForm and then call them in your script. By default, QuickForm can handle validation against regular expressions (preg_match style) and check for required elements. If you want client-side validation, QuickForm can generate the javascript code needed. Server-side validation is always on by default.
QuickForm can also make use of filters for data import into the form or for data processing once the form has been submitted. Filters work the same way as rules except that you don't need to register them. You write your filter functions and call them in your script. You can call any php function (ie. trim, addslashes, htmlentities, etc.) and have them applied recursively to your element values.
QuickForm makes client-side and server-side form validation easy. It allows for validation against regular expressions or custom functions and methods. You can define your own validation rules and apply them to the elements or groups you want. In this section, we will explore the different possibilities QuickForm offers to make validation easier.
QuickForm can verify if required elements are filled when the form is submitted. This works with every type of elements or groups, integer 0 is not considered as an empty value.
require_once 'HTML/QuickForm.php'; $form = new HTML_QuickForm('myform', 'post'); $form->addElement('text', 'email', 'Your email:'); $form->addElement('submit', 'submit', 'Submit'); // Validation rules $form->addRule('email', 'E-Mail is required', 'required'); // Validation if ($form->validate()) { $form->freeze(); } $form->display(); |
On empty elements validation: If the element is empty, no validation rules other than required are checked for it. This means that empty element can be invalid only when it is required.
On required uploads: required rule does not work for file elements. Use uploadedfile.
The HTML_QuickForm::validate() method will scan through each rules in the order they have been set. If a rule is not validated, the error message corresponding to the element will be displayed and the form will be shown once again. You can use templates to set the position of this error message. The order you decide to set your validation rules is important because it will determine which error message is used.
QuickForm can generate the javascript necessary to validate the form on the client side. This feature works for all standard elements and for groups. Server side validation is always performed in case the client has javascript turned off.
$form->addRule('email', 'E-Mail is required', 'required', null, 'client'); |
Подсказка: By setting the parameter 'client', you trigger the javascript automatic generation.
QuickForm offers a few registered rules that are often used when validating forms. Some of the rules may need an extra $format parameter passed to addRule() / addGroupRule() to work properly.
Таблица 42-1. List of built-in validation rules
Name | Description | $format parameter |
---|---|---|
required | value is not empty | |
maxlength | value must not exceed given number of characters | number of characters, integer |
minlength | value must have more than given number of characters | number of characters, integer |
rangelength | value must have between min and max characters | array(min characters, max characters) |
regex | value must pass the regular expression | regular expression to check, string |
value is a correctly formatted email | whether to perform an additional domain check via checkdnsrr() function, boolean | |
lettersonly | value must contain only letters | |
alphanumeric | value must contain only letters and numbers | |
numeric | value must be a number | |
nopunctuation | value must not contain punctuation characters | |
nonzero | value must be a number not starting with 0 | |
compare | The rule allows to compare the values of two form fields. This can be used for e.g. 'Password repeat must match password' kind of rule. Please note that you need to pass an array of elements' names to compare as a first parameter to addRule(). | Type of comparison to perform, string:
|
callback | This rule allows to use an external function/method for validation. This can be done either explicitly, by passing a callback as a format parameter or implicitly, by registering it via registerRule(). | Function/method to use, callback. |
Validation rules for file uploads | ||
uploadedfile | required file upload | |
maxfilesize | the file size must not exceed the given number of bytes | maximum file size, integer |
mimetype | the file must have a correct MIME type | either a string for single allowed MIME type, or an array of allowed MIME types |
filename | the filename must match the given regex | regular expression to test, string |
On rules for file uploads: These rules are defined in HTML/QuickForm/file.php, and are automatically registered when a file type element is added to the form. These rules are server-side only, for obvious reasons.
Usage of builtin rules is covered in rules-builtin.php example provided with the package. The rules-custom.php example covers the usage of custom rule classes and callback type rules. It also contains a NumericRange class for checking whether a number is between a maximum and a minimum.
Since release 3.2 all builtin validation is performed by subclasses of HTML_QuickForm_Rule class. You can create your own subclass of it and implement validate() and getValidationScript() methods. Consult the source for the examples.
When you need a more complex validation, QuickForm can use your own custom-made functions to validate an element or a group. QuickForm can also call a method of a class. This way, it is possible to use PEAR's Validate package or any other class. If you want to use your own functions, you basically have two options:
Register the function via registerRule() using 'callback' as $type and giving the new rule a custom $ruleName. Later you add the rule with this name via addRule() like any buitin rule.
Add the rule of callback type via addRule() passing the name of your function as $format. This way you'll have less characters to type, but will be unable to pass additional data to your function.
Пример 42-1. Email validation function
|
You can pass an extra parameter of the type you want to your function when set with HTML_QuickForm::addRule(). Here we used TRUE to enable the DNS check of our function.
If you use a method, you must specify the class your method is in. Use this syntax when you register your rule:
// Method checkEmail is in class Validate $form->registerRule('checkmail', 'callback', 'checkEmail', 'Validate'); |
Подсказка: You can also use a javascript function to validate your form, give it the same name as your PHP function, have it return a boolean and set the 'client' parameter.
Groups of elements can be validated the same way other elements are, or use a more complex validation scheme. To validate a group as a whole, just use HTML_QuickForm::addRule(). The group elements' values will be passed to the validation function as an array.
You can have more complex validation for your groups using the HTML_QuickForm::addGroupRule() method. This allows for a per element validation. It also makes it possible to specify the number of elements that need to be valid for the group to be valid too.
Пример 42-2. Complex group validation
|
In this example, we have set rules for the elements inside our group. Instead of using their names, we could have used their index (determined by the order they were created) in the group, it would speed up the validation process.
The following example takes the same group and will validate the form only if at least one of our two elements is not empty. To achieve this, we use the howmany parameter and set it to 1.
$form->addGroupRule('id', 'Fill at least one element', 'required', null, 1); |
You have seen that QuickForm makes it easy to validate your elements and groups without having to write all the usually necessary code to find the different values. It takes care of required elements, generates the javascript automatically and adds a lot of flexibility by allowing you to use your own validation functions and regular expressions. It's time to experiment...
If we add a rule like
$form->addRule('element', 'The element is required', 'required'); |
Of course this can be fixed by making a custom regex rule, but there is an easier solution. We usually do not care about leading and trailing spaces at all, and we can make the element's value pass through builtin trim() function before doing any validation on it:
$form->applyFilter('element', 'trim'); |
Filters are applied recursively, which means that trim() on an array will work, too. You can pass any valid callback as an argument to applyFilter() method.
Use filters if you want to 'sanitize' user input and do not really care about invalid values.
If the element is in fact a group, it will be considered as a whole, an array of group elements' values will be passed to validation function. To validate grouped elements as separate entities, use addGroupRule().
Form element name(s). Currently the only builtin rule that expects and correctly handles an array here is compare:
$form->addElement('password', 'cmpPasswd', 'Password:'); $form->addElement('password', 'cmpRepeat', 'Repeat password:'); $form->addRule(array('cmpPasswd', 'cmpRepeat'), 'The passwords do not match', 'compare', null, 'client'); |
Message to display for invalid data
Rule type, use getRegisteredRules() to get types. You can also pass a classname for a descendant of HTML_QuickForm_Rule or an instance of such class.
(optional) Required for extra rule data
(optional) Where to perform validation: "server", "client"
For client-side validation: reset the form element to it's original value if there is an error?
Force the rule to be applied, even if the target form element does not exist
Таблица 42-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
QUICKFORM_NONEXIST_ELEMENT | Element '$element' does not exist in HTML_QuickForm::addRule() | Tried to add a rule for a non-existant element | Check the element's name spelling or use $force to suppress the error. |
QUICKFORM_INVALID_RULE | Rule '$type' is not registered in HTML_QuickForm::addRule() | Rule is not known to QuickForm | Check rule type spelling or use HTML_QuickForm::registerRule(). |
Adds a validation rule for the given group of elements
Only groups with a name can be assigned a validation rule. Use addGroupRule() when you need to validate elements inside the group. Also use addRule() if you need to validate the group as a whole.
Form group name
Array for multiple elements or error message string for one element. If this is the array, its structure is the following:
array ( 'element name or index' => array( array(rule data), ... array(rule data) ), ... 'element name or index' => array( array(rule data), ... array(rule data) ) ) |
Замечание: If this parameter is an array, all the subsequent parameters are ignored. You should pass all the modifiers for the rules being added within this array (see the example below).
(optional) Rule type. Use getRegisteredRules() to get types. You can also pass a classname for a descendant of HTML_QuickForm_Rule or an instance of such class.
(optional) Required for extra rule data
(optional) How many valid elements should be in the group
(optional)Where to perform validation: "server", "client"
Client-side: whether to reset the element's value to its original state if validation failed.
Таблица 42-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
QUICKFORM_NONEXIST_ELEMENT | Group '$group' does not exist in HTML_QuickForm::addGroupRule() | Tried to add a rule for a non-existant group | Check the group name spelling |
QUICKFORM_NONEXIST_ELEMENT | Element '$elementIndex' not found in group '$group' in HTML_QuickForm::addGroupRule() | $arg1 is an array and contains an index for an element not present in a group | Check the element index spelling |
QUICKFORM_INVALID_RULE | Rule '$type' is not registered in HTML_QuickForm::addGroupRule() | Rule is not known to QuickForm | Check rule type spelling or use HTML_QuickForm::registerRule(). |
Пример 42-1. Using addGroupRule()
|
This should be used when you want to add a rule involving several fields or if you want to use some completely custom validation for your form. The rule function/method should return TRUE in case of successful validation and array('element name' => 'error') when there were errors.
Таблица 42-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
QUICKFORM_INVALID_RULE | Callback function does not exist in HTML_QuickForm::addFormRule() | Tried to pass a name of a non-existant function as a callback | Check spelling |
Пример 42-1. Using addFormRule()
|
Returns whether or not the form element is required, i.e. whether a 'required' rule was added for it.
Returns error corresponding to validated element. Errors are usually assigned to elements by validate() method.
Set error message for a form element. Errors are usually assigned to elements by validate() method. Use this if you need to explicitly set error message for an element.
Name of validation rule
Either: 'regex' or 'callback' ('function' is also kept for backward compatibility). If registering a subclass of HTML_QuickForm_Rule you can pass anything here, preferrably NULL or empty string.
Name of function, regular expression, classname of HTML_QuickForm_Rule subclass or an instance of such class.
Object parent of above function, name of the file containing the subclass of HTML_QuickForm_Rule.
Returns whether or not the given rule is supported. New rules are registered via registerRule() method.
Form element name or array of such names. Special name '__ALL__' means all the form elements.
Callback, either function name or array(&$object, 'method')
Таблица 42-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
QUICKFORM_INVALID_FILTER | Callback function does not exist in QuickForm::applyFilter() | Tried to pass a name of a non-existant function as a callback | Check spelling |
Your form can be customised in many ways. QuickForm can use different kind of renderers and provides a default one which allows for customization of the form, the elements, the error messages, the headers, the required elements note and the required elements sign. You can also write your own renderers.
array or string of element(s) to be frozen. If NULL then all the form's elements will be frozen.
Таблица 42-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
QUICKFORM_NONEXIST_ELEMENT | Element '$element' does not exist in HTML_QuickForm::freeze() | Tried to freeze a non-existant element | Check the element's name spelling |
Sets the required note. This note is usually displayed below the form when the form contains required fields.
Sets JavaScript warning messages: the first is displayed before element errors, the second after them. Useless if the form had no rules added with 'client' modifier.
Returns the required note. This note is usually displayed below the form when the form contains required fields.
Returns JavaScript used to validate the form on client side. Returns an empty string if no rules were added with 'client' modifier.
Returns a reference to default renderer object. You can use this method to save a few keystrokes:
<?php $renderer =& $form->defaultRenderer(); ?> |
<?php require_once 'HTML/QuickForm/Renderer/Default.php'; $renderer =& new HTML_QuickForm_Renderer_Default(); ?> |
Whether to collect hidden elements (passed to the Renderer's constructor)
return array of form contents, structure is described in renderer documentation.
(optional) Any extra data to insert right before form is rendered. Data will be inserted via addElement('html', $in_data)
These renderers are based on pre-3.0 HTML_QuickForm code and require no external classes to do their work.
Before release 3.0, form outputting logic was implemented as methods of HTML_QuickForm class. This led to two problems:
Bloat of the said class (80+ methods!)
Difficulties in adding new output logic (i.e. using template engines)
In release 3.0, new system was implemented. The form output logic is now contained in classes that extend HTML_QuickForm_Renderer, their behaviour is based on Visitor design pattern from the classic "Design Patterns" book. This gives the following advantages:
Code for some particular output method is loaded only when the method is used.
It is much easier to add new output method.
The main steps of using any available renderer are quite similar:
<?php // include the renderer class require_once 'HTML/QuickForm/Renderer/FooBar.php'; // instantiate the renderer $renderer =& new HTML_QuickForm_Renderer_FooBar($options); // do some customization $renderer->adjustSomething('element1', '...'); // ... $renderer->adjustSomething('elementN', '...'); // process the form $form->accept($renderer); // output the results $renderer->toFooBar(); ?> |
Concerning usage examples: Usage examples provided in the manual are pretty basic. More complex examples for Default renderer can be found in docs/ directory, for all other renderers - in docs/renderers/ directory of HTML_QuickForm.
This renderer directly generates and outputs form HTML. It is based on pre-3.0 built-in form output logic.
The renderer has built-in templates for elements, their format is similar to that of HTML_Template_Sigma or HTML_Template_IT (but only placeholders and blocks are supported). When renderer's renderSomething() method is called, it finds the template for the element, makes necessary substitutions and appends the result to the form's HTML.
It is recommended to use the Default renderer when you are not using any template engine in your application or do not need to do any customization to form output. It is the fastest way to output a form.
Пример 42-1. Default renderer usage
|
Подсказка: HTML_QuickForm::toHtml() method uses the Default renderer internally.
Clears all the HTML out of the templates that surround notes, elements, etc.
Useful when you want to use addElement('html', '...') to create a completely custom form look.
Sets element template. When called with one parameter, it sets the default element template, when called with two parameters it sets template for the concrete element. The template should include at least the {element} placeholder.
The default element template is
"\n\t<tr>\n\t\t<td align=\"right\" valign=\"top\"><!-- BEGIN required --><span style=\"color: #ff0000\">*</span><!-- END required --><b>{label}</b></td>\n\t\t<td valign=\"top\" align=\"left\"><!-- BEGIN error --><span style=\"color: #ff0000\">{error}</span><br /><!-- END error -->\t{element}</td>\n\t</tr>" |
The HTML surrounding an element
(optional) Name of the element to apply template for
Sets form template. The template should include {attributes} and {content} placeholders.
The default form template is
"\n<form{attributes}>\n<table border=\"0\">\n{content}\n</table>\n</form>" |
The HTML surrounding an element
Name of the group to apply template for
Sets template for a group wrapper
This template is contained within a group-as-element template set via setElementTemplate() and contains group's element templates, set via setGroupElementTemplate().
By default, the template is empty.
The HTML surrounding group elements
Name of the group to apply template for
Sets header template. The template should include the {header} placeholder.
The default header template is
"\n\t<tr>\n\t\t<td style=\"white-space: nowrap; background-color: #CCCCCC;\" align=\"left\" valign=\"top\" colspan=\"2\"><b>{header}</b></td>\n\t</tr>" |
Sets the note indicating required fields template. The template should include the {requiredNote} placeholder.
The default template is
"\n\t<tr>\n\t\t<td></td>\n\t<td align=\"left\" valign=\"top\">{requiredNote}</td>\n\t</tr>" |
This renderer does not output anything itself, it returns the form structure as an array. This array can later be used for generating the output. A usage example is available for this renderer and Smarty template engine, look in docs/renderers directory.
The form array structure is the following:
array( 'frozen' => 'whether the form is frozen', 'javascript' => 'javascript for client-side validation', 'attributes' => 'attributes for <form> tag', 'requirednote => 'note about the required elements', // if we set the option to collect hidden elements 'hidden' => 'collected html of all hidden elements', // if there were some validation errors: 'errors' => array( '1st element name' => 'Error for the 1st element', ... 'nth element name' => 'Error for the nth element' ), // if there are no headers in the form: 'elements' => array( element_1, ... element_N ) // if there are headers in the form: 'sections' => array( array( 'header' => 'Header text for the first header', 'name' => 'Name of the first header', 'elements' => array( element_1, ... element_K1 ) ), ... array( 'header' => 'Header text for the Mth header', 'elements' => array( element_1, ... element_KM ) ) ) ); |
array( 'name' => 'element name', 'value' => 'element value', 'type' => 'type of the element', 'frozen' => 'whether element is frozen', 'label' => 'label for the element', 'required' => 'whether element is required', 'error' => 'error associated with the element', 'style' => 'some information about element style (e.g. for Smarty)', // if element is not a group 'html' => 'HTML for the element' // if element is a group 'separator' => 'separator for group elements', 'elements' => array( element_1, ... element_N ) ); |
Подсказка: HTML_QuickForm::toArray() method uses the Array renderer internally.
TRUE: collect all hidden elements into string; FALSE: process them as usual form elements
TRUE: instead of putting an array of labels into the 'label' element of resultant array, create separate keys for them named 'label_$key' where $key is the key in the array of labels (key + 1 if it is numeric). The first element of the array occupies the 'label' element.
Sets a style to use for element rendering (this style can later be checked by e.g. a template engine).
element name or array ('element name' => 'style name')
style name if $elementName is not an array
These renderers use template engines to actually generate the HTML for the form.
This renderer was written by Thomas Schulz. It is based on pre-3.0 HTML_QuickForm::toArray() code and ITStatic renderer. It can be used to output the form into the 'static' Smarty template. Usage example for this is available in docs/renderers.
The form array structure is the following:
array ( ['frozen'] => 'whether the complete form is frozen', ['javascript'] => 'javascript for client-side validation', ['attributes'] => 'attributes for <form> tag', ['hidden'] => 'html of all hidden elements', ['requirednote'] => 'note about the required elements', ['errors'] => Array ( ['1st_element_name'] => 'Error for the 1st element', ... ['nth_element_name'] => 'Error for the nth element', ), ['header'] => Array ( ['1st_header_name'] => 'Header text for the 1st header', ... ['nth_header_name'] => 'Header text for the nth header' ), ['1st_element_name'] => 'Array for the 1st element', ... ['nth_element_name'] => Array for the nth element' ); |
array( ['name'] => 'element name', ['value'] => 'element value', ['type'] => 'type of the element', ['frozen'] => 'whether element is frozen', ['label'] => 'label for the element', ['required'] => 'whether element is required', // if element is not a group: ['html'] => 'HTML for the element', // if element is a group: ['separator'] => 'separator for group elements', ['1st_gitem_name'] => 'Array for the 1st element in group', ... ['nth_gitem_name'] => 'Array for the nth element in group' ); |
You can use {$label} or {$html} placeholders to let the renderer know where where the element label or the element html are positionned according to the error message. They will be replaced accordingly with the right value. The error message will replace the {$error} placeholder. For example: {if $error}<span style="color: red;">{$error}</span>{/if}{$html} will put the error message in red on top of the element html.
If you want all error messages to be output in the main error block, use the {$form.errors} part of the rendered array that collects all raw error messages.
If you want to place all error messages manually, do not specify {$html} nor {$label}.
Groups can have special layouts. With this kind of groups, you have to place the formated error message manually. In this case, use {$form.group.error} where you want the formated error message to appear in the form.
You can use {$label} or {$html} placeholders to let the renderer know where where the element label or the element html are positionned according to the required tag. They will be replaced accordingly with the right value. You can use the full smarty syntax here, especially a custom modifier for I18N. For example: {if $required}<span style="color: red;">*</span>{/if}{$label|translate} will put a red star in front of the label if the element is required and translate the label.
The word 'dynamic' in renderer name means that exact form layout is defined at script runtime. This also means that you can create one template file for all your forms. That template should contain a block for every distinct element 'look' appearing in your forms and also some special blocks. If a special block is not set for an element, the renderer falls back to a default one.
If most of your forms tend to share the same look (a good example would be back-office interface), your best bet will be to use Dynamic renderer. If each of your forms has a really special layout, you should go with a Static one.
This is a somewhat minimal template, but it contains all the necessary elements to render any form you are able to define with the package.
{qf_javascript} <form {qf_attributes}> <!-- BEGIN qf_hidden_loop --> {qf_hidden} <!-- END qf_hidden_loop --> <table> <!-- BEGIN qf_errors --> <tr> <td> Collected errors: <ul> <!-- BEGIN qf_error_loop --> <li>{qf_error}</li> <!-- END qf_error_loop --> </ul> </td> </tr> <!-- END qf_errors --> <!-- BEGIN qf_main_loop --> <!-- BEGIN qf_header --> <tr> <th colspan="2">{qf_header}</th> </tr> <!-- END qf_header --> <!-- BEGIN qf_element --> <tr valign="top"> <td align="right"> <!-- BEGIN qf_element_required --><span style="color: #FF0000;">*</span><!-- END qf_element_required --> <b>{qf_label}</b> </td> <td> <!-- BEGIN qf_element_error --><span style="color: #FF0000;">{qf_error}</span><br /><!-- END qf_element_error --> {qf_element} </td> </tr> <!-- END qf_element --> <!-- BEGIN qf_group --> <tr valign="top"> <td align="right"> <!-- BEGIN qf_group_required --><span style="color: #FF0000;">*</span><!-- END qf_group_required --> <b>{qf_group_label}</b> </td> <td> <!-- BEGIN qf_group_error --><span style="color: #FF0000;">{qf_error}</span><br /><!-- END qf_group_error --> <!-- BEGIN qf_group_loop --> <!-- BEGIN qf_group_element -->{qf_separator}{qf_label}{qf_element}<!-- END qf_group_element --> <!-- END qf_group_loop --> </td> </tr> <!-- END qf_group --> <!-- END qf_main_loop --> <!-- BEGIN qf_required_note --> <tr> <td> </td> <td align="left" valign="top">{qf_required_note}</td> </tr> <!-- END qf_required_note --> </table> </form> |
Blocks in the template
This block should always be present and should be a parent for all visible elements' blocks. It is used to implement "flow", to render elements one after another.
This is the default block for rendering form elements. This block should always be present, as the renderer uses the following logic to decide which block to use for an element's output:
If a special block was set for an element, use that
If a block qf_%element's type% (e.g. qf_password) exists, use that
Use qf_element
The block will be touch'd if an element is required.
An error associated with an element will be output here.
This is the default block used to output headers. Should be present unless you have no headers in your form.
Default block to output groups. Should be present unless you do not use grouped elements.
An analog of qf_main_loop, used to render group's elements one after another. A %group's block%_loop should always be present inside %group's block%
A default block to render group's elements, %group's block%_element should always be present inside %group's block%_loop (for the same reason as the qf_element should be present in qf_main_loop)
This is used to output collected errors for the elements that do not have a %element's block%_error block.
<input type="hidden" /> elements are rendered here.
Placeholders in the template
Javascript for client-side form validation will be output here.
If there are required elements in the form, a note will be output here
Assuming the template is in ./qform.html:
<?php require_once 'HTML/QuickForm/Renderer/ITDynamic.php'; require_once 'HTML/Template/Sigma.php'; // Instantiate the template object and load the template file $tpl =& new HTML_Template_Sigma('.'); $tpl->loadTemplateFile('qform.html'); // Instantiate the renderer and process the form $renderer =& new HTML_QuickForm_Renderer_ITDynamic($tpl); $form->accept($renderer); // Output the results $tpl->show(); ?> |
Template class compatibility: This renderer was developed and tested using HTML_Template_Sigma. While it probably will work with HTML_Template_IT, no warranties can be given.
Removing empty blocks: The renderer assumes that the template object was set up to remove empty blocks (this is the default behaviour). If that is not true, the results will be pretty discouraging.
element name or array ('element name' => 'block name')
block name if $elementName is not an array
The word 'static' in renderer name means that exact form layout is defined before the execution of the script starts. That also means that you should have an unique template for each form you want to display with this renderer.
The IT Static renderer, as opposed to the IT Dynamic renderer, offers more flexibility in the way you display your forms but might also takes more time to implement. Therefore, if your form is using always the same pattern to display form element labels and form element html, it is recommended to use the Dynamic renderer. On the other hand, if you have many different layouts for your form elements, for example if you alternate text and form elements, you will prefer to use the Static renderer.
With the ITStatic renderer, you have to know beforehand which elements (or group of elements) will compose your form. So we will start by defining our elements.
Пример 42-1. Defining the elements
|
One header: 'Registration form'
One hidden field
One group of two textfields: firstname and lastname
One textfield for the E-Mail address
One selectbox for the country with an empty default value
Two buttons: Reset and Register
One checkbox to subscribe to the newsletter
Now that we know which elements compose our form, it will be easy to layout the form using a WYSIWYG or an HTML editor. The idea is to use placeholders instead of labels and element html. The placeholders are named after the form and element or group names: formName_elementName or formName_groupName_elementName. Then you add _label or _html. We will save the following code in a template.html file.
Пример 42-2. A template
|
As you can notice, the layout is static. This makes the Static renderer only useful if your form does not change on runtime. Nevertheless, you can still hide blocks if you use the removeEmptyBlocks option of HTML_Template_IT / HTML_Template_Sigma. Now that we have the elements and the template, we are going to use our Static renderer.
Пример 42-3. Using the renderer
|
You can optionally specify the way your required elements and validation errors are rendered using respectively setRequiredTemplate() and setErrorTemplate(). In the given string, you will place either the {label} or the {html} placeholder at the position you want. If you prefer to have all your errors displayed at the same place, pass an empty string to setErrorTemplate() and add this block to your template at the position you want:
<!-- BEGIN myform_error_loop --> <font color="red">{myform_error}</font><br /> <!-- END myform_error_loop --> |
With the Static renderer, it is also possible to customize the way your groups are rendered. If you simply use a placeholder for your whole group, the group will be rendered using HTML_QuickForm default renderer. This means that if a separator string (or an array of separators) was specified, it will be used the usual way. In our form, the group called 'name' was rendered this way, using a - to separate the elements.
The problem we have is that elements inside the group don't show their label, so it is not possible to guess which textfield is firstname and which one is lastname. By replacing the layout for the element 'name' by these new placeholders, can customize the way the group will be displayed:
(...) <tr> <td>{myform_name_label}</td> <td> <!-- BEGIN myform_name_error -->{myform_name_error}<!-- END myform_name_error --> <table> <tr><td>{myform_name_first_html}</td><td>{myform_name_last_html}</td></tr> <tr><td>{myform_name_first_label}</td><td>{myform_name_last_label}</td></tr> </table> </td> </tr> (...) |
We need to add a new block and placeholder to let the renderer know where to display the error relative to this group. As you have noticed, every placeholder take the name of his group along with its own name.
Подсказка: Also note that if you use elements with the same name, like radios that are not in a group, you will have to add an index to the placeholder name starting at 0, like this: {myform_myradio_0_html}, {myform_myradio_1_html}...
We have seen how to use the Static renderer with standard elements and groups of elements. We have seen how to display errors and required tags. They won't show in your form because we did not add any validation rules. Feel free to try to add them as an exercise. You can also add a special placeholder to your template {myform_required_note}, it will display the note that indicates how to find required elements. This renderer usage is very easy, when you feel comfortable with it, you can move on to the Dynamic renderer which might also fit your needs in an other way.
You can use {label} or {html} placeholders to let the renderer know where where the element label or the element html are positionned according to the error message. They will be replaced accordingly with the right value. The error message will replace the {error} place holder. For example: <font color="red">{error}</font>{html} will put the error message in red on top of the element html.
If you want all error messages to be output in the main error block, do not specify {html} nor {label}.
Groups can have special layouts. With this kind of groups, the renderer will need to know where to place the error message. In this case, use error blocks like: <!-- BEGIN form_group_error -->{form_group_error}<!-- END form_group_error --> where you want the error message to appear in the form.
You can use {label} or {html} placeholders to let the renderer know where where the element label or the element html are positionned according to the required tag. They will be replaced accordingly with the right value. For example: <font color="red">*</font>{label} will put a red star in front of the label if the element is required.
This renderer has three main distinctives: an easy way to create custom-looking forms, the ability to separate the creation of form elements from their display, and being able to use QuickForm in widget-based template systems.
All of the renderers allow you to create a custom-looking form. However, unlike the default renderer, QuickHtml is solely for creating custom forms and has the additional benefits discussed below.
It is often desirable to separate the creation of form elements and their accompanying rules from their actual display on a page. For example, in the MVC design pattern it may be useful to create the form elements and their rules in the Model classes which control how the submitted data will be saved (field lengths, allowed characters, etc.), but leave the rendering of those form elements to the View classes which only care about how to make the page look a certain way.
A widget is a chunk of re-usable html which can be used with other widgets to create a webpage. Any template system which supports widgets (and nearly all do) can be used with QuickHtml. An example widget may consist of a table with reserved places for the form elements. The form elements would be rendered into those places and then the form tags, any remaining form elements (such as hidden elements), and any accompanying javascript for validation would be wrapped around the table widget.
The following is an example usage of the QuickHtml renderer. The "template" system we use is just a simple html widget in which the form elements are placed, but it could be replaced with a more complex template system. A more complex usage example is in docs/renderers/QuickHtml_example.php
Пример 42-1. QuickHtml renderer usage
|
Any html to put inside the form tags. This would normally be the html template into which you have rendered the form elements.
If you want to modify an existing renderer or write a new one, this section will be of interest to you.
Defines the abstract methods that should be implemented by child classes.
QuickForm renderers implement the Visitor design pattern. That means that each form element has an accept() method that is called with a renderer instance as a parameter. This method does the following:
If the element contains other elements (HTML_QuickForm_group and HTML_QuickForm itself) then it iterates over them calling each element's accept() method and calls the methods for rendering the container itself (e.g. startForm() and finishForm()).
If the element is simple, then it calls the renderer's method for rendering itself (e.g. renderHeader()).
It may seem that renderer object has to have a renderConcreteElement() method for each HTML_QuickForm_concreteElement it may visit, but fortunately most of the elements have fairly similar rendering needs, so instead of separate renderTextarea() and renderCheckbox() we have a generic renderElement() method.
The renderer should take care of "accumulating" the information passed to its methods and of generating some type of output based on it. How this is implemented internally depends on the renderer type.
The first thing you have to decide upon is how your renderer will accumulate the information. You'll probably have to create some data structures to keep it (unless you are going to pass the information to e.g. a template object at once).
Then you have to make concrete implementations for all the abstract methods defined in HTML_QuickForm_Renderer. One notable exception is renderHtml() method that is implemented only in the Default renderer and will probably stay this way.
You'll probably also want to add some public methods for customizing the output and getting the results of the renderer's work. But this depends on the type of the renderer very much.
If you want to contribute the renderer you made to QuickForm, consider the following
Your code should be useful to other people (e.g. renderer for some obscure private template engine is a bad contribution).
Your renderer should have non-trivial usage examples.
And last but not least, you code will have to conform to PEAR coding standards.
Подсказка: If you have examples for additional uses of an existing renderer, that will be a welcome contribution, too.
HTML_QuickForm_group object being visited
Whether a group is required
An error message associated with a group
HTML_QuickForm_element object being visited
Whether an element is required
An error message associated with an element
Called when visiting a raw HTML/text pseudo-element
Implementation of the method: HTML_QuickForm_html elements are used to directly add HTML to the form output. Thus they are useful with the Default renderer, but not with template-based one. Default renderer is currently the only one actually implementing this method, all others silently ignore HTML_QuickForm_html elements.
This is an add-on to HTML_QuickForm package that allows (among other things) to build multipage forms.
Cool features:
Includes several default Actions that allow easy building of multipage forms.
Includes usage examples for common usage cases (single-page form, wizard, tabbed form).
This package implements a PageController design pattern, which essentially means that there is a single page processing requests and actions this page performs depend on parameters passed in GET or POST data. The pattern is described in more detail on Martin Fowler's website and WACT project website.
What does this mean in application to QuickForm: we have a single script which shows and validates different forms depending on data in request. This allows to fairly easy build very complex forms consisting of several pages (think wizards and such).
The most basic implementation of the PageController pattern would look like
switch ($_REQUEST['action']) { case 'foo': doFoo(); break; case 'bar': doBar(); break; default: echo 'Hello, world!'; } |
HTML_QuickForm_Controller: this class extracts the action name from request and calls the appropriate handler. It includes several Pages.
HTML_QuickForm_Page: this class (extending HTML_QuickForm) represents a single page of a form.
HTML_QuickForm_Action: this class implements the Command design pattern, i.e. is essentially an OO callback.
Session initialization: This simple example does not use sessions since there is no need to pass data between pages. You'll need to use sessions when dealing with a real multipage form, though. HTML_QuickForm_Controller does not start a session automatically, you should explicitly call session_start() before instantiating the controller class.
To ease understanding of this package's features, lets take an example form from HTML_QuickForm tutorial and redo it using HTML_QuickForm_Controller:
Пример 42-1. Basic Controller usage
|
You may note that the code is more verbose than the original. That is true, but to make a three page wizard-type form you'll only need to create three subclasses of HTML_QuickForm_Page and 'process' event handler based on HTML_QuickForm_Action and add them to Controller, while without the Controller infrastructure it will require a non-trivial amount of programming.
You need to subclass HTML_QuickForm_Page and override its buildForm() method. Its contents are pretty self-explanatory (if you are familiar with QuickForm), except for a few things:
$this->_formBuilt = true; |
The second notable line is
$this->addElement('submit', $this->getButtonName('submit'), 'Send'); |
The third thing is
$this->setDefaultAction('submit'); |
You'll usually need to create handlers for two actions: 'process' and 'display'. While it is difficult to say anything about the former, as only you know how to process your form, for the latter you'll need to subclass HTML_QuickForm_Action_Display and override its _renderForm() method to call the appropriate Renderer and do form output customization.
Next we instantiate the page class defined above
$page =& new FirstPage('firstForm'); |
$page->addAction('process', new ActionProcess()); |
Then we instantiate the controller
$controller =& new HTML_QuickForm_Controller('tutorial'); |
Then we set the defaults for the form and add the page to it
$controller->setDefaults(array( 'name' => 'Joe User' )); $controller->addPage($page); |
Finally we call the Controller's run() method
$controller->run(); |
...are available in the package archive. Along with the example similar to the provided above, there are two multipage forms:
Wizard: form pages contain 'Next' and 'Back' buttons and you can't go to the next page unless the current page is valid.
Tabbed form: form has several pages and buttons allow to go directly to the corresponding page. Form is validated only when the global 'Submit' button is pressed.
This document is based on questions asked on PEAR general mailing list. You are encouraged to search the list archives to find more verbose answers and examples.
Sorry, HTML_QuickForm_Controller is not intended for PHP newbies. If you don't understand what classes are, if you have no prior experience with QuickForm, if you are a fan of copy-paste programming then this package is not for you.
The package is indeed complex, but so are the problems it is trying to solve. Try to rewrite any of the enclosed multipage form examples without using such a package and you'll see what we mean.
To avoid confusion lets use the terms "action" for the string containing the name of the action and "action handler" for the subclass of HTML_QuickForm_Action.
While you can invent your own action names and create custom handlers for them, you'll most certainly have to deal with the default actions and their handlers first.
Default action names
This action has a default handler, HTML_QuickForm_Action_Display, which displays the form using the Default renderer. You should subclass this handler if you want to customize the form output. This action is called automatically when the page needs to be displayed and should not be bound to buttons via getButtonName().
This action should be bound to a "global" submit button for a form. It can be the "submit" button of a single-page or tabbed multi-page form, "finish" button of a wizard. This action has a default handler, HTML_QuickForm_Action_Submit, which checks whether all the pages of the form are valid, then either calls the 'process' handler or displays the invalid page.
This action should be bound to the "Next" button of (usually) a modal multipage form (AKA wizard). This action has a default handler, HTML_QuickForm_Action_Next, which checks the validity of the current page and redirects to the next one if the current is valid (or if the form is not modal). On the last page of a modal multipage form this behaves like the default 'submit' handler.
This action should be bound to the "Back" button of (usually) a modal multipage form (AKA wizard). This action has a default handler, HTML_QuickForm_Action_Back, which redirects to the previous page if one exists. As of QFC 0.9.3, no form validation takes place on 'back' action.
This action has a default handler, HTML_QuickForm_Action_Jump, which just makes HTTP redirect to the given page of the form. This action should not be bound to buttons via getButtonName().
This is the action called by default 'submit' and 'next' (on the last page of the wizard only) handlers after successful (i.e. without validation errors) form submit. This action doesn't have a default handler, you should define the custom one yourself and implement all the necessary logic to process the form's values in it.
There is also a default handler, HTML_QuickForm_Action_Direct, that does not have a default action name. It is used to go to the specific page of the form and should be explicitly added via Page::addAction() or Controller::addAction() with the name of the target page as $actionName and bound to buttons via getButtonName() using the same name.
You should use Page's handle() method:
$page->handle('action'); |
Create a subclass of HTML_QuickForm_Action, add the necessary logic to its perform() method. Add it to the Page or to the Controller via addAction() with the appropriate name.
If you intend to bind this action to some button via getButtonName(), you should care about storing values in the container():
Build the form.
Get a reference to container.
Fill the container's ['values'][$pageName] and ['valid'][$pageName] elements.
As usual, see the default action handlers' source for the examples.
Controller is able to properly handle actions bound to <input type="image" /> controls, too. You don't have to do anything special, just set the control's name via getButtonName().
If you want to bind an action to something like a hyperlink, you must consider the following: the form must be submitted to be able to get its values, thus you need to write some javascript that will submit the form and somehow pass the action name to the controller.
Controller keeps the form data and validation status in session in so-called container, accessible via container() method. To reset the form you need to clear this container, which is achieved by passing TRUE to container().
The answer is quite simple: you need to use the container() method of HTML_QuickForm_Controller, like this:
// Note the reference $data =& $page->controller->container(); $data['_my_stuff'] = $stuff; |
$data =& $page->controller->container(); $stuff = $data['_my_stuff']; |
Please note that Controller knows nothing about your additional data, so do not expect it to return it via exportValues() method or the like. You'll have to use the container() method and extract the data yourself. However, your data will be deleted when the container is reset.
First of all, please understand that HTML_QuickForm_Page is a subclass of HTML_QuickForm, thus everything that applies to the parent class will apply to the child. You are encouraged to read the section about renderers in HTML_QuickForm and the docs to the renderer you are trying to use. The usage examples are available in docs/renderers/ directory of QuickForm distribution.
As was already pointed out, you should subclass the HTML_QuickForm_Action_Display class if you want to customize the form output and add an instance of this subclass as a handler for Page's 'display' action. Its _renderForm() will contain all renderer-specific code.
The only new problem Controller introduces is the buttons bound to specific actions via getButtonName(). If you are using some kind of Dynamic renderer this will not be a problem, as you need not care about the elements names, but you need these names to output the form via Static renderer.
We'll assume using ITStatic renderer but the same can be applied to other Static renderers as well. You basically have 3 options:
Manually add the buttons/placeholders with the names that should be autogenerated via getButtonName() to the form. This is not recommended, as the names should not be of interest to anyone except Controller itself and should not be used directly.
Put the auto-named buttons into group. You can name the group any way you like, just be sure to set $appendName to false. When ITStatic sees {form_element_html} placeholder, it'll assign group's HTML to it.
Call getButtonName() from within template. Add the following to the template
<input type="submit" value="Bla-bla" name="func_buttonName('action')" ... /> |
$tpl->setCallbackFunction('buttonName', array(&$page, 'getButtonName')); |
Thanks to Donald Lobo for this contribution.
Lets assume we have a three-page wizard:
Page 1 has a control that lets the user choose the next page.
Based on input, the user is directed to either page 2A or page 2B.
Both page 2A and 2B go to page 3 (this is commonly referred to as a StateMachine in programming books).
You need to create several action handlers based on QFC's default HTML_QuickForm_Action_Next and HTML_QuickForm_Action_Back. You can do this either at the Page level or at the Controller level. The Page level subclassing is simple, but if you have a complex StateMachine you will end up having multiple subclasses.
For the above example, the 'next' action on page 1 sends the 'user' to either page 2 or page 3 based on input. The handler also sets the 'valid' flag of the page that will not be visited.
The 'back' action on pages 2A and 2B sends the user back to page 1, while the 'next' action sends him to page 3.
Finally, the 'back' action handler on page 3 should examine the input on page 1 and send the user to either 2A or 2B.
The working example is available in statemachine.php file.
Client-side validation is called by form's onSubmit handler, if you remove the handler, the validation will not run. Therefore you need to remove it if user clicks on 'Back' button. This can be achieved f.e. by adding the following as the button's onClick handler:
this.form.onsubmit = null; return true; |
This class keeps track of pages and (default) action handlers for the form, it manages keeping the form values in session, setting defaults and constants for the form as a whole and getting its submit values.
Generally you don't need to subclass this.
Sets the form name and modal/non-modal behaviour. Different multipage forms should have different names, as they are used to store form values in session. Modal forms allow passing to the next page only when all of the previous pages are valid.
This handler will be used if the Page that has to handle some action does not have a handler itself.
name of the action
the handler for the action
Session initialization: The package does store the data in session, but it does not start the session automatically. You must call session_start() function yourself before instantiating HTML_QuickForm_Controller.
Returns a reference to a session variable containing the form-page values and pages' validation status. This is a "low-level" method, use exportValues() if you want just to get the form's values.
The structure of the container is the following
array ( 'defaults' => array(... default form values ...), 'constants' => array(... constant form values ...), 'values' => array( 'page1' => array(... submitted values for this page ...), ... 'pageN' => array(... submitted values for this page ...) ), 'valid' => array( 'page1' => null if the page was never validated, true if valid, false otherwise ... 'pageN' => null if the page was never validated, true if valid, false otherwise ) ) |
If true, then reset the container: clear all default, constant and submitted values
This method searches the $_REQUEST array for an element with a special name and splits the name into page name and action. If such an element is not found, the first page will be default and 'display' the default action.
require_once 'HTML/QuickForm/Controller.php'; |
object HTML_QuickForm_Page &HTML_QuickForm_Controller::getPage
(string $pageName)
This will be called if the page itself does not have a handler to a specific action. The method also loads and uses default handlers for common actions, if specific ones were not added.
The page that failed to handle the action
Name of the action
This finds the current page, the current action and passes the action to the page's handle() method.
Generally you'll need to subclass this and define your buildForm() method that will build the form. While it is also possible to instantiate this class and build the form manually, this is not the recommended way.
Note that unlike constructor of HTML_QuickForm there is no $action, as the form is always submitted to the current page. Note also that $formName is not optional.
Form's name
Form's method
Form's target
Extra attributes for <form> tag
name of the action
the handler for the action
Builds a form. You should override this method when you subclass HTML_QuickForm_Page, it should contain all the necessary addElement(), applyFilter(), addRule() and possibly setDefaults() and setConstants() calls. The method will be called on demand, so please be sure to set $_formBuilt property to TRUE to assure that the method works only once.
Returns a name for a submit button (or an <input type="image"> control) that will invoke a specific action. This means the following: if you do
$this->addElement('submit', $this->getButtonName('foo'), 'Foo'); |
This method simply calls the perform() method of an Action object registered for this action name. If an Action object for it was not registered here, controller's handle() method will be called.
The method is NOT intended for general usage. It should be used to assign form values from the container instead of from actual request data.
This is necessary as the user may just press Enter instead of clicking one of the named submit buttons and then no action name will be passed to the script.
This method adds a special hidden element to the form the contents of which will be used by Controller if no action name is found in the submitted values.
The Controller will select the appropriate Action to call on the request and call its perform() method. The subclasses of this class should implement all the necessary business logic.
The default action handlers are described in the FAQ section.
HTML_QuickForm_Action
Таблица 42-1. Classes that extend HTML_QuickForm_Action
Class | Summary |
---|---|
HTML_QuickForm_Action_Back | The action for a 'back' button of wizard-type multipage form. |
HTML_QuickForm_Action_Direct | This action allows to go to a specific page of a multipage form. |
HTML_QuickForm_Action_Display | This action handles the output of the form. |
HTML_QuickForm_Action_Jump | The action handles the HTTP redirect to a specific page. |
HTML_QuickForm_Action_Next | The action for a 'next' button of wizard-type multipage form. |
HTML_QuickForm_Action_Submit | The action for a 'submit' button. |
the current form-page
Current action name, as one Action object can serve multiple actions
Please note that the name for this action in addAction() should NOT be 'direct', but the name of the page you wish to go to.
If you want to customize the form display, subclass this class and override the _renderForm() method, you don't need to change the perform() method itself.
Replacement for the default renderer of HTML_QuickForm that uses only XHTML and CSS but no table tags, and generates fully valid XHTML output.
HTML_QuickForm_Renderer_Tableless is a replacement of the default renderer of HTML_QuickForm. It has two main goals:
Accessibility: Because of the abandonment of table tags and the addition of for attributes to the label tags and id attributes to the form elements, the generated output provides good accessibility. Challenged person might use screen readers, and unhindered persons benefit from the possibility to click on the labels to set the focus to the belonging form element.
Validity: The generated output of the renderer is fully XHTML 1.1 valid.
To use this renderer, you just need to copy (and modify if you want) the stylesheet and do something like this:
require_once 'HTML/QuickForm.php'; require_once 'HTML/QuickForm/Renderer/Tableless.php'; $form =& new HTML_QuickForm(); $renderer =& new HTML_QuickForm_Renderer_Tableless(); // usual code, e.g. new form fields, rules, ... $form->accept($renderer); echo $renderer->toHtml(); |
For full XHTML validity, you need to add the following line to your code:
$form->removeAttribute('name'); |
This document is based on questions asked on PEAR general mailing list and other mailing lists and forums.
1. The div tag in the element template is broken, a closing quote mark is missing! Can you please fix this?
No, it is not missing and there is no need to fix the element template.
HTML_QuickForm_Renderer_Tableless requires that HTML_QuickForm >= 3.2.6 is installed. Previous versions don't work correctly for element templates that have two error blocks.
Please use the PEAR installer to avoid such problems in the future. The installer takes care of the dependencies between packages.
This might sound funny because a hidden element is obviously already hidden, but the simple reason for this is the XHTML validity.
XHTML allows input elements only within block elements. And as form is not a block element, but div is a block element, this trick is used to make the output XHTML valid.
3. The layout of the forms is broken in Windows Internet Explorer 7. Is there a solution for this problem?
Release 0.4.3 contains a fix for this problem. The solution is to remove the "height: 1px;" style from "form fieldset li" block in the stylesheet.
Warning: This breaks layout compatibility with Firefox 1.x browsers (Firefox 2.0 still works as expected). The next question contains a solution for Firefox 1.x compatibility.
You need to add a "float: left;" style to the "form fieldset li" block in the stylesheet. In addition, you need to add the following two blocks to your stylesheet:
* html form fieldset li { float: none; } *+html form fieldset li { float: none; } |
If you don't need compatibility with Windows Internet Explorer 7, you don't need the mentioned CSS hacks, but can just (re-)add the "height: 1px;" style to the "form fieldset li" block in the stylesheet.
This is explained here: Howto: Adding explainations next to form fields with Tableless QuickForm renderer.
6. I'm having problems with the layout, the form and/or the other contents of my page are misplaced. How can I fix these problems?
Such problems are most likely caused by the style of the fieldsets. You can try two possible solutions.
At first, you can try to add
overflow: hidden; |
to the "form fieldset" block.
If this does not solve the problems, then try to remove the following two styles from the "form fieldset" block.
clear: both; float: left; |
Adds one or more element names that indicate the end of a fieldset (a new one will be opened when a the next header element occurs).
The HTML surrounding an element
(optional) Name of the element to apply template for
The HTML surrounding an element
Name of the group to apply template for
This template is contained within a group-as-element template set via setTemplate() and contains group's element templates, set via setGroupElementTemplate()
The HTML surrounding group elements
Name of the group to apply template for
Sets the template used when opening a hidden fieldset (i.e. a fieldset that is opened when there is no header element).
HTML_QuickForm_DHTMLRulesTableless is a DHTML replacement for the standard JavaScript alert window for client-side validation of forms built with HTML_QuickForm when using the HTML_QuickForm_Renderer_Tableless renderer.
In addition to the standard behaviour of HTML_QuickForm (i.e. showing the errors from client-side validation on the "onSubmit" event), this package can also show the errors on the "onBlur" and "onChange" events (see below for information on how to enable this).
To use this package you just need to do something like this:
require_once 'HTML/QuickForm.php'; require_once 'HTML/QuickForm/DHTMLRulesTableless.php'; require_once 'HTML/QuickForm/Renderer/Tableless.php'; $form = new HTML_QuickForm_DHTMLRulesTableless(...); $renderer = new HTML_QuickForm_Renderer_Tableless(); // usual code, e.g. new form fields, rules, ... $form->accept($renderer); echo $renderer->toHtml(); |
As already said for the tableless renderer, you need to add the following line to your code to get full XHTML validity:
$form->removeAttribute('name'); |
Замечание: $form can be used the same way as with the standard HTML_QuickForm package, there is no difference.
To enable validation on "onBlur" and "onChange" events, you need to add the following line before the $form->accept($renderer); call:
$form->getValidationScript(); |
API to create HTML tables
HTML_Table offers an interface for create a HTML table. You can work with the table like a spreadsheet. Instead of working with HTML code and linear adding of cells, you can address and fill cells independend of there position. There is no different, whether you start with fill a cell at the beginning, in the middle or at the end of the table, a row or a column.
Normaly, you would define a table with a constant number of rows and columns. But sometimes, you does not know, how many rows or columns you need: ie. transforming user input or the result of a database query to an HTML table.
In this case, you should enable the autoGrow feature. In this mode, HTML_Table adds new rows or columns automatically, if you use a cell address located in a not existing row or column.
If you create a table of data, sometimes you have not to fill all cells with different values. Perhaps you do not know the value for a cell, or you want to insert a default value - ie. retrieving data about users. Not every user has a mobile, a email address etc., in this case, an "n/a" should be inserted into that specific cell.
So, simply define "n/a" as autoFill value and fill only the cells where data exist. You need not to fill every cell; unfilled cells contain automatically an "n/a".
Our HTML table to create should contain the following data:
$data = array( '0' => array('Bakken', 'Stig', '', 'stig@example.com'), '1' => array('Merz', 'Alexander', 'alex.example.com', 'alex@example.com'), '2' => array('Daniel', 'Adam', '', '') ); |
Let us now start by creating a new instance of HTML_Table. The table should be 600 pixel wide. We do not know the quantity of the data to insert into the table - so we enable the autoGrow feature. Unfilled cells should contain an "n/a".
require_once 'HTML/Table.php'; $tableAttrs = array('width' => '600'); $table = new HTML_Table($tableAttrs); $table->setAutoGrow(true); $table->setAutoFill('n/a'); |
Now process every data entry. Here we use also the alternate feature of HTML_Table. Every second row will be colored red.
for ($nr = 0; $nr < count($data); $nr++) { $table->setHeaderContents($nr+1, 0, (string)$nr); for ($i = 0; $i < 4; $i++) { if ('' != $data[$nr][$i]) { $table->setCellContents($nr+1, $i+1, $data[$nr][$i]); } } } $altRow = array('bgcolor' => 'red'); $table->altRowAttributes(1, null, $altRow); |
Now we want to define the cells in the first row and column as header cells. It should looks like a spreadsheet application, so we want to use the color "silver" as the background colour for each header cell. The first row contains a column headline, the first column the number of the data set row.
$table->setHeaderContents(0, 0, ''); $table->setHeaderContents(0, 1, 'Surname'); $table->setHeaderContents(0, 2, 'Name'); $table->setHeaderContents(0, 3, 'Website'); $table->setHeaderContents(0, 4, 'EMail'); $hrAttrs = array('bgcolor' => 'silver'); $table->setRowAttributes(0, $hrAttrs, true); $table->setColAttributes(0, $hrAttrs); |
It is done! Our table is finished, now we can output the table as HTML code.
echo $table->toHtml(); |
<!-- BEGIN TABLE LEVEL: 0 --> <table width="600"> <tr> <th bgcolor="silver"> </th> <th bgcolor="silver">Surname</th> <th bgcolor="silver">Name</th> <th bgcolor="silver">Website</th> <th bgcolor="silver">EMail</th> </tr> <tr> <th bgcolor="silver">0</th> <td>Bakken</td> <td>Stig</td> <td>n/a</td> <td>stig@example.com</td> </tr> <tr> <th bgcolor="silver">1</th> <td bgcolor="red">Merz</td> <td bgcolor="red">Alexander</td> <td bgcolor="red">alex.example.com</td> <td bgcolor="red">alex@example.com</td> </tr> <tr> <th bgcolor="silver">2</th> <td>Daniel</td> <td>Adam</td> <td>n/a</td> <td>n/a</td> </tr> </table> <!-- END TABLE LEVEL: 0 --> |
If you want to divide your tables into thead, tfoot and tbody groups, you need to get table objects using getHeader(), getFooter() and getBody(), which you can then use like the normal table object.
$table = new HTML_Table(); $head =& $table->getHeader(); $foot =& $table->getFooter(); $body =& $table->getBody(); $head->setCellContents(...); $body->setCellContents(...); echo $table->toHtml(); |
Замечание: The rendering order is thead, then tfoot and as the last group tbody. This is not a bug but intended behaviour because that's the way it is defined in the (X)HTML Standard.
This document is based on questions asked on PEAR general mailing list and other mailing lists and forums.
Here is an example on how to set the attribute string id="header" for the thead tag. For the other two tags the procedure is similar.
$table = new HTML_Table(); // [...] $thead =& $table->getHeader(); $thead->setAttributes(array('id' => 'header')); // [...] $table->display(); |
This would give the following result:
<table> <thead id="header"> [...] </thead> [...] </table> |
array $attributes - Associative array of table tag attributes
integer $tabOffset - Tab offset of the table
boolean $useTGroups - Whether to use the thead, tfoot and tbody groups or not
array $contents - Must be an indexed array of valid cell contents.
mixed $attributes - Associative array or string of table row attributes
string $type - Cell type either 'th' or 'td'
array $contents - Must be an indexed array of valid cell contents
mixed $attributes - Associative array or string of table row attributes. This can also be an array of attributes, in which case the attributes will be repeated in a loop.
string $type - Cell type either 'th' or 'td'
boolean $inTR - FALSE, if attributes are to be applied in TD tags; TRUE, if attributes are to be applied in TR tag
int $start - Row index of row in which alternating begins
mixed $attributes1 - Associative array or string of table row attributes
mixed $attributes2 - Associative array or string of table row attributes
boolean $inTR - FALSE, if attributes are to be applied in td tags; TRUE, if attributes are to be applied in tr tag.
HTML_Table::setAllAttributes() , HTML_Table::updateAllAttributes() , HTML_Table::setColAttributes() , HTML_Table::updateColAttributes() , HTML_Table::setCellAttributes() , HTML_Table::updateCellAttributes() , HTML_Table::updateRowAttributes() , HTML_Table::setRowAttributes()
Эта функция не должна вызываться статически.
Внимание |
Эта функция объявлена как deprecated. Это означает, что в будущих версиях пакета она может больше не поддерживаться. |
Returns the value of the autoGrow flag. If a value into an cell, which not exists, HTML_Table will automatically add a necessary row or column, if the flag is TRUE.
Returns the table object for the tfoot group
If the usage of the thead, tfoot and tbody groups was not activated via the third parameter of the constructor, the grouping will be activated automatically when calling this function.
Returns the table object for the thead group
If the usage of the thead, tfoot and tbody groups was not activated via the third parameter of the constructor, the grouping will be activated automatically when calling this function.
HTML_Table::updateAllAttributes() , HTML_Table::setColAttributes() , HTML_Table::setCellAttributes() , HTML_Table::setRowAttributes()
If this flag is set to TRUE, HTML_Table will automatically add new rows or columns when you insert a value into a non-existing cell.
Sets the caption of a table. This does not refer to the <th>-tag. The <caption>-tag defines a headline for the whole table.
string $caption - the caption string
mixed $attributes - Associative array or string of caption attributes
Sets the cell attributes for an existing cell. If the given indices do not exist and autoGrow is TRUE then the given row and/or column is automatically added. If autoGrow is FALSE, an error is returned.
int $row - Row index
int $col - Column index
mixed $attributes - Associative array or string of table cell attributes
Таблица 42-1. Возможные значения PEAR_Error
Error code | Error message | Meaning | Solution |
---|---|---|---|
" Invalid table row reference [$row] " | The row $row does not exists | Enable the autoGrow feature | |
" Invalid table column reference [$column] " | The column $column does not exists | Enable the autoGrow feature |
Sets the cell contents for an existing cell. If the given indices do not exist and autoGrow is TRUE then the given row and/or column is automatically added. If autoGrow is FALSE, then an error is returned.
int $row - Row index
int $col - Column index
mixed $contents - May contain HTML or any object with a toHTML() method
string $type - Cell type either 'th' or 'td'
Таблица 42-1. Возможные значения PEAR_Error
Error code | Error message | Meaning | Solution |
---|---|---|---|
" Invalid table row reference [$row] " | The row $row does not exists | Enable the autoGrow feature | |
" Invalid table column reference [$column] " | The column $column does not exists | Enable the autoGrow feature |
int $col - Column index
mixed $attributes - Associative array or string of table column attributes
mixed $colgroup - Empty string, string with attributes or an associative array of attributes for the columns
mixed $attributes - Associative array or string of colgroup attributes
Пример 42-1. Usage without a col tag
|
Пример 42-2. Usage with col tags
|
Пример 42-3. Usage with multiple colgroups
|
int $row - Row index
mixed $attributes - Associative array or string of table row attributes. This can also be an array of attributes, in which case the attributes will be repeated in a loop.
boolean $inTR - FALSE, if attributes are to be applied in td tags; TRUE, if attributes are to be applied in tr tag
Таблица 42-1. Возможные значения PEAR_Error
Error code | Error message | Meaning | Solution |
---|---|---|---|
" Invalid table row reference [$row] " | The row $row does not exists | Enable the autoGrow feature | |
" Invalid table column reference [$column] " | The column $column does not exists | Enable the autoGrow feature |
int $row - Row index
int $col - Column index
mixed $attributes - Associative array or string of table row attributes
int $col - Column index
mixed $attributes - Associative array or string of table row attributes
int $row - Row index
mixed $attributes - Associative array or string of table row attributes
boolean $inTR - FALSE if attributes are to be applied in td tags; TRUE, if attributes are to be applied in tr tag.
Таблица 42-1. Возможные значения PEAR_Error
Error code | Error message | Meaning | Solution |
---|---|---|---|
" Invalid table row reference [$row] " | The row $row does not exists | Enable the autoGrow feature | |
" Invalid table column reference [$column] " | The column $column does not exists | Enable the autoGrow feature |
An extremely flexible Template core, with multiple engines.
HTML_Template_Flexy started it's life as a simplification of HTML_Template_Xipe, However the long term aim of Flexy is to provide a universal Template Base API for Compiling and native PHP type templates.
Flexy currently supports a number of backends (Template Formats), and is designed to be extended to support more, The Key Formats are:
Standard - A rich Tokenizer driven engine, that uses {variable_placeholders}, attribute based (flexy:foreach="...."), and custom tag <flexy:tojavascript ... To rapidly create PHP code from simple markup. These templates are designed to be editable in WYSIWYG HTML editors, without breaking the tags
Regex - A classic templating backend, for supporting Smarty, Xipe, or Email type convertion to PHP code.
Raw - A non compiling backend, that enables you to create templates using PHP, Useful if you intend to redistribute your application and are concerned about compilation
Data can be assigned in two ways with flexy, depending on your prefered style of working.
Push - you put data into the template engine, using $flexy->setData(), and $flexy->setDataByRef(), this is similar to the way Smarty and other templates work.
Push/Pull - You provide the outputer with a Data Provider Object, (either a Data Object, or a Controller) that contains the data to display (and objects with methods that can be called). This has the added benefit of making the Variables in the template documentable, using PEAR standards, eg. PHPDoc comments.
With all this Flexibility, it still manages to achieve
Very Lightweight Simple API, which easy to learn
In Normal operation very little code is actually loaded (so it's fast)
If you look around you will see there are other template systems available in PHP, they generally fall into two categories, Replacement Systems, or PHP Code builders.
Replacement systems like HTML_Template_IT, FastTemplate, PhpLib Template tend to be slower at doing block and nested block type templates and involve alot of code to add each variable to the template.
Php Code builders like Flexy, Smarty, SimpleTemplate (now HTML_Template_Xipe) tend to be better at more complex templates, and can offer a better approach to extendability. (the long term aim of Flexy is to integrate support for all of these PHP Generator templates into a simple package)
The Standard Compiling Backend uses a Tokenizer, which offers the possiblities of using HTML tags and attributes to provide looping and conditionals, and make dynamic XML_Tree like elements of HTML Forms that can be manipulated in your code. (This conversion is only done once when the template compiles)
Flexy template is normally called from within a Controller Class (in the Model,View,Controller paragam). You just send HTML_Template_Flexy, the name of the template, and the object to output. - any variable you want printing out just has to be set in the object being used to ouput.
Пример 42-1. Typical usage example for HTML_Template_Flexy
|
Now the example template,
Пример 42-2. Example Template for HTML_Template_Flexy
|
And the output
Пример 42-3. Output of example for HTML_Template_Flexy
|
HTML_Template_Flexy can either be configured globally or on each instance, using an associated array. The easiest way to configure HTML_Template_Flexy is to use ini files (although you may also like to consider the PEAR::Config class, or your own configuration system)
Пример 42-1. This is a typical configuration file for HTML_Template_Flexy
|
To use this ini file with HTML_Template_Flexy, (and Possibly any other classes that use options like this)
Пример 42-2. Setting the default options
|
Alternatively you can set (or override) the configuration when you instantate the class
Пример 42-3. Setting the default options
|
This is the directory where all your templates are located
The directory where the compiled templates will be stored, This directory should be writable by the web server
Normally 0, means that the template will only be compiled once (or if the template file is altered), this is only really usefull if you are developing filters and need to test the result.
The default debugging level (default 0=off), 1= shows some debugging information
Default is 'en' - english. The language use for reading/writing templates. Currently it is only used in the compiled files filename = eg. originalname.html.en.php
Flexy uses get_text() internally if it is installed, and will replace all strings in a HTML page with the return value of get_text(). - This enables the creation of multilanguage sites with a little less pain.
A file {templatename}.strings.serial is created for each file that is parsed, you can use this with PHP's unserialize function to retrieve an array of all the strings in a file. (for translating), or just use the tool xgettext.
Default is 'Flexy' - The Flexy Tokenizer Driver engine. Other engines available are regex (similar to Xipe's engine), Raw (For plain PHP files with no replacement or compiling) and Standard (depreciated). You can use this field to load your own engines, either based Off the core code, or totally seperate..
Default is false - Allow the same template to exist in multiple places (eg. if you have theme's and want to fall back to a default template if the themed version doesnt exist.)
Default is '' - by default, the first matched template is used, if you have multiple paths, and want the last in the list to be used, then set this to 'reverse'
an array or comma seperated string of filters ONLY USED BY THE Regex backend, available filters are: BodyOnly (strip everything before and after body tag), Mail (add an extra line break after php tags.), Php (removes php code, not very reliably), SimpleTags (variable, method etc. replacement), XML (replace XML opening tag with echos.)
default is false - if you use the Flexy compiler, it turns off parsing of HTML, (not heavily tested)
default is false - allows php code in templates, normally off to help you reduce the chance of you shooting your self in the foot by forgetting to escape output.. (can be usefull for complex looping), but not normally recommended. setting to true, enables PHP code, setting to 'delete' removes php code. (although it doesnt prevent XSS attacks, so it is only suited to trusted users)
default is false - setting to true, will turn off the conversion of html form elements into HTML_Template_Flexy_Element's
default is ",2,'.',','" - this is the piece of code that is appended to the output engine when using the :n modifier, eg. {xxxx:n} is replaced with number_format($t->xxxx,2,'.',','); see the php manual page for number_format the default output would be: 1,200.00
when compiling the template flexy can rewrite <img src, <script src, <a href and xul stylesheet urls. The format is "match/original:new/url, match/another/original:new/url" each combo is seperated by a comma, and the colon seperates the pair. This helps previewing templates without using the engine.
default false - if set to true, the compile will return a string of the compiled template, rather than writing it to the cache file. eg. {object._myvar}
default false - if set to true, you can access variables prefixed with an underscore (normally private in PEAR's coding standards) eg. {someobject._myprivatevar} and {_myprivate}
default false - if set to true, you can access php's globals and superglobals, eg. {_POST[myvar]}, {GLOBALS[somevalue]}
default false - if set to true, you can access any native php function using the GLOBALS. prefix eg. {GLOBALS.date(#d/m/Y#)} obviously you should trust your template authors, as they can easily run exec() if this is enabled.
default 'en' - either used to search for language specific templates with {filename}.{locale}.{extension} or in conjunction with the Translation2 language translation toolkit, to set the language used to translate templates to at compile time.
default false - you can set this to an array or an existing Translation2 object eg. Translation2 => array('driver'=>'dataobjectsimple', options=>array()));
default false - By default warnings about undefined variabes are hidden, this turns on all PHP warnings during the outputObject calls. Can be usefull for finding bugs hidden by method callbacks.
default constant HTML_TEMPLATE_FLEXY_ERROR_DIE - this determines the behaviour when compiling a template fails, normally flexy will die and report the error to the screen, you can change this to HTML_TEMPLATE_FLEXY_ERROR_RETURN, if you want to recieve a PEAR_Error object from compile().
loads plugin classes, (by default from the Plugin folder), these can be used either via {plugin.nameofmethod} or as a modifier {outputstring:dateformat}, default formats are normally collected via configuration options plugin.dateformat, plugin.numberformat.decimals, plugin.numberformat.point, plugin.numberformat.thousands
The Object Constructor accepts options as it's arguments. Normally, you do not need to provide any options, as they are set by the PEAR::getStaticPropery(), as described in the configuration.
If neccessary it will convert the Template markup into PHP code, and writes it to the compiledTemplate directory adding the {locale}.php to the end of the filename. The Template is only compiled if
No compiled file exists
The file modification date of the template is greater than the compiled one
The forceCompile Flag was set in config or when you created the template object.
It is not normally neccesary to set the forceCompile flag, unles you are working on the engine it'self.
string $template - Used in conjuction with the config variable 'templateDir' to locate the template to compile into PHP code.
string - the location of the compiled file (which could be used with include) - although it is recommended to use the outputObject methods.
Пример 42-1. Compiling multiple files.
|
Пример 42-2. Master template example
|
Пример 42-3. Simple ouput example
|
This makes the values of the supplied object (and optionally loads the HTML_Template_Flexy_Elements) available to the template when it is run.
object $controllerObject - The object you want to use with the template, the values of the object will relate to the $controllerObject->tag will map to {tag} on the template
array $elements - This is an associative array of form, or dynamic elements names (or id's) which will be merged with the one defined in the template.
Пример 42-1. PHP code initiating the template, and outputing it
|
Пример 42-2. The Template with some tags
|
Пример 42-3. Resulting output
|
This maps the values of the supplied object and runs the compiled template, and returns the result.
This can be used in conjuction with PEAR::Cache, or in the example below, with a email template (note this still needs testing.. - the backend should eventually support a native tokenizer for email templates.)
object $controllerObject - The object you want to use with the template, the values of the object will relate to the $controllerObject->tag will map to {tag} on the template
array $elements - This is an associative array of form, or dynamic elements names (or id's) which will be merged with the one defined in the template.
Пример 42-1. Person DataObject send_password method
|
Пример 42-2. An email template (using the Regex Parser - hence the {t.*})
|
Пример 42-3. The resulting email head and body
|
All Form elements, FORM, INPUT, SELECT and any HTML tag that includes the attribute flexy:dynamic Is converted into HTML_Template_Flexy_Element's and stored serialized in the same folder as the Compiled flexy template.
You can use this array to make changes to these elements or find out what form elements exist on a page.
Note: you should put the modified result as the $elements argument of >outputObject(), you do not however have to fetch the elements to assign them, you can just create blank elements, and merge them.
array - of Elements contained within the template. (or an empty array if no form/dynamic elements are used)
Пример 42-1. Introspecting a template
|
Пример 42-2. template example
|
Пример 42-3. template compiled
|
Пример 42-4. output from the Introspection
|
Flexy uses a single lightweight class to represent All HTML Tags, All the variables of the class are public, and you are encouraged to use them. And the methods provide generic assignment and conversion abilities.
To force th toHtml() method to generate XHTML, rather than standard HTML, use $element->setAttribute('flexy:xhtml','yes'); or add flexy:xhtml="true" to the attribute of the element in the template.
$tag - The name of the HTML Tag eg. img for <img ....
$attributes - Associative array of attributes, where key="value" is output when you turn it in toHtml(), If you need to represent a attribute without a value, use TRUE as the value. This also accepts a string in the format "href='/test.jpg' alt='test'", which will be parsed into the attributes array of the object.
The name of the html element eg. img for <img...
Attributes for the element
All the sub elements inside this, can be any object that implements toHtml(), or a string.
this value of thiswill be output when toHtml() is called, rather than the tags.
string or object that implements toHtml() method, and is returned by toHtml() before the tag HTML
string or object that implements toHtml() method, and is returned by toHtml() after the tag HTML
when you create an element, that is to be merged later with a full definition, you can assign the value here, and during toHtml(), the toValue() method will be called and select options, checkboxes and input values will be correctly filled in.
Пример 42-1. Using an element to change a template.
|
Пример 42-2. template example
|
Пример 42-3. output from the Template
|
This is used to set the values of form elements, results depend on the type of element
text,password inputs, buttons Fills in the value attribute
checkboxs / radio buttons adds a checked tag to the matching element
textarea fills in the text area content
checkbox with arrays adds checked to the matching elements
selects adds selected to the
$value The value to assign a form element, (use arrays for multiple selects or checkbox groups)
$array the options to appear.
$noValue dont use the keys from the array sent as the value= part of the option tag.
use this to remove attributes from the tag when the element is rendered, It may be easier to access the attributes array directly and assign the value to false.
Can be used to set attribute values, It is easier to set the attributes directly using the public attributes property.
returns the HTML to represent the object. If you wish to implement your own element, you only need to implement this method, and assign it to the element array..
Used by the template to represent form tags, which only the opening tag are rendered dynamically (so, all tags inside the tag are not forced to be dynamic).
this probably needs more thought.. - it would probably need to merge the full tag info with types, to be usefull..
$ar = HTML_Element_Factory::freeze($ar);
creates PHP code to echo a variable, with optional modifier. Modifiers are
No Modifier - does htmlspecialchars($variable)
:h - echos without any change - eg. raw
:u - echos urlencode($variable)
by default variables are assumed to have calling scope, and are prefixed with $t->, however if they are inside a loop (foreach), then the variables created by the loop are added to the scope and the prefix is not added.
Пример 42-1. setting an object variable
|
Пример 42-2. Outputting the variable
|
Пример 42-3. Compiled template
|
Пример 42-4. Simple ouput example
|
creates an PHP method call, any with any number of arguments, as variables or literals (quoted in #). the return value is echoed, and passed by a modifier (like variables)
No Modifier - does htmlspecialchars($variable)
:h - echos without any change - eg. raw
:u - echos urlencode($variable)
Пример 42-1. Including another template
|
Пример 42-2. Calling includeBody in template, and ucfirst
|
Пример 42-3. Compiled template
|
Пример 42-4. Output from the code
|
creates a foreach loop, needs an {end:} tag. note that the engine will add the variable to the scope, so they will not be prefixed with $t-> when used inside the loop.
string variable - relates to $object->variable
string key - creates a variable 'key' in the current scope.
string value - optionally creates a variable 'value' in the current scope. (as in $key=>$value)
Пример 42-1. Setting variables for foreach
|
Пример 42-2. Foreach in template
|
Пример 42-3. Compiled template
|
Пример 42-4. example output
|
creates an if statement, with the argument as a variable or method. You must close an if statement with an {end:} statement, and you may use {else:} with it.
Пример 42-1. Setting variables for if
|
Пример 42-2. The template
|
Пример 42-3. Compiled template
|
Пример 42-4. The output
|
adds a closing brace in PHP so that blocks of conditional HTML are shown correctly. You do not need to use {end:} tags if you are using HTML tag attributes like IF="a,b", as the closing HTML tag will indicate that.
Пример 42-1. Setting variables for if
|
Пример 42-2. The template
|
Пример 42-3. The compiled template
|
Пример 42-4. The output
|
Пример 42-1. Setting variables for if
|
Пример 42-2. Else in template
|
Пример 42-3. Compiled template
|
By default, all forms are converted to HTML_Template_Flexy_Elements, so they can be altered at runtime.
Пример 42-1. Using an element to change a template.
|
Пример 42-2. template example
|
Пример 42-3. output from the Template
|
fills in the form with values based on the form name and the tag name. If flexyignore is used, it is left alone (or if the body or form has a flexyignore tag it will be left alone).
Пример 42-1. Using an element to change a template.
|
Пример 42-2. template example
|
Пример 42-3. compiled template
|
Пример 42-4. output from the Template
|
fills in the form with values based on the form name and the tag name. If flexyignore is used, it is left alone (or if the body or form has a flexyignore tag it will be left alone).
Пример 42-1. Using an element to change a template.
|
Пример 42-2. template example
|
Пример 42-3. compiled template
|
Пример 42-4. output from the Template
|
fills in the select values based on the form name and the tag name and adds code to check if the object variable matches them. If flexyignore is used, it is left alone. If static is set, the currently defined options will be used.
Пример 42-1. Using an element to change a template.
|
Пример 42-2. template example
|
Пример 42-3. compiled template
|
Пример 42-4. output from the Template
|
string variable - relates to $object->variable
string method - relates to $object->method()
string object.method relates to $object->object->method()
Пример 42-1. Setting variables for foreach
|
Пример 42-2. flexy:if in template
|
Пример 42-3. Compiled template
|
Пример 42-4. Simple ouput example
|
string variable - relates to $object->variable
string key - creates a variable 'key' in the current scope.
string value - optionally creates a variable 'value' in the current scope. (as in $key=>$value)
Пример 42-1. Setting variables for foreach
|
Пример 42-2. Foreach in template
|
Пример 42-3. Compiled template
|
Пример 42-4. Simple ouput example
|
Tells the generator to start outputing using this tag. This can be useful if you want to edit the template in a editor that expects a head/footer, and you can list the available tags in the comments at the top of the page.
The actual value of the tag is not relivant.
Пример 42-1. Template with flexy:start
|
Пример 42-2. Compiled template
|
Tells the generator to start outputing using the children of this tag. This can be useful if you want to edit the template in a editor that expects a head/footer, normally adding this to body
The actual value of the tag is not relivant.
Пример 42-1. Template with flexystartchildren
|
Пример 42-2. Compiled template
|
Tells the generator not to replace form elements with PHP code. Can be used with a Form Tag, or individual elements.
Пример 42-1. Template with flexy:ignore
|
Пример 42-2. Compiled template
|
If you have a form with multiple input boxes (eg. group members), which are dynamically generated, then this attribute can be used to generate flexy elements based on sprintf'ing the variable value into the name attribute value.
Пример 42-1. Template with flexy:ignore
|
Пример 42-2. Backend Code Snippet
|
Пример 42-3. Compiled template
|
Пример 42-4. Resulting Output
|
To reduce the "WTF" effect of magically having javascript code that looks like flexy tags completely broken by the template engine, Flexy deliberately turns the parser OFF when dealing with script contents (see Configuration Options for details of PHP in script tags)
As a result of this, it is not possible to put any flexy tags within blocks of javascript code. the flexy:tojavascript tag solves this in a way that enables javascript to be tested seperatly from the application, and also serves to encourage better coding practices. (eg. seperating your code with distinct lines of communication)
This feature depends on PEAR's HTML_Javascript Library
Пример 42-1. A template with javascript and flexy:tojavasscript
|
Пример 42-2. compiled template
|
Пример 42-3. output from the Template (with no values set)
|
A template consists of text and special labeled blocks and placeholders. The content of blocks can be re-used and parsed multiple times with different placeholder values.
Пример 42-1. A typical template
|
Placeholders can be defined in templates and are filled from PHP code with content. The format of placeholder up to version (1.1.x) is
{[0-9A-Za-z_-]+} |
Since version 1.2.x dots are allowed, too.
{[\.0-9A-Za-z_-]+} |
This means, the name of the placeholder can consist of upper- and lowercase letters, underscores and hypens. The name must be placed between curly brackets without any spaces. Valid names are i.e.:
{Placeholder} |
{place2_holder} |
{PLACEHOLDER1} |
{Place-Holder} |
Valid names since version 1.2.x
{Place.Holder} |
Non-valid names are i.e.
{ Placeholder 3 } (spaces) |
{place*holder} (char isn't permitted) |
The format of a block is
<!-- BEGIN [0-9A-Za-z_-]+ --> ... block content ... <!-- END [0-9A-Za-z_-]+ --> |
Since version 1.2.x dots are allowed in block definitions
<!-- BEGIN [\.0-9A-Za-z_-]+ --> ... block content ... <!-- END [\.0-9A-Za-z_-]+ --> |
The rules for the block name are the same like for placeholders. In contrast to placeholders the spaces in the block markup are required.
The nesting of blocks is permitted, but be careful while parsing. You have to set and parse the deepest inner block first and then set and parse from inner to outer.
In IT the whole template file itself is nested in a meta block called "__global__". Most block-related functions use this block name as default.
Пример 42-2. The template
|
Пример 42-3. The script
|
Пример 42-4. The output
|
Constructor. Create a new instance of HTML_Template_IT and sets the search path for templates.
Таблица 42-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
IT_BLOCK_NOT_FOUND | " Cannot find this block block " | The given block does not exists. | Check for typing mistakes in the argument. |
Gets an array of all global variables in the variable cache. Only variables that are filled using HTML_Template_IT::setVariable() are returned. The returned has two values. The first values holds an array with the names of the global variables, the second value holds an array with all the values.
array - An array. The key 0 holds an array with the names of all filled variables, the key 1 holds an array with names of the according values.
Пример 42-1. Script
|
Пример 42-2. The output
|
string $filename - file to load
boolean $removeUnknownVariables - if TRUE, not substituted placeholders in a block will be removed
boolean $removeEmptyBlocks - if TRUE, not touched blocks will be removed. Blocks can be touched with HTML_Template_IT::touchBlock().
Пример 42-1. Templatefile main.tpl.htm
Script with $removeUnknownVariables = FALSE
Output
Script with $removeUnknownVariables = TRUE
Output
|
Parses the defined block, performs all substitutions and appends the result to already parsed blocks.
string $block - block to parse. When not set the complete template is used.
boolean $flag_recursion - Used internally. Can be ignored
boolean - Returns TRUE if there was no placeholder to substitute, otherwise FALSE or IT_Error.
Пример 42-1. The template cvsnames.tpl.htm
|
Пример 42-2. The script
|
Таблица 42-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
IT_BLOCK_NOT_FOUND | " Cannot find this block block " | The given block does not exists. | Check for typing mistakes in the argument. |
Parses the current block. The current block can be set with HTML_Template_IT::setCurrentBlock().
boolean - Returns TRUE if there was no placeholder to substitute, otherwise FALSE or IT_Error.
Пример 42-1. The template cvsnames.tpl.htm
|
Пример 42-2. Script
|
Таблица 42-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
IT_BLOCK_NOT_FOUND | " Cannot find this block block " | The given block does not exists. | Check for typing mistakes in the argument. |
Sets the name of the current block, where placeholder should be substituted. The current block can be parsed with HTML_Template_IT::parseCurrentTemplate().
boolean - TRUE, if found and succcessful set, otherwise IT_Error will be returned.
Таблица 42-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
IT_BLOCK_NOT_FOUND | " Cannot find this block block " | The given block does not exists. | Check for typing mistakes in the argument. |
Sets the path to the template directory where HTML_Template_IT::loadTemplatefile() searches for templates. Every filename is prefixed with the given string.
Пример 42-1. Directorytree.
|
Пример 42-2. script - testscript.php
|
Sets an option. Please notice that changing some option might result in an unexpected behaviour of HTML_Template_IT.
Таблица 42-1. Possible options:
Option | Default value | Description |
---|---|---|
removeUnknownVariables | TRUE | If TRUE all template variables, which are not filled, are removed while parsing. This option is usually set by calling HTML_Template_IT::loadTemplatefile() or HTML_Template_IT::setTemplate(). |
removeEmptyBlocks | TRUE | If TRUE all blocks not containing any filled template variables are removed. This option is usually set by calling HTML_Template_IT::loadTemplatefile() or HTML_Template_IT::setTemplate(). |
clearCache | FALSE | If TRUE parsed blocks are not cached. If you don't know exactly what you do, just leave the default value. |
clearCacheOnParse | FALSE | If TRUE the variable cache will be cleaned after parsing. If you don't know exactly what you do, just leave the default value. |
openingDelimiter | '{' | Defines the character, every template variable has to start with. If you change this value, you have to call init() to reinitialise the template. If you don't know exactly what you do, just leave the default value. |
closingDelimiter | '}' | Defines the character, every template variable has to end with. If you change this value, you have to call init() to reinitialise the template. If you don't know exactly what you do, just leave the default value. |
blocknameRegExp | '[\.0-9A-Za-z_-]+' | The regular expression, thats used to parse block names. If you change this value, you have to call init() to reinitialise the template. If you don't know exactly what you do, just leave the default value. |
variablenameRegExp | '[\.0-9A-Za-z_-]+' | The regular expression, thats used to parse template variable names. If you change this value, you have to call init() to reinitialise the template. If you don't know exactly what you do, just leave the default value. |
Loads template from a string and controls the behavior in case of unused variables and blocks
string $template - The content of the template.
boolean $removeUnknowVariables - if TRUE, not substituted placeholders in a block will be removed
boolean $removeEmptyBlocks - if TRUE, not touched blocks will be removed
Пример 42-1. Script
|
Set the value of a variable in the current template block. If $placeholder is an array the key of an element is treated as a placeholder name while the value is treated as it's substitution.
mixed $placeholder - name of the placeholder to substitute or a array with the placeholder as key and the data to assign as value.
mixed $variable - if $placeholder is not a array, the value to assign to the placeholder.
Пример 42-1. Template - cvsnames.tpl.htm
|
Пример 42-2. Script
|
Таблица 42-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
IT_BLOCK_NOT_FOUND | " Cannot find this block block " | The given block does not exists. | Check for typing mistakes in the argument. |
Preserves an empty template block, even if $removeEmptyBlocks is TRUE and no substition of placeholders took place.
Пример 42-1. Template - login.tpl.htm
|
Пример 42-2. Script
|
Таблица 42-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
IT_BLOCK_NOT_FOUND | " Cannot find this block block " | The given block does not exists. | Check for typing mistakes in the argument. |
HTML_Template_Sigma: implementation of Integrated Templates API with template 'compilation' added.
Class Trees for HTML_Template_Sigma()
HTML_Template_Sigma
The default format of placeholder is
{[0-9A-Za-z_-]+} |
Actual values for the placeholders are set using setVariable() and setGlobalVariable() methods. Placeholders for which no values were set are removed from output by default.
The format of a block is
<!-- BEGIN [0-9A-Za-z_-]+ --> ... block content ... <!-- END [0-9A-Za-z_-]+ --> |
The nesting of blocks is permitted, but be careful while parsing. You have to parse() the innermost block first and then go from inner to outer.
In Sigma the whole template itself is treated as a virtual block called "__global__". Most block-related functions use this block name as default.
It is possible to include a template file from within another template file using an <!-- INCLUDE filename --> statement:
... some content ... <!-- INCLUDE filename.html --> ... some more content ... |
Some things to note:
Although this functionality is implemented using addBlockfile(), unlike addBlockfile() no new blocks are created in the template.
<!-- INCLUDE --> calls are processed before any variable substitution can take place. So <!-- INCLUDE {placeholder} --> will not work unless you actually have a file named {placeholder} and want to load it.
Sigma templates can contain simple function calls. This means that the author of the template can add a special placeholder to it
... some content ... func_h1("embedded in h1") ... some more content ... |
Format of such function name is as follows
func_[_a-zA-Z]+[A-Za-z_0-9]* |
func_translate('Hello, {username}') |
Замечание: The information in this section applies to HTML_Template_Sigma version 1.1.2 and later, please upgrade if you have problems with template function arguments in previous versions.
Quoting of function arguments is not mandatory, the following is a perfectly valid template function:
func_uppercase(Some unquoted text) |
The next thing to consider is that HTML_Template_Sigma is mostly targeted for generating HTML. Therefore a quoted string within an argument is most probably a tag attribute. The contents of such strings are not parsed for commas and parentheses. Therefore the following is also a perfectly valid template function:
func_foo(<a href="javascript:foo(bar, baz)">Do foo</a>) |
Finally, the argument should be quoted if it is an empty string or if its leading or trailing whitespace is significant (leading and trailing whitespace will be removed from unquoted arguments).
The arguments can be quoted using either single or double quotes. If an argument contains a quote of the same type, then it should be escaped using the backslash symbol '\'. The backslash symbol itself should also be escaped,
func_foo('O\'really') func_foo('AC\\DC') |
Пример 42-1. Valid and invalid template function arguments
|
Since release 1.1.0, instead of using
func_callback({var}) |
{var:callback} |
'h' for htmlspecialchars()
'u' for urlencode()
'j' for a method of Sigma that escapes the string for usage in Javascript string constants.
Thus, if you add {var:h} placeholder to the template, var will be have unsafe characters replaced by corresponding HTML entitites.
Other usage examples: There are several usage examples in the package archive that cover most of its functionality. You are encouraged to review them along with the docs.
Пример 42-2. The table.html template file
|
Пример 42-3. The table_header.html template file
|
Пример 42-4. The script
|
Пример 42-5. The output
|
This is the way to bypass RegExp parsing on template load. Instead of parsing the original template on every request, we keep its internal representation (a serialized array, essentially) and load it instead.
Think about template compilation in Smarty. Only Sigma does not compile templates to PHP code.
No data caching is taking place. If you want to do this, consider using some of the PEAR's cache packages.
No. Cached version is considered valid until the source template changes.
Caching is completely transparent. To take advantage of this feature you only have to either pass a second parameter to the constructor or call a setCacheRoot() method later.
<?php require_once 'HTML/Template/Sigma.php'; $tpl =& new HTML_Template_Sigma('./templates', './templates/prepared'); $tpl->loadTemplateFile('default.html'); // go on ?> |
For each distinct template file in ./templates loaded with either loadTemplatefile(), addBlockfile(), replaceBlockfile() or <!-- INCLUDE --> a prepared version will be generated in ./templates/prepared.
Constructor: builds some complex regular expressions and optionally sets the root directories.
Make sure that you call this constructor if you derive your template class from this one.
root directory for templates
directory to cache "prepared" templates in
Adds a block to the template changing a variable placeholder to a block placeholder. This means that a new block will be integrated into the template in place of a variable placeholder. The variable placeholder will be removed and the new block will behave in the same way as if it was inside the original template.
The block content must not start with <!-- BEGIN blockname --> and end with <!-- END blockname -->, if it does the error will be thrown.
name of the variable placeholder, the name must be unique within the template.
name of the block to be added
content of the block
Таблица 42-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
SIGMA_BLOCK_EXISTS | Block '$block' already exists | Tried to add a block with a name that is already present in the template | Choose a different name for a new block |
SIGMA_PLACEHOLDER_NOT_FOUND | Variable placeholder '$placeholder' not found | There is no placeholder to replace by a new block in the template | Check the spelling of the placeholder name |
SIGMA_PLACEHOLDER_DUPLICATE | Placeholder '$placeholder' should be unique, found in multiple blocks | A placeholder to be replaced by a new block should appear only in one place | Check the spelling of the placeholder name, choose a different placeholder |
SIGMA_BLOCK_DUPLICATE | The name of a block must be unique within a template. Block 'blockname' found twice. | The added block contains a subblock that has the same name as the existing one | Check the $template and rename the block to something else |
SIGMA_CALLBACK_SYNTAX_ERROR | Cannot parse template function: (error description) | Bogus syntax for template function parameters. | Fix the template function definition, pay special attention to quoting rules. |
Adds a block taken from a file to the template, changing a variable placeholder to a block placeholder.
name of the variable placeholder
name of the block to be added
template file that contains the block
Таблица 42-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
SIGMA_BLOCK_EXISTS | Block '$block' already exists | Tried to add a block with a name that is already present in the template | Choose a different name for a new block |
SIGMA_PLACEHOLDER_NOT_FOUND | Variable placeholder '$placeholder' not found | There is no placeholder to replace by a new block in the template | Check the spelling of the placeholder name |
SIGMA_PLACEHOLDER_DUPLICATE | Placeholder '$placeholder' should be unique, found in multiple blocks | A placeholder to be replaced by a new block should appear only in one place | Check the spelling of the placeholder name, choose a different placeholder |
SIGMA_TPL_NOT_FOUND | Cannot read the template file '$filename' | File is unreadable for some reason | Check if the file exists and has correct permissions set |
SIGMA_CACHE_ERROR | Cannot save template file 'filename' | A prepared template file cannot be saved | Check if the directory for prepared templates cache exists and is writeable for your script |
SIGMA_BLOCK_DUPLICATE | The name of a block must be unique within a template. Block 'blockname' found twice. | The added file contains a block that has the same name as the existing one | Check the file and rename the block to something else |
SIGMA_CALLBACK_SYNTAX_ERROR | Cannot parse template function: (error description) | Bogus syntax for template function parameters. | Fix the template function definition, pay special attention to quoting rules. |
Global variables are not affected, only the ones set via setVariable(). The method is useful when you add a lot of variables via setVariable() and are not sure whether all of them appear in the block you parse(). If you clear the variables after parse(), you don't risk them suddenly showing up in other blocks.
Returns a textual error message for an error code. This is usually called when throwing a error, there is seldom need to call this method directly.
Returns a parsed block: block with all replacements done.
This method will automatically call parse(), only if called with $block='__global__' when '__global__' was not parse()'d before. In all other cases you should call parse() before calling get()
Таблица 42-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
SIGMA_BLOCK_NOT_FOUND | Cannot find block '$block' | There is no block $block in the template | Check the block name spelling, check whether you added all the necessary blocks to the template |
Returns a list of blocks within a template.
If $recursive is FALSE, it returns just a 'flat' array of $parent's direct subblocks. If $recursive is TRUE, it builds a tree of template blocks using $parent as root. Tree structure is compatible with PEAR::Tree's Memory_Array driver.
parent block name
whether to return a tree of child blocks (TRUE) or a 'flat' array (FALSE)
Таблица 42-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
SIGMA_BLOCK_NOT_FOUND | Cannot find block '$parent' | There is no block $parent in the template | Check the block name spelling, check whether you added all the necessary blocks to the template |
Returns a list of placeholders within a block.
Only 'normal' placeholders are in the list, not ones automatically created for blocks and template functions.
Таблица 42-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
SIGMA_BLOCK_NOT_FOUND | Cannot find block '$block' | There is no block $block in the template | Check the block name spelling, check whether you added all the necessary blocks to the template |
Hides the block even if it is not "empty".
Is somewhat an opposite to touchBlock().
Consider a block (a 'edit' link for example) that should be visible to registered/"special" users only, but its visibility is triggered by some little 'id' field passed in a large array into setVariable(). You can either carefully juggle your variables to prevent the block from appearing (a fragile solution) or simply call hideBlock()
Таблица 42-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
SIGMA_BLOCK_NOT_FOUND | Cannot find block '$block' | There is no block $block in the template | Check the block name spelling, check whether you added all the necessary blocks to the template |
Loads a template file. If caching is on, then it checks whether a "prepared" template exists. If it does, it gets loaded instead of the original, if it does not, then the original gets loaded and prepared and then the prepared version is saved. addBlockfile() and replaceBlockfile() implement quite the same logic.
filename
remove unknown/unused variables?
remove empty blocks?
Таблица 42-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
SIGMA_TPL_NOT_FOUND | Cannot read the template file '$filename' | File is unreadable for some reason | Check if the file exists and has correct permissions set |
SIGMA_CACHE_ERROR | Cannot save template file 'filename' | A prepared template file cannot be saved | Check if the directory for prepared templates cache exists and is writeable for your script |
SIGMA_BLOCK_DUPLICATE | The name of a block must be unique within a template. Block 'blockname' found twice. | The loaded file contains two blocks sharing the same name | Check the file and rename one of the the blocks to something else |
SIGMA_CALLBACK_SYNTAX_ERROR | Cannot parse template function: (error description) | Bogus syntax for template function parameters. | Fix the template function definition, pay special attention to quoting rules. |
see HTML_Template_Sigma::setTemplate(), HTML_Template_Sigma::$removeUnknownVariables, HTML_Template_Sigma::$removeEmptyBlocks
Parses the given block. It substitutes local and global variables appearing in the block and set via setVariable() and setGlobalVariable(), calls all the callback functions and recursively processes the subblocks of the block.
block name
TRUE if the function is called recursively (do not set this to TRUE yourself!)
TRUE if parsing a "hidden" block (do not set this to TRUE yourself!)
Таблица 42-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
SIGMA_BLOCK_NOT_FOUND | Cannot find block '$block' | There is no block $block in the template | Check the block name spelling, check whether you added all the necessary blocks to the template |
Checks whether the placeholder exists in the template, returns the name of the (first) block that contains the specified placeholder.
Name of the placeholder you're searching
Name of the block to scan. If left out (default) all blocks are scanned.
return Name of the (first) block that contains the specified placeholder. If the placeholder was not found an empty string is returned.
Таблица 42-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
SIGMA_BLOCK_NOT_FOUND | Cannot find block '$block' | There is no block $block in the template | Check the block name spelling, check whether you added all the necessary blocks to the template |
Replaces an existing block with new content. This function will replace a block of the template and all blocks contained in it and add a new block instead. This means you can dynamically change your template.
Sigma analyses the way you've nested blocks and knows which block belongs into another block. This nesting information helps to make the API short and simple. Replacing blocks does not only mean that Sigma has to update the nesting information (relatively time consuming task) but you have to make sure that you do not get confused due to the template change yourself.
name of a block to replace
new content
TRUE if the parsed contents of the block should be kept
Таблица 42-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
SIGMA_BLOCK_NOT_FOUND | Cannot find block '$block' | There is no block $block in the template | Check the block name spelling, check whether you added all the necessary blocks to the template |
SIGMA_BLOCK_DUPLICATE | The name of a block must be unique within a template. Block 'blockname' found twice. | The new block contains a subblock that has the same name as the existing one | Check the $template and rename the block to something else |
SIGMA_CALLBACK_SYNTAX_ERROR | Cannot parse template function: (error description) | Bogus syntax for template function parameters. | Fix the template function definition, pay special attention to quoting rules. |
name of a block to replace
template file that contains the block
TRUE if the parsed contents of the block should be kept
Таблица 42-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
SIGMA_BLOCK_NOT_FOUND | Cannot find block '$block' | There is no block $block in the template | Check the block name spelling, check whether you added all the necessary blocks to the template |
SIGMA_BLOCK_DUPLICATE | The name of a block must be unique within a template. Block 'blockname' found twice. | The loaded block contains a subblock that has the same name as the existing one | Check the file contents and rename the block to something else |
SIGMA_TPL_NOT_FOUND | Cannot read the template file '$filename' | File is unreadable for some reason | Check if the file exists and has correct permissions set |
SIGMA_CACHE_ERROR | Cannot save template file 'filename' | A prepared template file cannot be saved | Check if the directory for prepared templates cache exists and is writeable for your script |
SIGMA_CALLBACK_SYNTAX_ERROR | Cannot parse template function: (error description) | Bogus syntax for template function parameters. | Fix the template function definition, pay special attention to quoting rules. |
Sets the directory to cache "prepared" templates in, the directory should be writable for PHP.
The "prepared" template contains an internal representation of template structure: essentially a serialized array of $_blocks, $_blockVariables, $_children and $_functions, may also contain $_triggers. This allows to bypass expensive calls to HTML_Template_Sigma::_buildBlockVariables() and especially HTML_Template_Sigma::_buildBlocks() when reading the "prepared" template instead of the "source" one.
The files in this cache do not have any TTL and are regenerated when the source templates change.
Sets a callback function. Sigma templates can contain simple function calls. This means that the author of the template can add a special placeholder to it: func_h1("embedded in h1") Sigma will parse the template for these placeholders and will allow you to define a callback function for them. Callback will be called automatically when the block containing such function call is parse()'d.
Please note that arguments to these template functions can contain variable placeholders: func_translate('Hello, {username}'), but not blocks or other function calls.
This should NOT be used to add logic (except some presentation one) to the template. If you use a lot of such callbacks and implement business logic through them, then you're reinventing the wheel. Consider using XML/XSLT, native PHP or some other template engine.
Script:
<?php function h_one($arg) { return '<h1>' . $arg . '</h1>'; } // ... $tpl = new HTML_Template_Sigma(' ... '); // ... $tpl->setCallbackFunction('h1', 'h_one'); // ... $tpl->show() ?> |
... func_h1('H1 Headline') ... |
Function name in the template
A callback: anything that can be passed to call_user_func_array()
If TRUE, then no variable substitution in arguments will take place before function call
Таблица 42-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
SIGMA_INVALID_CALLBACK | Callback does not exist | The $callback is not an existing function or method | Check spelling, check whether the object was correctly instantiated if using the method callback |
Таблица 42-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
SIGMA_BLOCK_NOT_FOUND | Cannot find block '$block' | There is no block $block in the template | Check the block name spelling, check whether you added all the necessary blocks to the template |
Sets a global variable value. Global variables are "special": they do not get cleared after substitution and do not make blocks not empty if substituted.
variable name or array ('varname'=>'value')
variable value if $variable is not an array
Sets the option for the template class. Currently it understands the following options:
If set to TRUE, then do not substitute variables and remove unused placeholders in data added through setVariable() and setGlobalVariable(). See also bugs #20199 and #21951. Default is FALSE, for performance reasons.
Whether to trim extra whitespace from template on cache save. Generally safe to have this on, unless you have <pre></pre> in templates or want to preserve HTML indentantion. Default is TRUE
Таблица 42-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
SIGMA_UNKNOWN_OPTION | Unknown option '$option' | $option is not known to Sigma | Check the option name spelling |
Sets the file root for templates. The file root gets prefixed to all filenames passed to the object.
Sets the template. You can either load a template file from disk with loadTemplateFile() or set the template manually using this function.
template content
remove unknown/unused variables?
remove empty blocks?
Таблица 42-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
SIGMA_BLOCK_DUPLICATE | The name of a block must be unique within a template. Block 'blockname' found twice. | The $template contains two blocks sharing the same name | Check the $template and rename one of the the blocks to something else |
SIGMA_CALLBACK_SYNTAX_ERROR | Cannot parse template function: (error description) | Bogus syntax for template function parameters. | Fix the template function definition, pay special attention to quoting rules. |
Sets a variable value. The function can be used either like setVariable("varname", "value") or with one array $variables["varname"] = "value" given setVariable($variables)
variable name or array ('varname'=>'value')
variable value if $variable is not an array
Sometimes you have blocks that should be preserved although they are empty (no placeholder replaced). Think of a shopping basket. If it's empty you have to show a message to the user. If it's filled you have to show the contents of the shopping basket. Now where to place the message that the basket is empty? It's not a good idea to place it in you application as customers tend to like unecessary minor text changes. Having another template file for an empty basket means that one fine day the filled and empty basket templates will have different layouts.
So blocks that do not contain any placeholders but only messages like "Your shopping basked is empty" are intoduced. Now if there is no replacement done in such a block the block will be recognized as "empty" and by default ($removeEmptyBlocks = true) be stripped off. To avoid this you can call touchBlock()
Таблица 42-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
SIGMA_BLOCK_NOT_FOUND | Cannot find block '$block' | There is no block $block in the template | Check the block name spelling, check whether you added all the necessary blocks to the template |
The template engine is a compiling engine, all templates are compiled into PHP-files. This will make the delivery of the files faster on the next request, since the template doesn't need to be compiled again. If the template changes it will be recompiled. There is no new template language to learn. Beside the default mode, there is a set of constructs since version 1.6 which allow you to edit your templates with WYSIWYG editors
The template engine is a compiling engine, all templates are compiled into PHP-files. This will make the delivery of the files faster on the next request, since the template doesn't need to be compiled again. If the template changes it will be recompiled. There is no new template language to learn. Beside the default mode, there is a set of constructs since version 1.6 which allow you to edit your templates with WYSIWYG editors. By default the template engine uses indention for building blocks (you can turn that off). This feature was inspired by Python and by the need I felt to force myself to write proper HTML-code, using proper indentions, to make the code better readable.
Unfortunately, complete documentation is not available at the moment.
Data paging class which also builds links to the pages.
Pager is a class to page an array of data. It is taken as input and it is paged according to various parameters. Pager also builds links within a specified range, and allows complete customization of the output (it even works with mod_rewrite). It is compatible with Pager v.1.x and Pager_Sliding API
This simple example will page the array of alphabetical letters, giving back pages with 3 letters per page, and links to the previous two / next two pages:
require_once 'Pager.php'; $params = array( 'mode' => 'Jumping', 'perPage' => 3, 'delta' => 2, 'itemData' => array('a','b','c','d','e',[...omissis...],'z') ); $pager = & Pager::factory($params); $data = $pager->getPageData(); $links = $pager->getLinks(); //$links is an ordered+associative array with 'back'/'pages'/'next'/'first'/'last'/'all' links. //NB: $links['all'] is the same as $pager->links; //echo links to other pages: echo $links['all']; //Pager can also generate <link rel="first|prev|next|last"> tags echo $pager->linkTags; //Show data for current page: echo 'PAGED DATA: ' ; print_r($data); //Results from methods: echo 'getCurrentPageID()...: '; var_dump($pager->getCurrentPageID()); echo 'getNextPageID()......: '; var_dump($pager->getNextPageID()); echo 'getPreviousPageID()..: '; var_dump($pager->getPreviousPageID()); echo 'numItems()...........: '; var_dump($pager->numItems()); echo 'numPages()...........: '; var_dump($pager->numPages()); echo 'isFirstPage()........: '; var_dump($pager->isFirstPage()); echo 'isLastPage().........: '; var_dump($pager->isLastPage()); echo 'isLastPageComplete().: '; var_dump($pager->isLastPageComplete()); echo '$pager->range........: '; var_dump($pager->range); |
This example shows how you can use this class with mod_rewite. Let's suppose we have a .htaccess like this:
--------- RewriteEngine on #Options FollowSymlinks RewriteBase / RewriteRule ^articles/([a-z]{1,12})/art([0-9]{1,4})\.html$ /article.php?num=$2&month=$1 [L] --------- |
require_once 'Pager.php'; $month = 'september'; $params = array( 'mode' => 'Sliding', 'append' => false, 'urlVar' => 'num', 'path' => 'http://myserver.com/articles/' . $month, 'fileName' => 'art%d.html', //Pager replaces "%d" with page number... 'itemData' => array('a','b','c',[...omissis...],'z'), 'perPage' => 3 ); $pager = & Pager::factory($params); $data = $pager->getPageData(); echo $pager->links; echo 'Data for current page: '; print_r($data); |
Using more than one pager in a single page is as simple as using a different urlVar for each pager:
require_once 'Pager.php'; //first pager $params1 = array( 'perPage' => 3, 'urlVar' => pageID_articles, //1st identifier 'itemData' => $someArray ); $pager1 = & Pager::factory($params1); $data1 = $pager1->getPageData(); $links1 = $pager1->getLinks(); //second pager $params2 = array( 'perPage' => 8, 'urlVar' => pageID_news, //2nd identifier 'itemData' => $someOtherArray ); $pager2 = & Pager::factory($params2); $data2 = $pager2->getPageData(); $links2 = $pager2->getLinks(); |
If you want to paginate db resultsets, fetching them all into an array and passing it to Pager might not be the best option. You can still leverage Pager and have good performances using a wrapper. There is a sample wrapper for each one of the PEAR db abstraction systems in the /docs/examples/ dir of the package. You may use it as-is or customize it to your needs.
If you need to add some extra variables to the querystring, use the extraVars parameter:
$params = array( 'extraVars' => array( 'firstKey' => 'firstValue', 'secondKey' => 'secondValue', //... ), //... ); $pager1 = & Pager::factory($params); |
Since version 2.2.1, Pager works with PHP 5 too, but you must use the factory() method instead of the constructor (which is deprecated):
require_once 'Pager.php'; //wrong: //$pager =& new Pager($params); //right $pager =& Pager::factory($params); //continue as you did before |
If you are using a previous revision and cannot update, you must write the following code on PHP 5:
//chose your preferred mode [Jumping | Sliding]: //require_once 'Pager/Jumping.php'; require_once 'Pager/Sliding.php'; //$pager =& new Pager_Jumping($params); $pager =& new Pager_Sliding($params); //continue as you did before |
There are some other online resources with in-depth coverage of what Pager can do: PEAR::Pager tutorials.
Let's suppose that the data spans on 15 pages, and the window width is 5 page links. The links are built on "frames" of 5 pages each: [1-5] [6-10] [11-15] Pager in "Jumping" mode always shows the same 5 page links while you are on one of these pages. Here's a temporal succession of the links, starting from page 1 and moving forward. There are brakets around current page number to highlight this:
a) {1} 2 3 4 5 => // first frame: [1-5] b) <= 1 {2} 3 4 5 => c) <= 1 2 {3} 4 5 => d) <= 1 2 3 {4} 5 => e) <= 1 2 3 4 {5} => // HERE IT JUMPS TO THE NEXT FRAME f) <= {6} 7 8 9 10 => // second frame: [6-10] g) <= 6 {7} 8 9 10 => h) <= 6 7 {8} 9 10 => |
Instead of jumping from one frame to the other, with Pager in "Sliding" mode the change is done smoothly, and the current page is always shown at the center of the "window" (except of course for the first and the last pages):
a) {1} 2 3 4 5 => [15] b) [1] <= 1 {2} 3 4 5 => [15] c) [1] <= 1 2 {3} 4 5 => [15] // HERE IT's STARTING WORKING AS DESIGNED d) [1] <= 2 3 {4} 5 6 => [15] // see: current page number is at the center of the window e) [1] <= 3 4 {5} 6 7 => [15] // and it stays there... f) [1] <= 4 5 {6} 7 8 => [15] g) [1] <= 5 6 {7} 8 9 => [15] h) [1] <= 6 7 {8} 9 10 => [15] |
Apart from the different "philosophy", there is one difference in the delta parameter: in "Jumping" mode, it's the number of page numbers to show; in "Sliding" mode it's the number of page numbers to show before and after the current one.
Pager::factory() method takes an associative array of parameters as input values. This is the complete list of these options:
itemData [array]
Array of items to page.
totalItems [integer]
Number of items to page (used only if itemData is not provided).
perPage [integer]
Number of items to display on each page.
delta [integer]
Number of page numbers to display before and after the current one.
mode [string]
"Jumping" or "Sliding" -window - It determines pager behaviour.
httpMethod [string]
Specifies the HTTP method to use. Valid values are 'GET' or 'POST'.
formID [string]
Specifies which HTML form to use in POST mode.
importQuery [boolean]
if true (default behaviour), variables and values are imported from the submitted data (query string) and used in the generated links, otherwise they're ignored completely
currentPage [integer]
Initial page number (if you want to show page #2 by default, set currentPage to 2)
expanded [boolean]
if TRUE, window size is always 2*delta+1
linkClass [string]
Name of CSS class used for link styling.
urlVar [string]
Name of URL var used to indicate the page number. Default value is "pageID".
path [string]
Complete path to the page (without the page name).
fileName [string]
name of the page, with a "%d" if append == TRUE.
fixFileName [boolean]
If set to FALSE, the fileName option is not overridden. Use at your own risk.
append [boolean]
If TRUE pageID is appended as GET value to the URL. If FALSE it is embedded in the URL according to fileName specs.
altFirst [string]
Alt text to display on the link of the first page. Default value is "first page"; if you want a string with the page number, use "%d" as a placeholder (for instance "page %d")
altPrev [string]
Alt text to display on the link of the previous page. Default value is "previous page";
altNext [string]
Alt text to display on the link of the next page. Default value is "next page";
altLast [string]
Alt text to display on the link of the last page. Default value is "last page"; if you want a string with the page number, use "%d" as a placeholder (for instance "page %d")
altPage [string]
Alt text to display before the page number. Default value is "page ".
prevImg [string]
Something to display instead of "<<". It can be text such as "<< PREV" or an <img/> as well.
nextImg [string]
Something to display instead of ">>". It can be text such as "NEXT >>" or an <img/> as well.
separator [string]
What to use to separate numbers. It can be an <img/>, a comma, an hyphen, or whatever.
spacesBeforeSeparator [integer]
Number of spaces before the separator.
spacesAfterSeparator [integer]
Number of spaces after the separator.
curPageLinkClassName [string]
CSS class name for the current page link.
curPageSpanPre [string]
Text before the current page link.
curPageSpanPost [string]
Text after the current page link.
firstPagePre [string]
String used before the first page number. It can be an <img/>, a "{", an empty string, or whatever.
firstPageText [string]
String used in place of the first page number.
firstPagePost [string]
String used after the first page number. It can be an <img/>, a "}", an empty string, or whatever.
lastPagePre [string]
Similar to firstPagePre, but used for last page number.
lastPageText [string]
Similar to firstPageText, but used for last page number.
lastPagePost [string]
Similar to firstPagePost, but used for last page number.
clearIfVoid [boolean]
if there's only one page, don't display pager links (returns an empty string).
extraVars [array]
additional URL vars to be added to the querystring.
excludeVars [array]
URL vars to be excluded from the querystring.
useSessions [boolean]
if TRUE, number of items to display per page is stored in the $_SESSION[$_sessionVar] var.
closeSession [boolean]
if TRUE, the session is closed just after R/W.
sessionVar [string]
Name of the session var for perPage value. A value different from default can be useful when using more than one Pager istance in the page.
showAllText [string]
Text to be used for the 'show all' option in the select box generated by getPerPageSelectBox()
pearErrorMode [constant]
PEAR_ERROR mode for raiseError(). Default is PEAR_ERROR_RETURN.
fileName IF append==FALSE (default is TRUE)
itemData OR totalItems (if itemData is set, totalItems is overwritten)
integer $index - an associative array of options. See Pager::factory() for the full list of options.
If you want to change an option after the Pager object has been constructed, after the call to setOptions() you have to generate or refresh the links and paged data with this method.
integer $pageID - Optional pageID. If specified, linksfor that page are provided instead of current one.
return back/pages/next/first/last/all links, both as numeric and associative array.
If current page is last page this function returns FALSE, otherwise returns next page number.
Returns offsets for given pageID. Eg, if you pass it pageID one and your perPage limit is 10 it will return (1, 10). pageID=2 would give you (11, 20).
if the method is called without parameter, pageID is set to currentPage
Given a PageId, it returns the limits of the range of pages displayed. While getOffsetByPageId() returns the offset of the data within the current page, this method returns the offsets of the page numbers interval.
E.g., in "Jumping" mode, if you have pageId=3 and delta=10, it will return (1, 10). pageID=8 would give you (1, 10) as well, because 1 <= 8 <= 10. pageID=11 would give you (11, 20).
In "Sliding" mode, if you have pageId=5 and delta=2, it will return (3, 7). pageID of 9 would give you (4, 8).
if the method is called without parameter, pageID is set to currentPage number
If current page is first page this function returns FALSE, otherwise returns previous page number.
integer $start - Min. number of items per page (optional)
integer $end - Max. number of items per page (optional)
integer $step - Increment between two options (optional)
boolean $showAllData - If true, perPage is set equal to totalItems (optional)
array $extraParams (optional)
'optionText': text to show in each option. Use '%d' where you want to see the number of pages selected.
'attributes': (html attributes) Tag attributes or HTML attributes (id="foo" pairs), will be inserted in the <select> tag.
'checkMaxLimit': if true, Pager checks if $end is bigger than $totalItems, and doesn't show the extra select options.
Returns a string with a XHTML SELECT menu, useful for letting the user choose how many items per page should be displayed. If parameter useSessions is TRUE, this value is stored in a session var. The string isn't echoed right away so you can use it with template engines.
This example shows how you can create a select box to let your users choose the number of items to display on each page.
include 'Pager/Pager.php'; $params = array( 'mode' => 'Jumping', 'perPage' => 3, 'delta' => 2, 'itemData' => array('a','b','c','d','e',[...omissis...],'z') ); $pager = & Pager::factory($params); $selectBox = $pager->getPerPageSelectBox(); echo '<form action="' . htmlspecialchars($_SERVER['PHP_SELF']) . '" method="GET">'; echo $selectBox; echo '<input type="submit" value="submit" />'; echo '</form>'; |
return TRUE or FALSE, wrt the last page is complete (i.e. it has perPage values in the array for the last page) or not.
The constructor is deprecated in favour of the new factory() method, which is PHP5 compatible too.
Pager constructor takes an associative array of parameters as input values. This is the complete list of these options:
itemData [array]
Array of items to page.
totalItems [integer]
Number of items to page (used only if itemData is not provided).
perPage [integer]
Number of items to display on each page.
delta [integer]
Number of page numbers to display before and after the current one.
mode [string]
"Jumping" or "Sliding" -window - It determines pager behaviour.
expanded [boolean]
if TRUE, window size is always 2*delta+1
linkClass [string]
Name of CSS class used for link styling.
urlVar [string]
Name of URL var used to indicate the page number. Default value is "pageID".
path [string]
Complete path to the page (without the page name).
fileName [string]
name of the page, with a "%d" if append == TRUE.
append [boolean]
If TRUE pageID is appended as GET value to the URL. If FALSE it is embedded in the URL according to fileName specs.
altPrev [string]
Alt text to display for prev page, on prev link. Default value is "previous page";
altNext [string]
Alt text to display for next page, on next link. Default value is "next page";
altPage [string]
Alt text to display before the page number. Default value is "page ".
prevImg [string]
Something to display instead of "<<". It can be text such as "<< PREV" or an <img/> as well.
nextImg [string]
Something to display instead of ">>". It can be text such as "NEXT >>" or an <img/> as well.
separator [string]
What to use to separate numbers. It can be an <img/>, a comma, an hyphen, or whatever.
spacesBeforeSeparator [integer]
Number of spaces before the separator.
spacesAfterSeparator [integer]
Number of spaces after the separator.
firstPagePre [string]
String used before first page number. It can be an <img/>, a "{", an empty string, or whatever.
firstPageText [string]
String used in place of first page number.
firstPagePost [string]
String used after first page number. It can be an <img/>, a "}", an empty string, or whatever.
lastPagePre [string]
Similar to firstPagePre, but used for last page number.
lastPageText [string]
Similar to firstPageText, but used for last page number.
lastPagePost [string]
Similar to firstPagePost, but used for last page number.
curPageLinkClassName [string]
Name of CSS class used for current page link.
clearIfVoid [boolean]
if there's only one page, don't display pager (returns an empty string).
useSessions [boolean]
if TRUE, number of items to display per page is stored in the $_SESSION[$_sessionVar] var.
closeSession [boolean]
if TRUE, the session is closed just after R/W.
sessionVar [string]
Name of the session var for perPage value. A value different from default can be useful when using more than one Pager istance in the page.
pearErrorMode [constant]
PEAR_ERROR mode for raiseError(). Default is PEAR_ERROR_RETURN.
fileName IF append==FALSE (default is TRUE)
itemData OR totalItems (if itemData is set, totalItems is overwritten)
Data paging class which also builds links to the pages.
Pager_Sliding is a class to page an array of data. It is taken as input and it is paged according to various parameters. Pager_Sliding also builds links within a specified range, and allows complete customization of the output (it even works with mod_rewrite). It is compatible with PEAR::Pager's API
This simple example will page the array of alphabetical letters, giving back pages with 3 letters per page, and links to the previous two / next two pages:
require_once 'Pager/Sliding.php'; $params = array( 'perPage' => 3, 'delta' => 2, 'itemData' => array('a','b','c','d','e',[...omissis...],'z') ); $pager = & new Pager_Sliding($params); $data = $pager->getPageData(); $links = $pager->getLinks(); //$links is an ordered+associative array with 'back'/'pages'/'next'/'first'/'last'/'all' links. //NB: $links['all'] is the same as $pager->links; //echo links to other pages: echo $links['all'] //Show data for current page: echo 'PAGED DATA: ' ; print_r($data); //Results from methods: echo 'getCurrentPageID()...: '; var_dump($pager->getCurrentPageID()); echo 'getNextPageID()......: '; var_dump($pager->getNextPageID()); echo 'getPreviousPageID()..: '; var_dump($pager->getPreviousPageID()); echo 'numItems()...........: '; var_dump($pager->numItems()); echo 'numPages()...........: '; var_dump($pager->numPages()); echo 'isFirstPage()........: '; var_dump($pager->isFirstPage()); echo 'isLastPage().........: '; var_dump($pager->isLastPage()); echo 'isLastPageComplete().: '; var_dump($pager->isLastPageComplete()); echo '$pager->range........: '; var_dump($pager->range); |
This example shows how you can use this class with mod_rewite. Let's suppose we have a .htaccess like this:
--------- RewriteEngine on #Options FollowSymlinks RewriteBase / RewriteRule ^articles/([a-z]{1,12})/art([0-9]{1,4})\.html$ /article.php?num=$2&month=$1 [L] --------- |
require_once 'Pager/Sliding.php'; $month = 'september'; $params = array( 'append' => false, 'urlVar' => 'num', 'path' => 'http://myserver.com/articles/' . $month, 'fileName' => 'art%d.html', //Pager replaces "%d" with page number... 'itemData' => array('a','b','c',[...omissis...],'z'), 'perPage' => 3 ); $pager = & new Pager_Sliding($params); $data = $pager->getPageData(); echo $pager->links; echo 'Data for current page: '; print_r($data); |
Using more than one pager in a single page is as simple as using a different urlVar for each pager:
require_once 'Pager/Sliding.php'; //first pager $params1 = array( 'perPage' => 3, 'urlVar' => pageID_articles, //1st identifier 'itemData' => $someArray ); $pager1 = & new Pager_Sliding($params1); $data1 = $pager1->getPageData(); $links1 = $pager1->getLinks(); //second pager $params2 = array( 'perPage' => 8, 'urlVar' => pageID_news, //2nd identifier 'itemData' => $someOtherArray ); $pager2 = & new Pager_Sliding($params2); $data2 = $pager2->getPageData(); $links2 = $pager2->getLinks(); |
While Pager v.1.x has a "jumping window" style, Pager_Sliding has a "sliding window" style. What does that mean? Let's see an example:
Let's suppose that the data spans on 15 pages, and the window width is 5 page links. The links are built on "frames" of 5 pages each: [1-5] [6-10] [11-15] Pager v.1.x always shows the same 5 page links while you are on one of these pages. Here's a temporal succession of the links, starting from page 1 and moving forward. There are brakets around current page number to highlight this:
a) {1} 2 3 4 5 => // first frame: [1-5] b) <= 1 {2} 3 4 5 => c) <= 1 2 {3} 4 5 => d) <= 1 2 3 {4} 5 => e) <= 1 2 3 4 {5} => // HERE IT JUMPS TO THE NEXT FRAME f) <= {6} 7 8 9 10 => // second frame: [6-10] g) <= 6 {7} 8 9 10 => h) <= 6 7 {8} 9 10 => |
Instead of jumping from one frame to the other, with Pager_Sliding the change is done smoothly, and the current page is always shown at the center of the "window" (except of course for the first and the last pages):
a) {1} 2 3 4 5 => [15] b) [1] <= 1 {2} 3 4 5 => [15] c) [1] <= 1 2 {3} 4 5 => [15] // HERE IT's STARTING WORKING AS DESIGNED d) [1] <= 2 3 {4} 5 6 => [15] // see: current page number is at the center of the window e) [1] <= 3 4 {5} 6 7 => [15] // and it stays there... f) [1] <= 4 5 {6} 7 8 => [15] g) [1] <= 5 6 {7} 8 9 => [15] h) [1] <= 6 7 {8} 9 10 => [15] |
Apart from the different "philosophy", Pager_Sliding is also designed to be highly customizable.
UPDATE: since Pager 2.x release, every option once only available in Pager_Sliding is now fully implemented in Pager too, and more. As stated in the Intro, Pager_Sliding is now deprecated in favour of the new Pager v.2.x. You can have both behaviours ("Jumping" and "Sliding") in Pager v.2.x, just change the mode. Please refer to Pager docs for more details.
There are *many* options to change the look and feel of the links in your page. They are explained in the constructor docs.
It can work with Apache mod_rewrite module too, see the examples for that.
It is "template"-friendly, i.e. you can assign the processed links and page numbers to your custom vars and use them to draw your link bar according to your page layout, without worrying about the underlying logic.
You can easily extend the class; this is useful if you plan to use the class in many different pages and you don't want to set the same options everytime: just set your preferred default values in your extending class and you're done!
integer $pageID - Optional pageID. If specified, linksfor that page are provided instead of current one.
return back/pages/next/first/last/all links, both as numeric and associative array.
If current page is last page this function returns FALSE, otherwise returns next page number.
Eg, if you pass it pageID = 5 and your delta is 2 it will return you 3 and 7. PageID of 6 would give you 4 and 8
NB: The behaviour of this function could be misleading: it was left only for compatibility with PEAR::Pager. It could raise some confusion when pageID is within delta positions from an extreme: in fact this method returns also the extremes, while $this->_getPageLinks leaves them out. Pager_Sliding works this way: if pageID is NOT an extreme, show first and last page within brackets: [1] << 5 | _6_ | 7 >> [15] So when dealing with pageID within delta positions from an extreme, this method would return the extreme as well, while $this->_getPageLinks would return (for instance) 2 | _3_ | 4 | 5 even if pageID is 3 and delta is 2. Consider this method deprecated and/or subject to changes.
If current page is first page this function returns FALSE, otherwise returns previous page number.
return TRUE or FALSE, wrt the last page is complete (i.e. it has perPage values in the array for the last page) or not.
Pager_Sliding constructor takes an associative array of parameters as input values. This is the complete list of these options:
itemData [array]
Array of items to page.
totalItems [integer]
Number of items to page (used only if itemData is not provided).
perPage [integer]
Number of items to display on each page.
delta [integer]
Number of page numbers to display before and after the current one.
expanded [boolean]
if TRUE, window size is always 2*delta+1
linkClass [string]
Name of CSS class used for link styling.
urlVar [string]
Name of URL var used to indicate the page number. Default value is "pageID".
path [string]
Complete path to the page (without the page name).
fileName [string]
name of the page, with a "%d" if append == TRUE.
append [boolean]
If TRUE pageID is appended as GET value to the URL. If FALSE it is embedded in the URL according to fileName specs.
altPrev [string]
Alt text to display for prev page, on prev link. Default value is "previous page";
altNext [string]
Alt text to display for next page, on next link. Default value is "next page";
altPage [string]
Alt text to display before the page number. Default value is "page ".
prevImg [string]
Something to display instead of "<<". It can be text such as "<< PREV" or an <img/> as well.
nextImg [string]
Something to display instead of ">>". It can be text such as "NEXT >>" or an <img/> as well.
separator [string]
What to use to separate numbers. It can be an <img/>, a comma, an hyphen, or whatever.
spacesBeforeSeparator [integer]
Number of spaces before the separator.
spacesAfterSeparator [integer]
Number of spaces after the separator.
firstPagePre [string]
String used before first page number. It can be an <img/>, a "{", an empty string, or whatever.
firstPagePost [string]
String used after first page number. It can be an <img/>, a "}", an empty string, or whatever.
lastPagePre [string]
Similar to firstPagePre, but used for last page number.
lastPagePost [string]
Similar to firstPagePost, but used for last page number.
curPageLinkClassName [string]
Name of CSS class used for current page link.
lastPagePost [boolean]
if there's only one page, don't display pager (returns an empty string).
fileName IF append==FALSE (default is TRUE)
itemData OR totalItems (if itemData is set, totalItems is overwritten)
Предоставляет Пакеты для работы с Протоколом Передачи ГиперТекста.
Provides a set of usefull, static functions related to the Hyper-Text-Transfer-Protocol.
Converts a UNIX timestamp into an RFC compliant HTTP header line. This function honors the "y2k_compliance" php.ini directive.
Пример 43-1. HEAD request to example.com
|
array - an array containing the header lines or a PEAR_Error.
Example output:
Array ( [response_code] => 200 [response] => HTTP/1.1 200 OK [Date] => Tue, 25 Nov 2003 22:08:57 GMT [Server] => Apache/1.3.27 (Unix) (Red-Hat/Linux) [Last-Modified] => Wed, 08 Jan 2003 23:11:55 GMT [ETag] => "3f80f-1b6-3e1cb03b" [Accept-Ranges] => bytes [Content-Length] => 438 [Connection] => close [Content-Type] => text/html ) |
Таблица 43-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
NULL | "HTTP::head Error $errstr ($erno)" | Connection to server failed | Check connectivity of your host and the given URL in $url |
Negotiate language with the user's browser through the Accept-Language HTTP header or the user's host address. Language codes are generally in the form "ll" for a language spoken in only one country, or "ll-CC" for a language spoken in a particular country. For example, U.S. English is "en-US", while British English is "en-UK". Portugese as spoken in Portugal is "pt-PT", while Brazilian Portugese is "pt-BR". Two-letter country codes can be found in the ISO 3166 standard.
Quantities in the Accept-Language: header are supported, for example:
Accept-Language: en-UK;q=0.7, en-US;q=0.6, no;q=1.0, dk;q=0.8 |
Пример 43-1. Usage example
|
This example negotiates with the user agent if any of the languages, which are specified in supported, are supported on the user's system. If the negotiation has a positive result, the language code of the most preferred language is printed. Otherwise the default language code (en-US) is printed.
Being able to perform language negotiation is a big help when developing internationalized website with pages, that are available in more than one language. Using negotiation, the user will always get pages in the language which he prefers. (Assuming that their user agent is configured properly.)
array $supported - an associative array indexed by language codes (country codes) supported by the application. Values must evaluate to TRUE.
string $default - the default language that should be used if none of the other languages are found during negotiation.
Эта функция может быть вызвана статически.
The returned language is only a hint! Sending the accepted languages by the client is optional. The language settings of the browser do not have to meet the user's native language - for example a german traveller in a spanish internet cafe. You can improve your result by combining it with the result of the Net_Geo package. Apart from that, you should still give the user the chance to manually choose their preferred language menu.
This function redirects the client. This is done by issuing a Location: header and exiting.
Пример 43-1. Redirecting to another site
|
Пример 43-2. Local redirect
|
A simple HTTP client class. The class wraps around HTTP_Request providing a higher-level API for performing multiple HTTP requests. It handles HTTP redirects, stores cookies and sets referrers between requests.
Parameters to pass to HTTP_Request's constructor
Default headers to send on every request
The attached Listeners are notified of the following events:
sent before a HTTP request that is not a result of previous redirect.
sent upon receiving a successfull 2xx response (or 3xx response, if it is not a redirect or if redirect processing is disabled).
sent when a 3xx redirection response is received, before following a redirect
sent on 4xx, 5xx response
Listener instance to attach
Whether the listener should be attached to the created HTTP_Request objects
URL
additional data to send
Whether the data is already urlencoded
URL
Data to send
Whether the data is already urlencoded
Files to upload. Elements of the array should have the form: array(name, filename(s)[, content type]), see HTTP_Request::addFile()
header name or array ('header name' => 'header value')
header value if $name is not an array
Setting this value to 0 disables redirect processing. If it is not 0 and the number of redirects after a request is bigger than this number, then an error will be raised.
parameter name or array ('parameter name' => 'parameter value')
parameter value if $name is not an array
Stores cookies and passes them between HTTP requests. While this class is a part of HTTP_Client package, it can be used separately.
An array representing cookie, this function expects all of the array's fields ('name', 'value', 'domain', 'path', 'expires', 'secure') to be set.
The method sends only the cookies that should be sent with the request and it adds them in right order.
This method gets the cookies from HTTP response received by HTTP_Request instance and adds them to the object's internal list.
Send HTTP Downloads
HTTP_Download provides an interface to easily send any arbitrary data to HTTP clients. HTTP_Download can gain its data from variables, files or stream resources.
With this package you can easily handle (hidden) downloads. Hidden means not accessible by the public - for instance if you want to restrict access to particular downloads.
It supports HTTP compression, caching and partial downloads, resuming and sending raw data, for example from database BLOBs.
ATTENTION: You shouldn't use this package together with ob_gzhandler or zlib.output_compression enabled in your php.ini, especially if you want to send already gzipped data!
Have a look at the following examples:
Пример 43-1. Static send:
|
Пример 43-2. Send a hidden file:
|
Пример 43-3. Send arbitrary data:
|
Пример 43-4. Limiting bandwidth:
|
Пример 43-5. Sending a PostgreSQL LOB:
|
array $params - An associative array of parameters:
one of:
$params['file'] - filepath
$params['data'] - raw data
$params['resource'] - resource handle
and any of:
$params['gzip'] - whether to gzip the download
$params['cache'] - whether to allow client side caching of the download
$params['lastmodified'] - unix timestamp of last modification
$params['contenttype'] - content type
$params['contentdisposition'] - content disposition
$params['buffersize'] - amount of bytes read at once from files or resources
$params['throttledelay'] - amount of seconds to sleep after each chunk that has been sent
$params['cachecontrol'] - cache privacy and validity
See also setFile(), setData(), setResource(), setGzip(), setCache(), setContentType(), setLastModified(), setContentDisposition(), setBufferSize(), setThrottleDelay(), setCacheControl(), setParams().
Set the parameters for the download.
You can use this method as an alternative to passing the parameters in the constructor or calling the setter of each parameter.
array $params - An associative array of parameters:
one of:
$params['file'] - filepath
$params['data'] - raw data
$params['resource'] - resource handle
and any of:
$params['gzip'] - whether to gzip the download
$params['cache'] - whether to allow client side caching of the download
$params['lastmodified'] - unix timestamp of last modification
$params['contenttype'] - content type
$params['contentdisposition'] - content disposition
$params['buffersize'] - amount of bytes read at once from files or resources
$params['throttledelay'] - amount of seconds to sleep after each chunk that has been sent
$params['cachecontrol'] - cache privacy and validity
See also setFile(), setData(), setResource(), setGzip(), setCache(), setContentType(), setLastModified(), setContentDisposition(), setBufferSize(), setThrottleDelay(), setCacheControl().
string $file - file path
bool [$send_404 = true] - whether to send "HTTP 404 File Not Found", if file couldn't be found
Set $data to null if you want to unset.
Otherwise you can send any arbitrary data ie. from a database BLOB.
Set the resource handle to retrieve the data for the download.
The resource handle supplied will be closed after sending the download.
Set $handle to null if you want to unset.
Замечание: This cannot be used with resources of databases that populate their BLOBs as resource handles like PostgreSQL. A possible solution would be to write a stream wrapper.
Returns a PEAR_Error if $handle is no valid resource or not null.
Define whether you want to send the download gzipped or not.
Returns a PEAR_Error if ext/zlib is not available.
Define whether you want to allow caching of the download on the clients side.
If set to true (default), HTTP_Download will emit some caching headers like Cache-Control, Last-Modified and ETag.
Define the contents of the Cache-Control header.
If set to set to "public", proxies are adviced to cache the response, if set to "private", proxies are adviced to do not.
The maxage paramter controls the amount of seconds an entity is suggested to be cached. Many user agents won't even send a request for subsequent requests to the same resource within the specified time frame.
string [$cache = "public"] - whether to allow proxy caching
int [$maxage = 0] - maximum age of the cached entity
The amount of bytes specified as buffer size is the maximum amount of data read at once from resources or files. The default size is 2M (2097152 bytes).
Be aware that if you enable gzip compression and you set a very low buffer size that the actual file size may grow due to added gzip headers for each sent chunk of the specified size.
Returns PEAR_Error (HTTP_DOWNLOAD_E_INVALID_PARAM) if $size is not greater than 0 bytes.
Set the amount of seconds to sleep after each chunck that has been sent. One can implement some sort of throttle through adjusting the buffer size and the throttle delay. With a setting of buffersize=25600 and throttledelay=1 HTTP_Download will sleep a second after each 25 K of data sent.
Just be aware that if gzip'ing is enabled, decreasing the chunk size too much leads to proportionally increased network traffic due to added gzip header and bottom bytes around each chunk.
Set a reasonable content type for the download.
Examples:
application/pdf
application/zip
text/css
Returns PEAR_Error if $content_type doesn't seem to be valid.
Set the time (unix timestamp) of last modification of the download.
This is usually determined by filemtime($file) in setFile().
Set content disposition of the download.
"Content-Disposition" is not HTTP compliant, but most browsers follow this header, so it was borrowed from MIME standard. It looks like this: "Content-Disposition: attachment; filename=example.tgz".
string [$disposition = HTTP_DOWNLOAD_ATTACHMENT] - the disposition of the download (either 'attachment' or 'inline')
string [$file_name = null] - the file name the browser's download window should show
Use only if you send a file.
First we try to use MIME_Type, if installed, to detect the content type, else we check if ext/mime_magic is loaded and properly configured.
Returns PEAR_Error if:
MIME_Type failed to detect a proper content type (HTTP_DOWNLOAD_E_INVALID_CONTENT_TYPE) |
ext/magic.mime is not installed, or not properly configured (HTTP_DOWNLOAD_E_NO_EXT_MMAGIC) |
mime_content_type() couldn't guess content type or returned a content type considered to be bogus by setContentType() (HTTP_DOWNLOAD_E_INVALID_CONTENT_TYPE) |
Send the download.
Returns PEAR_Error if:
HTTP headers were already sent
HTTP Range was invalid
bool [$autoSetContentDisposition = true] - automatically sets the Content-Disposition to HTTP_DOWNLOAD_ATTACHMENT header if not already set
array $params - An associative array of parameters:
one of:
$params['file'] - filepath
$params['data'] - raw data
$params['resource'] - resource handle
and any of:
$params['gzip'] - whether to gzip the download
$params['cache'] - whether to allow client side caching of the download
$params['lastmodified'] - unix timestamp of last modification
$params['contenttype'] - content type
$params['contentdisposition'] - content disposition
$params['buffersize'] - amount of bytes read at once from files or resources
$params['throttledelay'] - amount of seconds to sleep after each chunk that has been sent
bool [$guess = false] - whether to call guessContentType()
See also setFile(), setData(), setResource(), setGzip(), setCache(), setContentType(), setLastModified(), setContentDisposition(), setBufferSize(), setThrottleDelay(), setParams().
Send an archive created on the fly by Archive_Tar or Archive_Zip.
The parameter $files can be an array of files/directories or a space separated string of files/directories which should be packed to an archive.
The parameter $type can be one of HTTP_DOWNLOAD_TAR, HTTP_DOWNLOAD_TGZ, HTTP_DOWNLOAD_BZ2 and HTTP_DOWNLOAD_ZIP.
Замечание: The usage of this method is deprecated. Use HTTP_Download_Archive::send() instead.
string $name - the name the archive should have
mixed $files - list of files/directories
string [$type = HTTP_DOWNLOAD_TGZ] - the format of the archive (TAR, TGZ, BZ2 or ZIP)
string [$add_path = ''] - path that should be prepended to the files
string [$strip_path = ''] - path that should be stripped from the files
The package provides an easy way to perform HTTP requests. It supports GET/POST/HEAD/TRACE/PUT/DELETE, Basic authentication, Proxy, Proxy Authentication, SSL, file uploads etc.
With this package, one can easily perform HTTP request from within PHP scripts. It support GET/POST/HEAD/TRACE/PUT/DELETE, Basic authentication, Proxy, Proxy Authentication, SSL, file uploads etc.
Because of the above mentioned features HTTP_Request makes it possible to mimic big parts of web browsers such as the widely-known Mozilla browser in PHP applications. Possible application areas are:
Checking the validity of WWW links with the help of getResponseCode().
Grabbing remote web pages and parsing the result.
etc.
Пример 43-1. Fetches yahoo.com and displays it
|
Пример 43-2. Fetching two website in a row In this example, two websites are fetched and displayed. To the first one a POST parameter is passed. The POST data stack is cleared before the second website is fetched.
|
Basic Authentication is a challenge-response mechanism described in RFC 2617.
Пример 43-1. Basic Authentication The following example assumes that one wants to fetch a page /protected.html on the host example.com that is protected using Basic Authentication. The necessary username to pass the authentication is johndoe and the appendant password is foo.
|
Пример 43-1. Adding a cookie to the request In this example a cookie named version is added to the HTTP request. The value of this cookie is the version string of the PHP interpreter that is running the instance of HTTP_Request.
|
Пример 43-2. Reading cookies from a HTTP response Reading cookies that come with a HTTP response is shown in this following example.
|
Пример 43-1. Upload a PDF document In this example a file named /home/johndoe/text.pdf is uploaded to the remote machine upload.example.com under the name johndoe-text.pdf. Additionally Basic Authentication is used to ensure that John is allowed to upload something.
|
Пример 43-1. Adding a custom request header In this example a HTTP header X-PHP-Version is added to the HTTP request. The value of this header is the version string of the PHP interpreter that is running the instance of HTTP_Request.
|
Headers that have been added to the HTTP_Request object can be removed with the method removeHeader(), before sendRequest() has been called.
Пример 43-1. Using a proxy server with anonymous access In this example it is assumed that one wants to use the machine with the hostname proxy.example.com, where a proxy server is listening on port 8080, to proxy the outgoing connection to example.com. The second parameter of setProxy() is optional and defaults to 8080.
|
Пример 43-2. Using proxy authorization This is the same example as above, except that a username/password tuple is provided, which authorizes the user at the proxy server: The username is johndoe and the appendant password is foo.
|
Because HTTP is a protocol based on the Request - Response scheme, every HTTP request is followed by a HTTP response. HTTP_Request offers several methods to evaluate the information from these responses.
A important part of the HTTP response is the response code. The most well-known response code probably is 404, which you may have seen in your browser at several occasions. The meaning of 404 is that the requested ressource could not be found. A complete list of status codes can be found in RFC 2616.
Пример 43-1. Checking the response code
|
Similar to a HTTP request a HTTP response consists of a header and a body. HTTP_Request offers a method to access the header of the response.
Пример 43-2. Getting all headers from the response
This will print all headers and the appendant values. |
Пример 43-3. Getting a specific header
This will print the value of the Date: header. |
Fetching the cookies that are part of the HTTP response is described in the Cookies section.
HTTP_Request_Listener is an abstract class that can be extended to capture events and respond to them as they occur. Included with HTTP_Request is an example of a console-based progress bar. To implement this, the HTTP_Request_DownloadListener class is used, which uses the Console_ProgressBar package to display a download progress meter.
In order to use a listener, it must attach to the specific HTTP_Request or HTTP_Response object that you want to monitor. The attach code is shown at the bottom of the example. As you can see, the event listener is propagated from the HTTP_Request object to any child HTTP_Response objects, and attaching only need happen to the first HTTP_Request object.
Пример 43-1. Download progress bar with HTTP_Request_Listener
|
The HTTP_Request class sends these events:
connect - upon server connection, this event is sent
sentRequest - after the request was sent, this event is sent
disconnect - after server disconnect, this event is sent
The HTTP_Response class sends these events:
gotHeaders - this event is sent after receiving response headers (headers are passed in $data as an associative array)
tick - this event is sent on receiving a part of response body (the part is passed in $data as a string)
gzTick - this event is sent on receiving a part of response body that is gzip-compressed (the part is passed in $data as a string)
gotBody - this event is sent on after receiving the complete response body (the decoded body is passed as a string in $data if it was gzipped)
Provides packages for internationalization and localization.
The static I18Nv2 class currently provides routines for unified (ment as OS independent) locale setting, retrieving locale specific information like the "thousands separator" and automatic characterset conversion for output.
Внимание |
This documentation is outdated and needs an overhaul. |
The work on I18Nv2 has actually started as a refactoring of I18N, but after some time I figured out that too many BC breaking changes were applied, so the release of a new major version was suggested.
I18N was modeled after Java OO practice and it provides a bunch of classes for each formatting action (numbers, currencies, dates).
I18Nv2 takes another approach and provides all formatting functionality within one class, which is I18Nv2_Locale.
I18Nv2_Locale is based upon PHPs builtin functionality of setlocale() , localeconv () and iconv related functions, while I18N completely depends on user contributed formatting rules.
I wouldn't say I18Nv2's approach is the better one, because it depends on the internationalization capabilities of the underlying operating system, but it's simpler and faster - though it is in need of user contributed date and time formatting rules.
I18N's translation functionality was dropped in favour of the new and shiny Translation2.
I18Nv2 still provides an HTTP negotiator to reveal the users preferred language/locale and charset.
I18Nv2 has translated lists of ISO country and language names for about 50 different languages. See I18Nv2_Country and I18Nv2_Language.
Because Un*x and Windows use different locale codes, PHPs setLocale() is not easily portable - I18Nv2::setLocale() attempts to provide this portability.
With I18Nv2 you can use standard locale codes like 'en_US' on both, Linux and Windows, though the list is far not complete yet, so if you stumble over a not covered locale (I18Nv2::$locales in I18Nv2::_main()), just drop a mail to the maintainer with the missing locale and its corresponding Win32 code.
Пример 45-1. I18Nv2::setLocale()
|
I18Nv2 holds locale conventions returned by localeConv() stored statically, so they are easily accessible through I18Nv2::getInfo(). Have a look at the documentation of PHPs localeConv() for all available information.
Пример 45-2. I18Nv2::getInfo()
|
I18Nv2 provides an easy way to utilize the ob_iconv_handler() through I18Nv2::autoConv().
Пример 45-3. I18Nv2::autoConv()
|
I18Nv2_Locale is a formatter object that provides functionality to format dates, times, numbers and currencies in locale dependent conventions.
Пример 45-4. I18Nv2_Locale
|
I18Nv2 provides a language, charset and locale negotiator for HTTP.
Пример 45-5. I18Nv2_Negotiator
|
I18Nv2 provides translated lists of ISO language names.
Пример 45-6. I18Nv2_Language
|
I18Nv2 provides translated lists of ISO country names.
Пример 45-7. I18Nv2_Country
|
I18Nv2 provides decorated classes for country and language lists.
Пример 45-8. I18Nv2_DecoratedList
|
Пример 45-9. I18Nv2_CommonList::toDecoratedList()
|
Таблица 45-1. Constants defined in I18Nv2/Locale.php
Name | Value |
---|---|
I18Nv2_CURRENCY | 20 |
I18Nv2_CURRENCY_INTERNATIONAL | 22 |
I18Nv2_CURRENCY_LOCAL | 21 |
I18Nv2_DATETIME | 30 |
I18Nv2_DATETIME_DEFAULT | 32 |
I18Nv2_DATETIME_FULL | 35 |
I18Nv2_DATETIME_LONG | 34 |
I18Nv2_DATETIME_MEDIUM | 33 |
I18Nv2_DATETIME_SHORT | 31 |
I18Nv2_NUMBER | 10 |
I18Nv2_NUMBER_FLOAT | 11 |
I18Nv2_NUMBER_INTEGER | 12 |
Set environment to the specified locale.
Пример 45-1. Set a locale:
|
a valid locale like en_US or de_DE
the locale category - usually LC_ALL
See also I18Nv2::setLocale() example, I18Nv2::getInfo(), I18Nv2::lastLocale(), PHPs setlocale().
Retrieve kinda history of locales that have been already set.
This only works, if I18Nv2::setLocale() has already been called.
if 0, the current otherwise n prior to the current locale
whether to return the array with locale, language and actually used system locale
Get several locale specific information like thousands separator. The provided information debends on the local libc implementation and thus is not always reliable - especially on Microsoft Windows.
Пример 45-1. Retrieving specific locale information:
|
Returns mixed locale specific information or array all available locale specific information if called without parameter.
This method utilizes ob_iconv_handler(), so you should call it at the beginning of your script (prior to any output).
1 require_once 'I18Nv2.php'; 2 I18Nv2::autoConv('iso-8859-1', 'utf-8'); 3 // ... |
Возвращает TRUE при удаче и PEAR_Error в обратном случае.
Returns PEAR_Error if output buffering couldn't be started.
require_once 'I18Nv2.php'; |
object
I18Nv2_Negotiator
&I18Nv2::createNegotiator
([string $defLang = 'en' [, string $defCharset = 'iso-8859-1']])
Create a new I18Nv2_Negotiator object with the specified default language and default character set.
Represents a specific locale and provides routines for formatting date and time, numbers and currency.
Initializes the I18Nv2_Locale object.
This method gets aumatically called by the constructor.
Возвращает TRUE при удаче и PEAR_Error в обратном случае.
Returns a PEAR_Error if the supplied locale was invalid.
Set a custom format.
If $format is omitted, the custom format for $type will be discarded - if both vars are omitted all custom formats will be discarded.
the I18Nv2 format category for which to set the custom format
the custom format
Set the currency format to use.
Either I18Nv2_CURRENCY_LOCAL, I18Nv2_CURRENCY_INTERNATIONAL or a custom currency format.
a I18Nv2_CURRENCY constant
whether to use a defined custom format
a I18Nv2_DATETIME constant
whether to use a defined custom format
a I18Nv2_NUMBER constant
whether to use a defined custom format
a I18Nv2_DATETIME constant
whether to use a defined custom format
numerical representation of weekday (0 = Sunday, 1 = Monday, ...)
whether to return the abbreviation
numerical representation of month (0 = January, 1 = February, ...)
whether to return the abbreviation
require_once 'I18N/Negotiator.php'; |
object
I18Nv2_Negotiator
I18Nv2_Negotiator::I18Nv2_Negotiator
([string $defaultLanguage = 'en' [, string $defaultCharset = 'iso-8859-1' [, string $defaultCountry = '']]])
Find language code, country code, charset code, and dialect or variant of locale setting in HTTP request headers.
default language
default character set
default country
Get a matching locale code.
This method is a combination of I18Nv2::getLanguageMatch() and I18Nv2::getCountryMatch()
List of ISO-639-1 two letter resp. ISO-639-2 three letter language code to language name mapping.
require_once 'I18Nv2/Language.php'; |
object
object I18Nv2_Language
I18Nv2_Language::I18Nv2_Language
([bool $threeLetters = FALSE])
whether to use ISO-639-2 three letters or ISO-639-1 two letters language code format.
Translation2
Таблица 45-1. Classes that extend Translation2
Class | Summary |
---|---|
Translation2_Admin | Administration utilities for translation string management |
Translation2 is a class for multilingual applications management. It provides an easy way to retrieve all the strings for a multilingual site from a data source (i.e. db). The API is designed to be clean, simple to use, yet powerful and extensible. A Translation2_Admin class is provided to easily manage translations (add/remove a language, add/remove a string).
The following containers (data source drivers) are provided:
PEAR::DB
PEAR::MDB
PEAR::MDB2
gettext
PEAR::DB_DataObject (experimental, used by PEAR:: HTML_Template_Flexy)
XML
Some decorator classes will help in various tasks. They can be layered/stacked one on top of the other, in any number. This approach should suit everyone's needs. Currently, the following decorators are provided:
CacheLiteFunction (for fast file-based caching)
CacheMemory (for memory-based caching)
DefaultText (to replace empty strings with their keys or a default text)
ErrorText (to replace empty strings with an "error_text" fallback message)
Iconv (to switch from/to different encodings)
Lang (resort to fallback languages for empty strings)
SpecialChars (replace html entities with their hex codes)
UTF-8 (convert UTF-8 strings to ISO-8859-1)
This simple example will show how you can instanciate a Translation2 object and use it to retrieve your translated strings from a db, using the MDB2 driver:
// set the parameters to connect to your db $dbinfo = array( 'hostspec' => 'host', 'database' => 'dbname', 'phptype' => 'mysql', 'username' => 'user', 'password' => 'pwd' ); define('TABLE_PREFIX', 'mytable_'); // tell Translation2 about your db-tables structure, // if it's different from the default one. // NB: the default db structure is: // // Table "langs" (available languages and meta info) // +----+------+------+----------+------------+ // | ID | name | meta | encoding | error_text | // +----+------+------+----------+------------+ // // Table "strings" (translations) // +----+---------+----+----+----+-----+ // | ID | page_id | en | de | it | ... | // +----+---------+----+----+----+-----+ // You can have one table per translation, instead // of one table for all the languages // $params = array( 'langs_avail_table' => TABLE_PREFIX.'langs_avail', 'lang_id_col' => 'ID', 'lang_name_col' => 'name', 'lang_meta_col' => 'meta', 'lang_errmsg_col' => 'error_text', 'strings_tables' => array( 'en' => TABLE_PREFIX.'i18n', 'it' => TABLE_PREFIX.'i18n', 'de' => TABLE_PREFIX.'i18n' ), 'string_id_col' => 'ID', 'string_page_id_col' => 'pageID', 'string_text_col' => '%s' //'%s' will be replaced by the lang code ); $driver = 'MDB2'; require_once 'Translation2.php'; $tr =& Translation2::factory($driver, $dbinfo, $params); //always check for errors. In this examples, error checking is omitted //to make the example concise. if (PEAR::isError($tr)) { //deal with it } // you can set the charset that the database must use, for instance 'utf8' $tr->setCharset('iso-8859-1'); // set primary language $tr->setLang('it'); // set the group of strings you want to fetch from $tr->setPageID('defaultGroup'); // add a Lang decorator to provide a fallback language $tr =& $tr->getDecorator('Lang'); $tr->setOption('fallbackLang', 'en'); // add another Lang decorator to provide another fallback language, // in case some strings are not translated in Italian or English $tr =& $tr->getDecorator('Lang'); $tr->setOption('fallbackLang', 'de'); // fetch the string with the 'test' stringID echo $tr->get('test'); // fetch a string not translated into Italian (test fallback language) echo $tr->get('only_english'); // fetch the whole group of strings, without resorting to the fallback lang // and without any "decoration" $rawPage = $tr->getRawPage(); print_r($rawPage); // fetch the whole group of strings, but applying the decorators $page = $tr->getPage(); print_r($page); // you can force the lang and the group of the string you're requesting echo $tr->get('month_01', 'calendar', 'it'); // the same is true for getRawPage() and getPage() $page = $tr->getPage('calendar', 'de'); print_r($page); |
As you can see, the main methods are get(), getPage() and getRawPage(). The full syntax is
get($stringID, $pageID, $langID); |
NB: you have to check for errors at least on the first invocation of one of these methods, since the db connection is only estabilished at this point, so the chances of failures are higher here.
Now let's see how we can extract some meta info from the db:
$tr->getLang(); // no langID => get current lang $tr->getLang('it'); // same as above, if the current lang is Italian // the first parameter is the lang code, // with the second parameter you can filter the info you need $tr->getLang('it', 'error_text'); $tr->getLang('en', 'name'); $tr->getLang('de', 'meta'); $tr->getLang('de', 'encoding'); |
Translation2 uses decorators to filter/change the retrieved strings. You can have a chain of decorators (filters), and you can also add yours.
$tr =& Translation2::factory($driver, $dbinfo, $params); $tr->setLang('en'); $tr->setPageID('calendar'); // add a memory-based cache decorator, to do some basic prefetching and // reduce the load on the db $tr = & $tr->getDecorator('CacheMemory'); // add a file-based cache decorator, to cache the query results through pages $tr =& $tr->getDecorator('CacheLiteFunction'); $tr->setOption('cacheDir', 'cache/'); $tr->setOption('lifeTime', 3600*24); // add a fallback lang decorator $tr = & $tr->getDecorator('Lang'); $tr->setOption('fallbackLang', 'it'); // add a special chars decorator to replace special characters with the html entity $tr = & $tr->getDecorator('SpecialChars'); // control the charset to use $tr->setOption('charset', 'ISO-8859-2'); // add a UTF-8 decorator to automatically decode UTF-8 strings $tr = & $tr->getDecorator('UTF8'); // add a default text decorator to deal with empty strings $tr = & $tr->getDecorator('DefaultText'); // replace the empty string with its stringID echo $tr->get('emptyString'); // use a custom fallback text echo $tr->get('emptyString', 'stringGroup', 'en', 'show this default text'); |
The getStringID() method is the reverse of get(). If you want to translate a string to another language, but you don't know the associated stringID, you can retrieve it with this method:
$tr->setLang('it'); // translate the Italian string "gennaio" into the English "january" $stringID = $tr->getStringID('gennaio', 'calendar'); echo $translatedString = $tr->get($stringID, 'calendar', 'en'); |
Translation2 can handle parametric strings, and replace them with parameters passed at runtime (they can be numeric or associative arrays).
// "hello_user" = "hello &&user&&, today is &&weekday&&, &&day&&th &&month&& &&year&&" $tr->setParams(array( 0 => '', 'user' => 'Joe', 'day' => '15', 'month' => $tr->get('month_01', 'calendar', 'en'), 'year' => '2004', 'weekday' => $tr->get('day_5', 'calendar', 'en') )); echo $tr->get('hello_user'); // the above line will print "hello Joe, today is Friday, 15th January 2004" |
If your site structure is organized in sections, like a header, a body and a footer, you may use those units as "pages" (or groups of translations), and then fetch them one by one:
$header_trans = $tr->getPage('header'); $body_trans = $tr->getPage('body'); $footer_trans = $tr->getPage('footer'); |
$translations = array_merge( $tr->getPage('header'), $tr->getPage('body'), $tr->getPage('footer') ); |
Translation2_Admin is a class meant to help with translation management (add/remove a language, add/remove a string).
This simple example will show how you can add a new language [addLang()], using the MDB2 driver:
// set the parameters to connect to your db $dbinfo = array( 'hostspec' => 'host', 'database' => 'dbname', 'phptype' => 'mysql', 'username' => 'user', 'password' => 'pwd' ); // tell Translation2 about your db-tables structure, // if it's different from the default one. $params = array( 'langs_avail_table' => 'langs_avail', 'lang_id_col' => 'id', 'lang_name_col' => 'name', 'lang_meta_col' => 'meta', 'lang_errmsg_col' => 'error_text', 'lang_encoding_col' => 'encoding', 'strings_tables' => array( 'it' => 'i18n', 'de' => 'i18n' ), //OR, if you use only one table, //'strings_default_table' => 'i18n', 'string_id_col' => 'id', 'string_page_id_col' => 'page_id', 'string_text_col' => '%s' //'%s' will be replaced by the lang code ); $driver = 'MDB2'; require_once 'Translation2/Admin.php'; $tr =& Translation2_Admin::factory($driver, $dbinfo, $params); // set some info about the new lang $newLang = array( 'lang_id' => 'en', 'table_name' => 'i18n', 'name' => 'english', 'meta' => 'some meta info', 'error_text' => 'not available', 'encoding' => 'iso-8859-1', ); $tr->addLang($newLang); |
This simple example will show how you can update an existing language [updateLang()]:
// set some info about the new lang $langData = array( 'lang_id' => 'en', 'table_name' => 'i18n', 'name' => 'English', 'meta' => 'some updated meta info', 'error_text' => 'this text is not available in English', 'encoding' => 'iso-8859-15', ); $tr->updateLang($langData); |
If you want to remove all the translated strings and the info for a certain language, all you have to do is
$tr->removeLang('fr'); |
$tr->removeLang('fr', true); |
Now let's see how we can add() a new translation for a new or an existing string.
$stringArray = array( 'en' => 'sample', 'it' => 'esempio', ); // add the English and Italian translations associated to // the 'smallTest' stringID and to the 'testGroup' pageID $tr->add('smallTest', 'testGroup', $stringArray); |
You can remove() the translations for a certain stringID:
$tr->remove('smallTest', 'testGroup'); |
Translation2 supports different storage drivers; this page is meant to highlight the differences among them.
Translation2 can work with any of these database abstraction layers, just pass the appropriate connection options. These three containers are absolutely identical in what they do and in how they work (wrt Translation2, of course).
// connection options $dbinfo = array( 'hostspec' => 'host', 'database' => 'dbname', 'phptype' => 'mysql', 'username' => 'user', 'password' => 'pwd' ); //select the preferred driver $driver = 'MDB2'; //switch to 'DB' or 'MDB' as needed require_once 'Translation2.php'; $tr =& Translation2::factory($driver, $dbinfo, $params); |
The dataobjectsimple container is the natural choice for those using DB_DataObject, as it is tightly tied to the DAO. This storage driver can use all databases supported by the PEAR::DB abstraction layer to fetch data.
For this container, you can't specify a custom table definition, since this feature is not supported yet. You must create a table with the following structure:
// meta data etc. not supported table: translations id // not null primary key autoincrement.. string_id // translation id page // indexed varchar eg. (mytemplate.html) lang // index varchar (eg. en|fr|.....) translation // the translated value in language lang. |
create table translations ( id int(11) auto_increment not null primary key, string_id int(11), page varchar(128), lang varchar(10), translation text ); alter table translations add index page (page); alter table translations add index lang (lang); alter table translations add index string_id (string_id); |
This is a wrapper around the gettext base functions, and thanks to File_Gettext you can retrieve an entire domain or write to an existing/new domain without calling the command line compiler utility.
The gettext container requires PEAR::File_Gettext and PEAR::I18Nv2 0.9.1 or newer, make sure you have them installed.
The construction parameters are a bit different from the db ones. To make things as simple as possible, the domain definitions and the available language list are read from two INI files.
langs.ini example:
; If one does not specify the source encoding, ISO-8859-1 is assumed ; Beware that gettext can choke on bad encodings! [en] name = English encoding = iso-8859-1 [de] name = Deutsch encoding = iso-8859-1 [it] name = italiano encoding = iso-8859-1 |
messages = /path/to/locale 2nddomain = /path/to/locale 3rddomain = /path/to/locale |
Sample code to use Translation2 with the gettext container:
require_once 'Translation2.php'; $params = array( 'prefetch' => false, 'langs_avail_file' => 'path/to/langs.ini', 'domains_path_file' => 'path/to/domains.ini', 'default_domain' => 'messages', //'file_type' => 'po', ); // Better set prefetch to FALSE for the gettext container, so we don't need // to read in the whole MO file with File_Gettext on every request. $tr =& Translation2::factory('gettext', $params); $tr->setLang('en'); // Note that, if there is no translation available for a string, the gettext // container will return the string ID! This behaviour emulates native gettext. echo $tr->get('mystring'); print_r($tr->getPage('3rddomain')); |
The XML container requires PEAR::XML_Serializer 0.13.0 or newer, make sure you have it installed.
$driver = 'XML'; $options = array( 'filename' => 'i18n.xml', 'save_on_shutdown' => true, //set to FALSE to save in real time ); require_once 'Translation2.php'; $tr =& Translation2::factory($driver, $options); |
Type of the storage driver ('db', 'mdb', 'mdb2', 'gettext', 'dataobjectsimple')
Additional options for the storage driver (example: if you are using DB as the storage driver, you have to pass the dsn string here)
Array of parameters for the adapter class (i.e. you can set here the mappings between your table/field names and the ones used by this class)
Fetch the string from the container. If the string is empty and the DefaultText decorator is used, then return the $defaultText.
Text to display when the string is empty. NB: This parameter is only used in the DefaultText decorator
This method is used to get a decorator instance. A decorator can be seen as a filter, i.e. something that can change or handle the values of the objects/vars that pass through.
Name of the decorator
Object to decorate (the default object being $this)
Get some extra information about the language (its full name, the localized error text, ...)
Get some extra information about the languages (their full names, the localized error text, their codes...)
Same as getRawPage(), but resort to fallback language and replace parameters when needed.
NB: in Translation2 lingo, a "page" is just a logical "group of strings", it doesn't have to be a "phisical" (HTML or whatever) page.
Text to display when the string is empty
Fetch the page (aka 'group of strings') from the container, without applying any formatting and without replacing the parameters.
This is NOT the stringID, this is a real string. The method will return its matching stringID.
Set the charset that shall be used when retrieving strings. Currently only used by the MDB2 container.
Set the page (aka 'group of strings') that shall be used when retrieving strings. If you set it, you don't have to state it in each get() call.
Set the replacement for the parameters in the string(s). Parameter delimiters are customizable.
Translation2_Admin
Translation2_Admin Inherited Methods
Таблица 45-1. Inherited from Translation2
Method Name | Summary |
---|---|
Constructor Translation2::Translation2() | Constructor (deprecated in favour of factory()) |
Factory Translation2::factory() | Return a Translation2 instanciated object |
Translation2::get() | Get translated string |
Translation2::getDecorator() | Return an instance of a decorator |
Translation2::getLang() | get language info |
Translation2::getLangs() | get available languages |
Translation2::getPage() | Same as getRawPage(), but resort to fallback language and replace parameters when needed |
Translation2::getRaw() | Get translated string (as-is) |
Translation2::getRawPage() | Get the array of strings in a page |
Translation2::setCharset() | Set the correct charset in the database |
Translation2::setLang() | Set default lang |
Translation2::setPageID() | Set default page |
Translation2::setParams() | Set parameters for next string |
Translation2::getStringID() | Get the stringID for a given string |
array( 'lang_id' => 'en', 'table_name' => 'i18n', 'name' => 'english', 'meta' => 'some meta info', 'error_text' => 'not available', 'encoding' => 'iso-8859-1', ); |
array( 'charset' => 'latin1', 'collation' => 'latin1_bin', ); |
array( 'lang_id' => 'en', 'table_name' => 'i18n', 'name' => 'english', 'meta' => 'some new meta info', 'error_text' => 'text not available', 'encoding' => 'iso-8859-15', ); |
If the strings table holds other languages and $force==FALSE, then only the lang column is dropped. If $force==TRUE, the whole table is dropped without any check
Add a new translated string (or a set of translated strings) for a given stringID. For instance, to add the English, Spanish and Italian translations for the stringID 'example', use the following code:
$stringArray = array( 'en' => 'example', 'es' => 'ejemplo', 'it' => 'esempio', ); $tr->add('example', 'mypage', $stringArray); |
identificator for the string
destination pageID, i.e. the group of strings where this string belongs to.
Associative array with string translations.
ID of the string to translate
ID of the page (or group) the string to translate belongs to
Associative array with string translations:
array( 'en' => 'sample', 'it' => 'esempio', ); |
If you use the CacheLiteFunction decorator, you may want to invalidate the cache after a change in the data base.
This method is used to get a decorator instance. A decorator can be seen as a filter, i.e. something that can change or handle the values of the objects/vars that pass through.
Name of the decorator
Object to decorate (the default object being $this)
Create a subclass of this class for your own "decoration". The base class acts as a proxy to these methods:
get()
getDecorator()
getLang()
getLangs()
getPage()
getRaw()
getRawPage()
getStringID()
replaceEmptyStringsWithKeys()
setCharset()
setContainerOptions() [protected]
setLang()
setOption()
setOptions() [protected]
setPageID()
setParams()
translate()
Translation2_Decorator
Таблица 45-1. Classes that extend Translation2_Decorator
Class | Summary |
---|---|
Translation2_Decorator_CacheLiteFunction | Decorator to cache fetched data using Cache_Lite_Function class |
Translation2_Decorator_CacheMemory | Decorator to cache fetched data in memory |
Translation2_Decorator_DefaultText | Decorator to provide a fallback text for empty strings. |
Translation2_Decorator_ErrorText | Decorator to provide an error_text message for empty strings. |
Translation2_Decorator_Iconv | Decorator to switch from/to different encodings. |
Translation2_Decorator_Lang | Decorator to provide a fallback language for empty strings. |
Translation2_Decorator_SpecialChars | Decorator to replace special chars with the matching html entities. |
Translation2_Decorator_UTF8 | Decorator to convert UTF-8 strings to ISO-8859-1 |
This decorator provides a very efficient cache layer. It requires PEAR::Cache_Lite. It supports all the main options supported by Cache_Lite:
lifeTime [integer]
cacheDir [string]
fileLocking [boolean]
caching [boolean]
$tr = new Translation2($driver, $dbinfo, $params); $tr =& $tr->getDecorator('CacheLiteFunction'); $tr->setOption('cacheDir', '/var/tmp/'); $tr->setOption('lifeTime', 3600*24*7); //one week //change a custom Cache_Lite option $tr->setCacheOption($name, $value); |
This decorator provides a memory cache layer. It does NOT persist through requests, only in the current execution of the script. You can turn off prefetch if you want small network load (but it will increase the number of queries to the database)
$tr = new Translation2($driver, $dbinfo, $params); $tr =& $tr->getDecorator('CacheMemory'); $tr->setOption('prefetch', true); //default value is true |
When the fetched string is empty, it replaces it with the 4th parameter of the get() method, i.e. $defaultText. If the defaultText parameter is empty too, then return "$emptyPostfix.$outputString.$emptyPrefix", the three variables being class properties you can set to a custom string.
When getPage() is called, all the empty strings in the page are replaced by their stringID value.
$tr = new Translation2($driver, $dbinfo, $params); $tr =& $tr->getDecorator('DefaultText'); // %stringID% will be replaced with the stringID // %pageID_url% will be replaced with the pageID // %stringID_url% will replaced with a urlencoded stringID // %url% will be replaced with the targeted url $tr->outputString = '%stringID%<a href="%url%">(T)</a>'; //default: '%stringID%' $tr->url = '#'; //same as default $tr->emptyPrefix = '['; //default: empty string $tr->emptyPostfix = ']'; //default: empty string |
When the fetched string is empty, it replaces it with the contents of the "error_text" column of the langs_avail table
$tr = new Translation2($driver, $dbinfo, $params); $tr =& $tr->getDecorator('ErrorText'); |
This decorator is very useful when you want to provide a fallback language for empty strings. It is stackable, so you can have more than one default language. Use setOption() with the fallbackLang parameter to specify the fallback language of the current decorator.
$tr = new Translation2($driver, $dbinfo, $params); //set English as the main language $tr->setLang('en'); //set Italian as the first fallback language $tr =& $tr->getDecorator('Lang'); $tr->setOption('fallbackLang', 'it'); //set Spanish as the second fallback language $tr =& $tr->getDecorator('Lang'); $tr->setOption('fallbackLang', 'es'); |
Use setOption() with the encoding parameter to specify the target encoding of the current decorator.
$tr = new Translation2($driver, $dbinfo, $params); //set Hungarian as the main language $tr->setLang('hu'); //encode all the strings using the ISO-8859-2 charset $tr =& $tr->getDecorator('Iconv'); $tr->setOption('encoding', 'ISO-8859-2'); |
This decorator replaces special chars with the matching html entities. Use setOption() with the charset parameter to specify the target charset of the current decorator (the default is 'ISO-8859-1'):
$tr = new Translation2($driver, $dbinfo, $params); $tr =& $tr->getDecorator('SpecialChars'); $tr->setOption('charset', 'UTF-8'); |
This decorator calls utf8_decode() on each string
$tr = new Translation2($driver, $dbinfo, $params); $tr =& $tr->getDecorator('UTF8'); |
Таблица 45-1. Constants defined in DecoratorCacheMemory.php
Name | Value | Line Number |
---|---|---|
TRANSLATION2_EMPTY_PAGEID_KEY | 'array_key_4_empty_pageID' | 34 |
TRANSLATION2_NULL_PAGEID_KEY | 'array_key_4_null_pageID' | 40 |
Таблица 45-2. Constants defined in Translation2.php
Name | Value | Line Number |
---|---|---|
TRANSLATION2_DEFAULT_PAGEID | 'translation2_default_pageID' | 38 |
TRANSLATION2_ERROR | -1 | 43 |
TRANSLATION2_ERROR_METHOD_NOT_SUPPORTED | -2 | 44 |
TRANSLATION2_ERROR_CANNOT_CONNECT | -3 | 45 |
TRANSLATION2_ERROR_CANNOT_FIND_FILE | -4 | 46 |
TRANSLATION2_ERROR_DOMAIN_NOT_SET | -5 | 47 |
TRANSLATION2_ERROR_INVALID_PATH | -6 | 48 |
TRANSLATION2_ERROR_CANNOT_CREATE_DIR | -7 | 49 |
TRANSLATION2_ERROR_CANNOT_WRITE_FILE | -8 | 50 |
TRANSLATION2_ERROR_UNKNOWN_LANG | -9 | 51 |
Provides Packages for logging purposes
Implements both an abstraction for various logging mechanisms and the Subject end of a Subject-Observer pattern.
The full online documentation is available at the maintainer's website: http://www.indelible.org/pear/Log/guide.php.
Предоставляет пакеты для создания писем и работы с электронной почтой.
An interface for sending EMails
Mail supports different types of backends to send email. So two steps are necessary to send an email.
Mail supports three types of backends:
Sends a mail using PHP's built-in mail() function.
sendmail
Sends a mail using a sendmail program.
smtp
Sends a mail directly connecting to a smtp server.
string $backend - the name of the backend "mail","smtp", "sendmail"
array $params - a array of backend specific parameters.
List of parameter for the backends
If safe mode is disabled, $params will be passed as the fifth argument to the PHP mail() function. If $params is an array, its elements will be joined as a space-delimited string.
sendmail
$params["sendmail_path"] - The location of the sendmail program on the filesystem. Default is /usr/bin/sendmail
$params["sendmail_args"] - Additional parameters to pass to the sendmail. Default is -i
smtp
$params["host"] - The server to connect. Default is localhost
$params["port"] - The port to connect. Default is 25
$params["auth"] - Whether or not to use SMTP authentication. Default is FALSE
$params["username"] - The username to use for SMTP authentication.
$params["password"] - The password to use for SMTP authentication.
$params["localhost"] - The value to give when sending EHLO or HELO. Default is localhost
$params["timeout"] - The SMTP connection timeout. Default is NULL (no timeout)
$params["verp"] - Whether to use VERP or not. Default is FALSE
$params["debug"] - Whether to enable SMTP debug mode or not. Default is FALSE
$params["persist"] - Indicates whether or not the SMTP connection should persist over multiple calls to the send() method.
Таблица 47-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
NULL | "Unable to find class for driver xxx" | Mailer backend class was not found. | Check the $backend parameter, if correct reinstall and/or update your Mail package. |
mixed $recipients - an array or a string with comma separated recipients.
array $headers - an associative array of headers. The header name is used as key and the header value as value.
string $body - the body of the email.
Таблица 47-1. Возможные значения PEAR_Error
Mailer driver | Error code | Error message | Reason | Solution | |
---|---|---|---|---|---|
sendmail | NULL | "No from address given." | The $headers array requires at least a from entry. |
Add a From header:
| |
sendmail | NULL | "From address specified with dangerous characters." | The from entry in the $headers array contains one ore more characters which could be non-RFC compliant | Check the given from address for characters like: spaces or ; or & or ` (backtick) | |
sendmail | NULL | "sendmail [path to sendmail] not executable" | The path to sendmail program is not correct. No sendmail executable found there. | Check the $param['sendmail_path'] entry in your Mail::factory() call. If you use another mailer then sendmail, ie. qmail, check installation of the mailer. Normally it should includes a sendmail wrapper. | |
sendmail | NULL | "sendmail returned error code code" | Sendmail returns a error, which must be handled by use. | See the documention of your mailer programm. | |
smtp | PEAR_MAIL_SMTP_ERROR_CREATE | "Failed to create a Net_SMTP object" | Failure in class creation | Reinstall/update the Net_SMTP package. | |
smtp | PEAR_MAIL_SMTP_ERROR_CONNECT | "Failed to connect to host:port" | Connect to SMTP server failed | Check $param['port'] and $param['host'] entries in your Mail::factory() call. | |
smtp | PEAR_MAIL_SMTP_ERROR_AUTH | "method authentication failure" | Authentication failed | Check $param['auth'], $param['username'] and $param['password'] entries in your Mail::factory() call. Ensure to use the correct authentication method for the SMTP server. | |
smtp | PEAR_MAIL_SMTP_ERROR_FROM | "No From: address has been provided" | The $headers array requires at least a from entry. |
Add a From header:
| |
smtp | PEAR_MAIL_SMTP_ERROR_SENDER | "Failed to set sender: from" | Setting the sender address failed | Check the RFC-compliances of the sender address and the server connnectivity. | |
smtp | PEAR_MAIL_SMTP_ERROR_RECIPIENT | "Failed to add recipient: recipient " | Sending of recipient address failed | Check the RFC-compliances of the recipient address and the server connnectivity. | |
smtp | PEAR_MAIL_SMTP_ERROR_DATA | "Failed to send data" | Body of the mail message could not send | Check the RFC-compliances of the message body and the server connnectivity. |
<?php include('Mail.php'); $recipients = 'joe@example.com'; $headers['From'] = 'richard@example.com'; $headers['To'] = 'joe@example.com'; $headers['Subject'] = 'Test message'; $body = 'Test message'; $params['sendmail_path'] = '/usr/lib/sendmail'; // Create the mail object using the Mail::factory method $mail_object =& Mail::factory('sendmail', $params); $mail_object->send($recipients, $headers, $body); ?> |
This class performs email address checking according to the RFC822 specification.
Note that the class only checks for a proper format of the indicated email address. This means it is not guaranteed that the email address itself exists or is owned by the particular user. You may also want to send the user an email, and force them to respond.
string $address - the address(es) to validate
string $defaultDomain - the default domain to use in case of absence in the given email address.
boolean $nestGroups - whether to return the structure with groups nested for easier viewing.
boolean $validate - whether to validate atoms. Turn this off if you need to run addresses through before encoding the personal names, for instance.
array - a nested array of anonymous objects.
If $nestGroups set to FALSE, you can jump over the next paragraph.
Every array entry contains an object per group. This object has two attributes:
groupname - the name of the group |
addresses - an array of all addresses of a group |
The addresses array consists of an array of anonymous objects for each address. This object comes with the following attributes:
personal - the name of the address owner |
comment - an array, an entry for each comment per address |
mailbox - the name of the mailbox, the part before the @ |
host - the name of the server, the part after the @ |
Таблица 47-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
NULL | every | The given address string is not RFC822 compliant | The error code contains a description of the error. |
Эта функция может быть вызвана статически.
Внимание |
This class checks the string only. It does not check for the existence of an email address. |
Пример 47-1. Extract some addresses
|
A Package to enable easy creation of complex multipart emails. If you look for a simple API for creating such emails, then Mail_Mime class will probably suffice. Else you can use Mail_mimePart, which gives you better control about MIME creation.
Mail_mimeDecode provides a API for decode MIME data.
Normally, it is not necessary to set the $crlf parameter. But, if you want to send the generated MIME message using Mail then you have to set $crlf to "\n"
string $file - The file name or the data itself
string $c_type - The content type of the image or file.
string $name - The suggested file name for the data. Only used, if $file contains data.
boolean $isfile - Whether $file is a file name or not.
string $encoding - Type of transfer encoding to use for the file data. Defaults is "base64". For text based files (eg. scripts/html etc.) this could be given as "quoted-printable".
Таблица 47-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
NULL | "File is not readable file_name" | The file was not found or the script has not enough rights to access the file. | Check the file name and path. Check user and file permissions. |
NULL | "Could not open file_name" | The file is already opened and exclusivly locked by another application. | In the most cases a program opens the file for writing. addAttachment() does no file locking, so this problem is not caused by competitive callings of this function. |
string $file - The image file name or the image data itself
string $c_type - The content type of the image or file.
string $name - The filename of the image. Only used, if $file contains the image data.
boolean $isfile - Whether $file is a filename or not.
Таблица 47-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
NULL | "File is not readable file_name" | The file was not found or the script has not enough rights to access the file. | Check the file name and path. Check user and file permissions. |
NULL | "Could not open file_name" | The file is already opened and exclusivly locked by another application. | In the most cases a programm opens the file for writing. addHTMLImage() does no file locking, so this problem is not caused by competitve callings of this function. |
This function should be called once you have added the text/html/images/attachments. It builds the message and returns it. It does not send it. To send what this function returns (in conjunction with the headers() -function) you would need to use the Mail::send()-function
array $param - An associative array of parameters. These parameters affect the way the message is built.
$param["text_encoding"] - Type of encoding to use for the plain text part of the email. Default is "7bit".
$param["html_encoding"] - Type of encoding for the HTML part of the email. Default is "quoted-printable".
$param["7bit_wrap"] - Number of characters after which text is wrapped. SMTP stipulates maximum line length of 1000 characters including CRLF. Default is 998 (CRLF is appended to make up to 1000).
$param["head_charset"] - The character set to use for the headers. Default is "iso-8859-1".
$param["text_charset"] - The character set to use for the plain text part of the email. Default is "iso-8859-1".
$param["html_charset"] - The character set to use for the HTML part of the email. Default is "iso-8859-1".
Returns an array with the headers needed to prepend to the email (MIME-Version and Content-Type). Please note that the function get() has to be called before calling headers().
array $headerEx - Additional headers, the format of the argument is $array["header-name"] = "header-value"
array - an associative array with the mime headers and the additional headers. The return value can directly passed to the second parameter of Mail::send().
Эта функция не должна вызываться статически.
Внимание |
Mail_Mime::headers() has to be called after Mail_Mime::get(). |
string $data - The text to set or, if $isfile is TRUE a valid filename. An URL as argument is not allowed.
boolean $isfile - If TRUE, the content of given file $data is used as message text.
Таблица 47-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
NULL | "File is not readable file_name" | The file was not found or the script has not enough rights to access the file. | Check the file name and path. Check user and file permissions. |
NULL | "Could not open file_name" | The file is already opened and exclusivly locked by another application. | In the most cases a programm opens the file for writing. setHTMLBody() does no file locking, so this problem is not caused by competitve callings of this function. |
string $data - The text to set or, if $isfile is TRUE a valid filename. An URL as argument is not allowed.
boolean $isfile - If TRUE, the content of given file $data is used as message text.
Таблица 47-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
NULL | "File is not readable file_name" | The file was not found or the script has not enough rights to access the file. | Check the file name and path. Check user and file permissions. |
NULL | "Could not open file_name" | The file is already opened and exclusivly locked by another application. | In the most cases a programm opens the file for writing. setTxtBody() does no file locking, so this problem is not caused by competitve callings of this function. |
<?php include('Mail.php'); include('Mail/mime.php'); $text = 'Text version of email'; $html = '<html><body>HTML version of email</body></html>'; $file = '/home/richard/example.php'; $crlf = "\n"; $hdrs = array( 'From' => 'you@yourdomain.com', 'Subject' => 'Test mime message' ); $mime = new Mail_mime($crlf); $mime->setTXTBody($text); $mime->setHTMLBody($html); $mime->addAttachment($file, 'text/plain'); //do not ever try to call these lines in reverse order $body = $mime->get(); $hdrs = $mime->headers($hdrs); $mail =& Mail::factory('mail'); $mail->send('postmaster@localhost', $hdrs, $body); ?> |
string $body - The body of the mime part if any. Default is an empty string.
array $params - An associative array of parameters:
$params["content_type"] - The content type for this part ie. multipart/mixed
$params["encoding"] - The encoding to use ie. 7bit, 8bit, base64 or quoted-printable
$params["cid"] - content ID to apply
$params["disposition"] - Content disposition inline or attachment
$params["dfilename"] - Optional filename parameter for content disposition
$params["description"] - Content description
$params["charset"] - Character set to use
string - the body of the sub part
array - the parameter for the sub part. See constructor for the possible values.
Пример 47-1. Add two attachments to a mail
|
array - an associative array containing two elements, body and headers. The headers element is itself an indexed array.
The key names are
'headers' - an array with the mail headers |
'body' - a string with the mail body |
array $args - an array with the function arguments
boolean $args['include_bodies'] - whether to include the bodies in the returned structure.
boolean $args['decode_bodies'] - whether to decode the returned bodies.
boolean $args['decode_headers'] - whether to decode the headers (RFC2047).
string $args['input'] - if and only if called statically, this should be used to specify the input to be decoded.
string $args['crlf'] - if and only if called statically, this should be used to specify the line ending type.
object -
array $return->headers - an associative array of the headers. The keys of the array are the header names (lowercased) whilst the values are the header values (original case). If there are multiple headers with the same name (eg. Received: ) then the value is a numerically indexed array of each of the header values. If the parameter decode_headers is specified as TRUE, the headers will be decoded according to RFC 2047.
string $return->ctype_primary - the first part of the content type (ie. before the forward slash). Eg. if the content type is multipart/mixed, ctype_primary would be "multipart".
string $return->ctype_secondary - the second part of the content type. Eg. If the content type is multipart/mixed, ctype_secondary would be "mixed".
array $return->ctype_parameters - if the content type header has any parameters (eg. boundary="=_hudfhdsalfhds8fy8329hfj") then they will be in this associative array. Keys are the parameter name (eg. boundary) whilst the values are the parameter values (eg. =_hudfhdsalfhds8fy8329hfj).
string $return->disposition - if the Content-Disposition header is present, its value will be given here. This is usually either "inline" or "attachment".
array $return->d_parameters - if any parameters are given with the Content-Disposition header, they will be given here in an associative array, keys being the parameter names and values being the parameter values. "name" and "filename" are two common examples here.
array $return->body - if the include_bodies parameter is given when instanciating the class, (either statically or via a concrete instance), then this will be present if the part in question has a body. MIME parts with content type multipart/* generally do not not have bodies, instead consisting of subparts. If the parameter decode_bodies is specified as TRUE then the body will be decoded.
array $return->parts - if a MIME part consists of subparts, then this array will be present consisting of objects with the same properties as described here.
Таблица 47-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
NULL | " Called statically and no input given " | You called the function statically and forgot to fill $args['input'] | Fill $args['input'] with the content to decode or do not call the function statically. |
NULL | every other | See the error message. | The input or parts of the input does not complies to the MIME standard. |
Decodes UU-coded data. 'Unix-to-Unix'-Encoding is used to send binary files (eg. programs, graphics) over 7bit-ASCII-only media, like email.
array - the decoded data
string $return[]['filename'] - the name of the UUencoded file.
string $return[]['fileperm'] - the file permissions of the UUencoded file, if given. The format is unix-styled, ie. "0666" or "666".
string $return[]['filedata'] - the decoded content of the UUencoded file.
Пример 47-1. Create a XML representation
|
Пример 47-1. Decode an email
This example calls the decode function statically (ie no object, straight function call) and then passes the structure to the getXML() function.
|
Предоставляет пакеты для работы с сетью.
Package to check the correct syntax of an IPv4 address.
Пример 49-1. Using check_ip()
|
Finger is a service providing information about a user of a server. The finger-protocol is deactivated on the most Internet servers due to security reasons. So it makes especially sense for intranets and local host administration.
The output of the finger command depends on the system and less standarized, because the output should be easy to read for humans and not for machines.
string $server - The name of the server or the IP-adress
string $query - The finger object to look up
The returned PEAR_Error object in case of an error is unspecific, so you can ignore the error code and/or message. The reason for a failure could be a failed connection to the server or the server did not run a finger service.
Замечание: You will not get a PEAR_Error, if the query fails due to a not existing finger object. This can be only done by checking the data returned by query().
Пример 49-1. Using query()
|
Provides function to work with the 'Internet Protocol v6'
Compresses an IPv6 address. RFC 2373 allows you to compress zeros in an address to '::'. This function expects an valid IPv6 address and compresses successive zeros to '::'
FF01:0:0:0:0:0:0:101 -> FF01::101 0:0:0:0:0:0:0:1 -> ::1 |
Uncompresses an IPv6 address. RFC 2373 allows you to compress zeros in an address to '::'. This function expects an valid IPv6 address and expands the '::' to the required zeros.
FF01::101 -> FF01:0:0:0:0:0:0:101 ::1 -> 0:0:0:0:0:0:0:1 |
RFC 1883, Section 2.3 describes several types of addresses in the IPv6 addresse space. This methods tries to find the type of address for the given IP.
Внимание |
Several address types are markers for reserved spaces and as consequence a subject to change. |
int - the addresstype
The type can be one of this constants:
NET_IPV6_MULTICAST
NET_IPV6_UNICAST_PROVIDER
NET_IPV6_LOCAL_LINK
NET_IPV6_LOCAL_SITE
NET_IPV6_UNKNOWN_TYPE
NET_IPV6_RESERVED_UNICAST_GEOGRAPHIC
NET_IPV6_RESERVED_IPX
NET_IPV6_RESERVED
NET_IPV6_RESERVED_NSAP
NET_IPV6_UNASSIGNED
string $ip - the IP address in Hex format, compressed IPs are allowed
int $bits - if the number of netmask bits is not part of the IP, you must provide the mumber of bits
Checks if an (compressed) IP is in a specific address space. If the IP does not contain the number of netmask bits (for example: F8000::FFFF/16), then you have to use the $bits parameter.
string $ip - the IP address in Hex format, compressed IPs are allowed
string $netmask - the netmask (for example: F800::)
int $bits - if the number of netmask bits is not part of the IP, you must provide the mumber of bits
Splits an IPv6 address into the IPv6 and a possible IPv4-formated part. RFC 2373 allows you to note the last two parts of an IPv6 address in the IPv4 address format.
0:0:0:0:0:0:13.1.68.3 0:0:0:0:0:FFFF:129.144.52.38 |
Implementation of the NNTP protocol
Замечание: The Net_NNTP class is considered deprecated as of v0.10.x; Net_NNTP_Client should be used instead in new applications. A 'backport' of Net_NNTP_Client has replaced Net_NNTP to maintain backward compatibility, but this is temporary and will only last for some time.
NNTP client implementation
require_once 'Net/NNTP/Client.php';
publicbooleanNet_NNTP_Client::authenticatestring$userstring$passinteger$authmode = NET_NNTP_AUTHORIGINAL
$user - Username to authenticate with
$pass - Password to authenticate with
$authmode - Type of authentication. Default=NET_NNTP_AUTHORIGINAL
require_once 'Net/NNTP/Client.php'; |
boolean Net_NNTP_Client::connect
([string $host = NET_NNTP_PROTOCOL_DEFAULT_HOST [, integer $port = NET_NNTP_PROTOCOL_DEFAULT_PORT]])
$host - Hostname of the NNTP-server. Default=NET_NNTP_PROTOCOL_DEFAULT_HOST
$port - Port, where the NNTP-server listens. Default=NET_NNTP_PROTOCOL_DEFAULT_PORT
Таблица 49-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
NULL | "Could not connect to NNTP-server $host" or "Not connected" |
The connection couldn't be established because
| Check for server name, the connection to the net and possible firewalls on client or server side. |
Пример 49-1. Using connect()
|
require_once 'Net/NNTP/Client.php'; |
boolean Net_NNTP_Client::connectAuthenticated
([integer $user = NULL [, integer $pass = NULL [, string $host = NET_NNTP_PROTOCOL_DEFAULT_HOST [, integer $port = NET_NNTP_PROTOCOL_DEFAULT_PORT [, integer $authmode = NET_NNTP_AUTHORIGINAL]]]]])
Connect and authenticate to a specific NNTP-server
Внимание |
Эта функция объявлена как deprecated. Это означает, что в будущих версиях пакета она может больше не поддерживаться. |
$user - Username to authenticate
$pass - Password to authenticate
$host - Hostname of the NNTP-server. Default=NET_NNTP_PROTOCOL_DEFAULT_HOST
$port - Port, where the NNTP-server listens. Default=NET_NNTP_PROTOCOL_DEFAULT_PORT
$authmode - Type of authentication. Default=NET_NNTP_AUTHORIGINAL
Таблица 49-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
NULL | "Could not connect to NNTP-server $host" or "Not connected" |
The connection couldn't be established because
| Check for server name, the connection to the net and possible firewalls on client or server side. |
Пример 49-1. Using connectauthenticated()
|
Пример 49-1. Using count()
|
Пример 49-1. Using first()
|
string $article - article number or Message-ID of the article to fetch
boolean $implode - Determines if the resulting array is to be imploded into a string.
Таблица 49-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
NULL | Different error messages | The messages are directly passed from the news server, in the most cases caused by calling a non existing article |
Net_NNTP_Client::getArticle() , Net_NNTP_Client::getHeaderRaw() , Net_NNTP_Client::getBodyRaw()
Пример 49-1. Using getArticleRaw()
|
string $article - article number or Message-ID of the article to fetch
boolean $implode - Determines if the resulting array is to be imploded into a string.
Таблица 49-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
NULL | Different error messages | The messages are directly passed from the news server, in the most cases caused by calling a non existing article |
since 0.3
Эта функция не должна вызываться статически.
Замечание: getBody() makes no converting of the body content to any character set. You get the content 'as is'.
Пример 49-1. Using getBodyRaw()
|
Таблица 49-1.
$format | returns |
---|---|
0 | timestamp |
1 |
array - a hash with the date
|
Пример 49-1. Using getDate()
|
array - a two dimensional, nested array indicated by the name of the newsgroup, every entry contains information about the newsgroup:
$groups[newsgroup_name]['group'] Name of the newsgroup
$groups[newsgroup_name]['last'] Number of the last article
$groups[newsgroup_name]['first'] Number of the first article
$groups[newsgroup_name]['posting'] values: y - yes, n - no, m - moderated)
Эта функция не должна вызываться статически.
Внимание |
Especially public news server can provide more then 30.000 newsgroup. So this function may runs longer then the maximum execution time set in the php.ini. |
Пример 49-1. Using getGroups()
|
string $article - article number or Message-ID of the article to fetch
boolean $implode - Determines if the resulting array is to be imploded into a string.
Таблица 49-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
NULL | Different error messages | The messages are directly passed from the news server, in the most cases caused by calling a non existing article |
Net_NNTP_Client::getHeader() , Net_NNTP_Client::getArticleRaw() , Net_NNTP_Client::getBodyRaw()
Пример 49-1. Using getHeaderRaw()
|
Returns (a certain range of) the overview of the currently selected newsgroup. selected newsgroup
$first - first article number, start of the range
$last - last article number, end of the range
array - a nested array indicated by the message id of the article, every entry contains the header as array
$msgs[message_id][headername] = headercontent |
Эта функция не должна вызываться статически.
Внимание |
Be careful with choosing the range. It could requires some time to get a huge number of message headers. |
Пример 49-1. Using getOverview()
|
require_once 'Net/NNTP/Client.php';
publicbooleanNet_NNTP_Client::groupstring$userstring$passinteger$authmode = NET_NNTP_AUTHORIGINALВнимание |
Этот метод не документирован на данный момент. |
Внимание |
Эта функция является ЭКСПЕРИМЕНТАЛЬНОЙ. Это означает, что ее поведение, имя и ВСЕ остальное может быть изменено в будущем без каких-либо уведомлений. Вы можете использовать эту функцию только на свой страх и риск. |
Пример 49-1. Using last()
|
array - If the newsgroup exists, an array is returned:
Таблица 49-1.
Key | Value |
---|---|
'count' | Number of articles in the group |
'first' | The first article number in the group |
'last' | The last article number in the group |
'group' | Groupname |
Таблица 49-2. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
NULL | Different error messages | The messages are directly passed from the news server, in the most cases caused by calling a non existing article |
Пример 49-1. Using selectGroup()
|
Внимание |
Эта функция объявлена как deprecated. Это означает, что в будущих версиях пакета она может больше не поддерживаться. |
The historical Net_NNTP class
Command() sends a string command to a newsserver. So you can send customized and/ or non-standard commands to the newsserver.
string $cmd - the command to send
boolean $auth - if TRUE, an auth request is issued before the command
Эта функция не должна вызываться статически.
Внимание |
Command() does no checks on the given command and/ or proccesses the server response. So you should know what are you doing. |
Таблица 49-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
NULL | "Could not connect to NNTP-server $host" or "Not connected" |
The connection couldn't be established because
| Check for server name, the connection to the net and possible firewalls on client or server side |
Пример 49-1. Using connect()
|
$user - Username to authenticate
$pass - Password to authenticate
$host - Hostname of the NNTP-server
$port - Port, where the newsserver listens
$authmode - Type of authentication, at the moment only NET_NNTP_AUTHORIGINAL
Таблица 49-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
NULL | "Could not connect to NNTP-server $nntpserver" or "Not connected" |
The connection couldn't be established because
| Check for server name, the connection to the net and possible firewalls on client or server side |
Пример 49-1. Using connectauthenticated()
|
Внимание |
Эта функция объявлена как deprecated. Это означает, что в будущих версиях пакета она может больше не поддерживаться. |
Retrieves the date from the news server
Пример 49-1. Using date()
|
Пример 49-1. Using first()
|
Returns the whole article from the current selected newsgroup
Внимание |
Эта функция объявлена как deprecated. Это означает, что в будущих версиях пакета она может больше не поддерживаться. |
Consider this method deprecated and subject to changes - use Net_NNTP::getArticleRaw() instead.
Таблица 49-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
NULL | Different error messages | The messages are directly passed from the news server, in the most cases caused by calling a non existing article | Check the article ID or if your are still connected to the server ( Net_NNTP::isConnected()) |
Пример 49-1. Using getArticle()
|
Таблица 49-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
NULL | Different error messages | The messages are directly passed from the news server, in the most cases caused by calling a non existing article | Check the article ID or if your are still connected to the server ( Net_NNTP::isConnected()) |
Пример 49-1. Using getArticleRaw()
|
Returns the whole body of an article in the current selected newsgroup from the webserver
Внимание |
Эта функция объявлена как deprecated. Это означает, что в будущих версиях пакета она может больше не поддерживаться. |
Consider this method deprecated and subject to changes - use Net_NNTP::getBodyRaw() instead.
Таблица 49-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
NULL | Different error messages | The messages are directly passed from the news server, in the most cases caused by calling a non existing article | Check the article ID or if your are still connected to the server ( Net_NNTP::isConnected()) |
Эта функция не должна вызываться статически.
Замечание: getBody() makes no converting of the body content to any character set. You get the content 'as is'.
Net_NNTP::getHeaders() , Net_NNTP::splitHeaders() , Net_NNTP::getArticle() , Net_NNTP::getOverview()
Пример 49-1. Using getBody()
|
Таблица 49-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
NULL | Different error messages | The messages are directly passed from the news server, in the most cases caused by calling a non existing article | Check the article ID or if your are still connected to the server ( Net_NNTP::isConnected()) |
since 0.3
Эта функция не должна вызываться статически.
Замечание: getBody() makes no converting of the body content to any character set. You get the content 'as is'.
Net_NNTP::getHeaderRaw() , Net_NNTP::splitHeaders() , Net_NNTP::getArticleRaw() , Net_NNTP::getOverview()
Пример 49-1. Using getBodyRaw()
|
Пример 49-1. Using getDate()
|
array - a two dimensional, nested array indicated by the name of the newsgroup, every entry contains information about the newsgroup:
$groups[newsgroup_name]['group'] name of the newsgroup
$groups[newsgroup_name]['last'] message number of the last message
$groups[newsgroup_name]['first'] message number of the first message
$groups[newsgroup_name]['posting_allowed'] values: y - yes, n - no, m - moderated)
$groups[newsgroup_name]['desc'] newsgroup description
Эта функция не должна вызываться статически.
Внимание |
Especially public news server can provide more then 30.000 newsgroup. So this function may runs longer then the maximum execution time set in the php.ini. |
Пример 49-1. Using getGroups()
|
Таблица 49-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
NULL | Different error messages | The messages are directly passed from the news server, in the most cases caused by calling a non existing article | Check the article ID or if your are still connected to the server ( Net_NNTP::isConnected()) |
Пример 49-1. Using getHeaderRaw()
|
Returns all avaible header lines of a specified message in the current selected newsgroup
Внимание |
Эта функция объявлена как deprecated. Это означает, что в будущих версиях пакета она может больше не поддерживаться. |
Consider this method deprecated and subject to changes - use Net_NNTP::getHeaderRaw() instead.
Таблица 49-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
NULL | Different error messages | The messages are directly passed from the news server, in the most cases caused by calling a non existing article | Check the article ID or if your are still connected to the server ( Net_NNTP::isConnected()) |
Пример 49-1. Using getHeaders()
|
array - a nested array indicated by the message id of the article, every entry contains the header as array
$msgs[message_id][headername] = headercontent |
Эта функция не должна вызываться статически.
Внимание |
Be careful with choosing the range. It could requires some time to get a huge number of message headers. |
Пример 49-1. Using getOverview()
|
Пример 49-1. Using getOverviewFmt()
|
Пример 49-1. Using getOverviewFmt()
|
Пример 49-1. Using isConnected()
|
Пример 49-1. Using last()
|
Внимание |
Эта функция объявлена как deprecated. Это означает, что в будущих версиях пакета она может больше не поддерживаться. |
Retrieves the highest message number in the current selected newsgroup
Пример 49-1. Using max()
|
Внимание |
Эта функция объявлена как deprecated. Это означает, что в будущих версиях пакета она может больше не поддерживаться. |
Retrieves the lowest message number in the current selected newsgroup
Пример 49-1. Using min()
|
$subject - Subject of the message
$newsgroup - Post to this newsgroup
$from - EMail adress of sender
$body - Body of the message
$additional - String of headers to add
Таблица 49-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
NULL | "Not connected" | You forgot the set up a connection to a news server or the connection was already again closed. | Open a connection before using post(). Check the connection status before using post(). |
Эта функция не должна вызываться статически.
Внимание |
post() doesn't care about character encoding of subject and body. Make sure to set correct headers, if you are using non ASCII-127 characters. |
Пример 49-1. Using post()
|
Connect to a specific newsserver and access the given newsgroup
Внимание |
Эта функция объявлена как deprecated. Это означает, что в будущих версиях пакета она может больше не поддерживаться. |
Consider this method deprecated - use Net_NNTP::connectAuthenticated() instead.
$nntpserver - Name of the newsserver to connect
$port - Port, where the newsserver listens
$newsgroup - Newsgroup to access
$user - Username to authenticate
$user - Username to authenticate
$pass - Password to authenticate
$authmode - Type of authentication, at the moment only PEAR_NNTP_AUTHORIGINAL
Таблица 49-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
NULL | "Could not connect to NNTP-server $nntpserver" or "Not connected" |
The connection couldn't be established because
| Check for server name, the connection to the net and possible firewalls on client or server side |
NULL | Every other message | This message is directly passed from the news server, in the most cases caused by calling a non existing newsgroup | Check the given newsgroup name |
Эта функция не должна вызываться статически.
Внимание |
Эта функция объявлена как deprecated. Это означает, что в будущих версиях пакета она может больше не поддерживаться. |
Fetching data with a connection created with prepareConnection() is faster then a created connection with connect()
Пример 49-1. Using prepareConnection()
|
array - If the newsgroup exists an array containing the message number of the first (array key: ['first']) and the last message id (array key: ['last']) or a PEAR_Error, if fail.
Таблица 49-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
NULL | Different error messages | The messages are directly passed from the news server, in the most cases caused by calling a non existing article | Check the article ID or if your are still connected to the server ( Net_NNTP::isConnected()) |
Пример 49-1. Using selectGroup()
|
Returns all avaible header lines of a specified message of the current selected newsgroup into an array
array - if message exists the headers as array or a PEAR_Error, if fail. The array is an associative array with the header names as key.
Таблица 49-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
NULL | Different error messages | The messages are directly passed from the news server, in the most cases caused by calling a non existing article | Check the article ID or if your are still connected to the server ( Net_NNTP::isConnected()) |
Пример 49-1. Using splitHeaders()
|
Внимание |
Этот модуль является ЭКСПЕРИМЕНТАЛЬНЫМ. Это означает, что поведение его функций, имена функций и ВСЕ остальное может быть изменено в будущем без каких-либо уведомлений. Вы можете использовать этот модуль только на свой страх и риск. |
Этот пакет пока не документирован.
Внимание |
Этот модуль является ЭКСПЕРИМЕНТАЛЬНЫМ. Это означает, что поведение его функций, имена функций и ВСЕ остальное может быть изменено в будущем без каких-либо уведомлений. Вы можете использовать этот модуль только на свой страх и риск. |
Этот пакет пока не документирован.
Low level NNTP client implementation.
Этот пакет пока не документирован.
API for the Ping command
Пример 49-1. Sending a ping request
|
array $args - an array of the arguments to set
Таблица 49-1. possible array keys
Key name | Description | NOT supported on |
---|---|---|
"count" | Number of ping packages to send | |
"quiet" | Level of output verbosity | Windows |
"iface" | FreeBSD, Linux, Windows | |
"ttl" | ||
"timeout" | Time to wait for a ACK of a ping package | |
"size" | Size of a ping package | FreeBSD, Darwin, Linux, Windows |
Таблица 49-2. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
NULL | PING_INVALID_ARGUMENTS | A not supported argument was given | Check typing of argument (key name) and OS-support of the argument. |
Provides an API for scanning ports
This function checks if there is a service available at the specified port on the specified machine.
string $host - address of the host to check
string $port - port to check
string $timeout - time in seconds to wait for response from host
Важно: If you run into timeout problems despite setting this parameter to a reasonably high value, you need to make sure that the configuration directive default_socket_timeout in the php.ini configuration file does not force the maximum timeout down to a lower value.
Пример 49-1. Using checkPort
|
This function checks if there are services available at the specified ports on the specified machine.
string $host - address of the host to check
string $minPort - lowest port to test to check
string $maxPort - highest port to test to check
string $timeout - time in seconds to wait for every response from host
Важно: If you run into timeout problems despite setting this parameter to a reasonably high value, you need to make sure that the configuration directive default_socket_timeout in the php.ini configuration file does not force the maximum timeout down to a lower value.
Пример 49-1. Using checkPortRange
|
This function returns the port which corresponds to service for the specified protocol as per /etc/services.
Эта функция может быть вызвана статически.
The port number is retrieved from the machine where Net_Portscan is executed, not from the remote host, which you possibly used in Net_Portscan::checkPort().
This function returns the service associated with port for the specified protocol as per '/etc/services'.
Эта функция может быть вызвана статически.
The name of the service is retrieved from the machine where Net_Portscan is executed, not from the remote host, which you possibly used in Net_Portscan::checkPort().
Net_Socket provides a generic API for communication over TCP/IP-sockets.
Connect to the specified port. If called when the socket is already connected, it disconnects and connects again.
Таблица 49-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
every | every |
The connection could not be established because
| Check for server name, the connection to the net and possible firewalls on client or server side |
Таблица 49-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
NULL | "not connected" | The connection to close was not open or is already closed. | Ensure a sucessfull call of connect() |
Таблица 49-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
NULL | "not connected" | There is no open connection. | You must establish a connection before ( Net_Socket::connect()). |
array - the data as array or a PEAR_Error
The content of the array is:
boolean 'timed_out' - the socket timed out waiting for data
boolean 'blocked' - blocking mode
boolean 'eof' - indicates EOF event
integer 'unread_bytes' - number of bytes left in the socket buffer
Таблица 49-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
NULL | "not connected" | There is no open connection. | You must establish a connection before ( Net_Socket::connect()). |
Read a specified amount of data. This is guaranteed to return, and has the added benefit of getting everything in one fread() chunk; if you know the size of the data you're getting beforehand, this is definitely the way to go.
Таблица 49-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
NULL | "not connected" | There is no open connection. | You must establish a connection before ( Net_Socket::connect()). |
Read until the socket closes.
Внимание |
This function will not exit, if the socket is in blocking mode until the socket closes. |
Таблица 49-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
NULL | "not connected" | There is no open connection. | You must establish a connection before ( Net_Socket::connect()). |
Таблица 49-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
NULL | "not connected" | There is no open connection. | You must establish a connection before ( Net_Socket::connect()). |
Net_Socket::read() , Net_Socket::readWord() , Net_Socket::readInt() , Net_Socket::readString() , Net_Socket::readIPAddress()
Таблица 49-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
NULL | "not connected" | There is no open connection. | You must establish a connection before ( Net_Socket::connect()). |
Net_Socket::read() , Net_Socket::readByte() , Net_Socket::readWord() , Net_Socket::readString() , Net_Socket::readIPAddress()
Reads a IP from the socket. The function expects an integer which will converted to a IP address. This function only works with IPv4 addresses.
Таблица 49-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
NULL | "not connected" | There is no open connection. | You must establish a connection before ( Net_Socket::connect()). |
Net_Socket::read() , Net_Socket::readByte() , Net_Socket::readWord() , Net_Socket::readInt() , Net_Socket::readString()
Read until either the end of the socket or a newline, whichever comes first. Strips the trailing newline from the returned data.
Таблица 49-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
NULL | "not connected" | There is no open connection. | You must establish a connection before ( Net_Socket::connect()). |
Таблица 49-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
NULL | "not connected" | There is no open connection. | You must establish a connection before ( Net_Socket::connect()). |
Net_Socket::read() , Net_Socket::readByte() , Net_Socket::readWord() , Net_Socket::readInt() , Net_Socket::readIPAddress()
Таблица 49-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
NULL | "not connected" | There is no open connection. | You must establish a connection before ( Net_Socket::connect()). |
Эта функция не должна вызываться статически.
Замечание: "Word" means not a word in literary sense. A word is a statment of size for data.
Net_Socket::read() , Net_Socket::readByte() , Net_Socket::readInt() , Net_Socket::readString() , Net_Socket::readIPAddress()
Sets whether the socket connection should be blocking or not. A read call to a non-blocking socket will return immediately if there is no data available, whereas it will block until there is data for blocking sockets.
Таблица 49-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
NULL | "not connected" | There is no open connection. | You must establish a connection before ( Net_Socket::connect()). |
Sets the timeout value on socket descriptor, expressed in the sum of seconds and microseconds.
Таблица 49-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
NULL | "not connected" | There is no open connection. | You must establish a connection before ( Net_Socket::connect()). |
Таблица 49-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
NULL | "not connected" | There is no open connection. | You must establish a connection before ( Net_Socket::connect()). |
Таблица 49-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
NULL | "not connected" | There is no open connection. | You must establish a connection before ( Net_Socket::connect()). |
Пример 49-1. Sending and recieving data
|
Provides an API for accessing Whois services
string $query - the Whois database object to look up
string $server - the name of the server or its IP address
Таблица 49-1. Возможные значения PEAR_Error
Error code | Error message | Reason | Solution |
---|---|---|---|
every | " Error connecting to server (Net_Socket says: Error-Message.) " | Connection to server failed | Check typing of server address and make sure the host is connected to the network. |
Замечание: You will not get a PEAR_Error, if the query fails due to a not existing whois object. This can be only done by checking the data returned by query().
Пример 49-1. Using Whois-query()
|
Предоставляет пакеты для работы с ядром PEAR или получения информации о нем.
Displays Information about your current PEAR install. Akin to PHP's phpinfo().
PEAR_Info obtains and displays information about your current PEAR Install. The PEAR_Info page features an A-Z index for easy searching, aswell as anchors for each package in the form of pkg_Package_Name (i.e. url.tld/pearinfo.php#pkg_PEAR_Info) PEAR_Info also features a full 'PEAR Credits' page, with information about the authors of the packages you currently have installed. PEAR_Info will also display any later versions that are available from PEAR to help keep you up to date.
Пример 52-1. Using PEAR_Info
|
The PEAR_PackageFileManager class uses a plugin system to generate the list of files in a package. This allows both standard recursive directory parsing (plugin type file) and more intelligent options such as the CVS browser PEAR_PackageFileManager_Cvs, which grabs all files in a local CVS checkout to create the list, ignoring any other local files.
Other options include specifying roles for file extensions (all .php files are role="php", for example), roles for directories (all directories named "tests" are given role="tests" by default), and exceptions. Exceptions are specific pathnames with * and ? wildcards that match a default role, but should have another. For example, perhaps a debug.tpl template would normally be data, but should be included in the docs role. Along these lines, to exclude files entirely, use the ignore option.
Required options for a release include version, baseinstalldir, state, and packagedirectory (the full path to the local location of the package to create a package.xml file for)
Example usage:
1 <?php 2 require_once('PEAR/PackageFileManager.php'); 3 $packagexml = new PEAR_PackageFileManager; 4 $e = $packagexml->setOptions( 5 array('baseinstalldir' => 'PhpDocumentor', 6 'version' => '1.2.1', 7 'packagedirectory' => 'C:/Web Pages/chiara/phpdoc2/', 8 'state' => 'stable', 9 'filelistgenerator' => 'cvs', // generate from cvs, use file for directory 10 'notes' => 'We\'ve implemented many new and exciting features', 11 'ignore' => array('TODO', 'tests/'), // ignore TODO, all files in tests/ 12 'installexceptions' => array('phpdoc' => '/*'), // baseinstalldir ="/" for phpdoc 13 'dir_roles' => array('tutorials' => 'doc'), 14 'exceptions' => array('README' => 'doc', // README would be data, now is doc 15 'PHPLICENSE.txt' => 'doc'))); // same for the license 16 if (PEAR::isError($e)) { 17 echo $e->getMessage(); 18 die(); 19 } 20 $e = $test->addPlatformException('pear-phpdoc.bat', 'windows'); 21 if (PEAR::isError($e)) { 22 echo $e->getMessage(); 23 exit; 24 } 25 $packagexml->addRole('pkg', 'doc'); // add a new role mapping 26 if (PEAR::isError($e)) { 27 echo $e->getMessage(); 28 exit; 29 } 30 // replace @PHP-BIN@ in this file with the path to php executable! pretty neat 31 $e = $test->addReplacement('pear-phpdoc', 'pear-config', '@PHP-BIN@', 'php_bin'); 32 if (PEAR::isError($e)) { 33 echo $e->getMessage(); 34 exit; 35 } 36 $e = $test->addReplacement('pear-phpdoc.bat', 'pear-config', '@PHP-BIN@', 'php_bin'); 37 if (PEAR::isError($e)) { 38 echo $e->getMessage(); 39 exit; 40 } 41 // note use of debugPackageFile() - this is VERY important 42 if (isset($_GET['make']) || $_SERVER['argv'][1] == 'make') { 43 $e = $packagexml->writePackageFile(); 44 } else { 45 $e = $packagexml->debugPackageFile(); 46 } 47 if (PEAR::isError($e)) { 48 echo $e->getMessage(); 49 die(); 50 } 51 ?> |
In addition, a package.xml file can now be generated from scratch, with the usage of new options package, summary, description, and the use of the addMaintainer() method
name of the option
prompt to display to the user
default value
This will overwrite an existing dependency if it is found. In other words, if a dependency on PHP 4.1.0 exists, and addDependency('php', '4.3.0', 'ge', 'php') is called, the existing dependency on PHP 4.1.0 will be overwritten with the new one on PHP 4.3.0
Dependency element name
Dependency version
A specific operator for the version, this can be one of: 'has', 'not', 'lt', 'le', 'eq', 'ne', 'ge', or 'gt'
Dependency type. This can be one of: 'pkg', 'ext', 'php', 'prog', 'os', 'sapi', or 'zend'
TRUE if dependency is optional
Every maintainer must have a valid account at pear.php.net. The first parameter is the account name (for instance, cellog is the handle for Greg Beaver at pear.php.net). Every maintainer has one of four possible roles:
lead: the primary maintainer
developer: an important developer on the project
contributor: self-explanatory
helper: ditto
username on pear.php.net of maintainer
role of maintainer
full name of maintainer
email address of maintainer
The format of the platform string must be OS-version-cpu-extra if any more specific information is needed, and the OS must be in lower case as in "windows." The match is performed using a regular expression, but uses * and ? wildcards instead of .* and .?. Note that hpux/aix/irix/linux are all exclusive. To select non-windows, use an expression like (*ix|*ux|darwin). If using PEAR 1.3.2 and newer, use !windows.
This information is based on eyeing the source for OS/Guess.php, so if you are unsure of what to do, read that file.
relative path of file (relative to packagedirectory option)
platform descriptor string
This sets an install-time complex search-and-replace function allowing the setting of platform-specific variables in all installed files.
if $type is php-const, then $to must be the name of a PHP Constant. If $type is pear-config, then $to must be the name of a PEAR config variable accessible through a PEAR_Config::get() method. If type is package-info, then $to must be the name of a section from the package.xml file used to install this file.
variable type, either php-const, pear-config or package-info
text to replace in the source file
variable name to use for replacement
This sets an install-time complex search-and-replace function allowing the setting of platform-specific variables in an installed file.
if $type is php-const, then $to must be the name of a PHP Constant. If $type is pear-config, then $to must be the name of a PEAR config variable accessible through a PEAR_Config::get() method. If type is package-info, then $to must be the name of a section from the package.xml file used to install this file.
relative path of file (relative to packagedirectory option)
variable type, either php-const, pear-config or package-info
text to replace in the source file
variable name to use for replacement
Roles influence both where a file is installed and how it is installed. Files with role="data" are in a completely different directory hierarchy from the program files of role="php"
In PEAR 1.3b2, these roles are
php (most common)
data
doc
test
script (gives the file an executable attribute)
src
throws PEAR_PACKAGEFILEMANAGER_RUN_SETOPTIONS
throws PEAR_PACKAGEFILEMANAGER_PHP_COMPAT_NOT_INSTALLED
throws PEAR_PACKAGEFILEMANAGER_NO_PHPCOMPATINFO
This method instructs writePackageFile() to simply print the package.xml to output, either command-line or web-friendly (this is automatic based on the existence of $_SERVER['PATH_TRANSLATED']
see PEAR_PackageFileManager::writePackageFile() - calls with the debug parameter set based on whether it is called from the command-line or web interface
1 function raiseError($code, $i1 = '', $i2 = '') 2 { 3 return PEAR::raiseError('PEAR_PackageFileManager Error: ' . 4 sprintf($GLOBALS['_PEAR_PACKAGEFILEMANAGER_ERRORS'][$this->_options['lang']][$code], 5 $i1, $i2), $code); 6 } |
The options array is indexed as follows:
1 $options = array('option_name' => <optionvalue>); |
The documentation below simplifies this description through the use of option_name without quotes
Configuration options:
lang: lang controls the language in which error messages are displayed. There are currently only English error messages, but any contributed will be added over time. Possible values: en (default)
packagefile: the name of the packagefile, defaults to package.xml
pathtopackagefile: the path to an existing package file to read in, if different from the packagedirectory
packagedirectory: the path to the base directory of the package. For package PEAR_PackageFileManager, this path is /path/to/pearcvs/pear/PEAR_PackageFileManager where /path/to/pearcvs is a local path on your hard drive
outputdirectory: the path in which to place the generated package.xml by default, this is ignored, and the package.xml is created in the packagedirectory
filelistgenerator: the <filelist> section plugin which will be used. In this release, there are two generator plugins, file and cvs. For details, see the docs for these plugins
usergeneratordir: For advanced users. If you write your own filelist generator plugin, use this option to tell PEAR_PackageFileManager where to find the file that contains it. If the plugin is named foo, the class must be named PEAR_PackageFileManager_Foo no matter where it is located. By default, the Foo plugin is located in PEAR/PackageFileManager/Foo.php. If you pass /path/to/foo in this option, setOptions will look for PEAR_PackageFileManager_Foo in /path/to/foo/Foo.php
doctype: Specifies the DTD of the package.xml file. Default is http://pear.php.net/dtd/package-1.0
pearcommonclass: Specifies the name of the class to instantiate, default is PEAR_Common, but users can override this with a custom class that implements PEAR_Common's method interface
changelogoldtonew: True if the ChangeLog should list from oldest entry to newest. Set to false if you would like new entries first
simpleoutput: True if the package.xml should not contain md5sum or <provides /> for readability
addhiddenfiles: True if you wish to add hidden files/directories that begin with . like .bashrc. This is only used by the File generator. The CVS generator will use all files in CVS regardless of format
baseinstalldir: The base directory to install this package in. For package PEAR_PackageFileManager, this is "PEAR", for package PEAR, this is "/"
license: The license this release is released under. Default is PHP License if left unspecified
notes: Release notes, any text describing what makes this release unique
changelognotes: notes for the changelog, this should be more detailed than the release notes. By default, PEAR_PackageFileManager uses the notes option for the changelog as well
version: The version number for this release. Remember the convention for numbering: initial alpha is between 0 and 1, add b<beta number> for beta as in 1.0b1, the integer portion of the version should specify backwards compatibility, as in 1.1 is backwards compatible with 1.0, but 2.0 is not backwards compatible with 1.10. Also note that 1.10 is a greater release version than 1.1 (think of it as "one point ten" and "one point one"). Bugfix releases should be a third decimal as in 1.0.1, 1.0.2
package: [optional] Package name. Use this to create a new package.xml, or overwrite an existing one from another package used as a template
summary: [optional] Summary of package purpose
description: [optional] Description of package purpose. Note that the above three options are not optional when creating a new package.xml from scratch
package.xml complex options:
cleardependencies: since version 1.3.0, this option will erase any existing dependencies in the package.xml if set to true
ignore: an array of filenames, directory names, or wildcard expressions specifying files to exclude entirely from the package.xml. Wildcards are operating system wildcards * and ?. file*foo.php will exclude filefoo.php, fileabrfoo.php and filewho_is_thisfoo.php. file?foo.php will exclude fileafoo.php and will not exclude fileaafoo.php. test/ will exclude all directories and subdirectories of ANY directory named test encountered in directory parsing. *test* will exclude all files and directories that contain test in their name
include: an array of filenames, directory names, or wildcard expressions specifying files to include in the listing. All other files will be ignored. Wildcards are in the same format as ignore
roles: this is an array mapping file extension to install role. This specifies default behavior that can be overridden by the exceptions option and dir_roles option. use addRole() to add a new role to the pre-existing array
dir_roles: this is an array mapping directory name to install role. All files in a directory whose name matches the directory will be given the install role specified. Single files can be excluded from this using the exceptions option. The directory should be a relative path from the baseinstalldir, or "/" for the baseinstalldir
exceptions: specify file role for specific files. This array maps all files matching the exact name of a file to a role as in "file.ext" => "role"
deps: dependency array. Pass in an empty array to clear all dependencies, and use addDependency() to add new ones/replace existing ones
maintainers: maintainers array. Pass in an empty array to clear all maintainers, and use addMaintainer() to add a new maintainer/replace existing maintainer
installexceptions: array mapping of specific filenames to baseinstalldir values. Use this to force the installation of a file into another directory, such as forcing a script to be in the root scripts directory so that it will be in the path. The filename must be a relative path to the packagedirectory
platformexceptions: array mapping of specific filenames to the platform they should be installed on. Use this to specify unix-only files or windows-only files. The format of the platform string must be OS-version-cpu-extra if any more specific information is needed, and the OS must be in lower case as in "windows." The match is performed using a regular expression, but uses * and ? wildcards instead of .* and .?. Note that hpux/aix/irix/linux are all exclusive. To select non-windows, use (*ix|*ux)
scriptphaseexceptions: array mapping of scripts to their install phase. This can be one of: pre-install, post-install, pre-uninstall, post-uninstall, pre-build, post-build, pre-setup, or post-setup
installas: array mapping of specific filenames to the filename they should be installed as. Use this to specify new filenames for files that should be installed. This will often be used in conjunction with platformexceptions if there are two files for different OSes that must have the same name when installed.
replacements: array mapping of specific filenames to complex text search-and-replace that should be performed upon install. The format is: filename => array('type' => php-const|pear-config|package-info 'from' => text in file 'to' => name of variable) if type is php-const, then 'to' must be the name of a PHP Constant. If type is pear-config, then 'to' must be the name of a PEAR config variable accessible through a PEAR_Config class->get() method. If type is package-info, then 'to' must be the name of a section from the package.xml file used to install this file.
globalreplacements: a list of replacements that should be performed on every single file. The format is the same as replacements (since 1.4.0)
configure_options: array specifies build options for PECL packages (you should probably use PECL_Gen instead, but it's here for completeness)
throws PEAR_PACKAGEFILEMANAGER_NOPKGDIR
throws PEAR_PACKAGEFILEMANAGER_NOVERSION
throws PEAR_PACKAGEFILEMANAGER_NOSTATE
throws PEAR_PACKAGEFILEMANAGER_NOBASEDIR
throws PEAR_PACKAGEFILEMANAGER_GENERATOR_NOTFOUND_ANYWHERE
throws PEAR_PACKAGEFILEMANAGER_GENERATOR_NOTFOUND
ALWAYS use debugPackageFile() to verify that output is correct before overwriting your package.xml
throws PEAR_PACKAGEFILEMANAGER_RUN_SETOPTIONS
throws PEAR_PACKAGEFILEMANAGER_ADD_MAINTAINERS
throws PEAR_PACKAGEFILEMANAGER_CANTWRITE_PKGFILE
throws PEAR_PACKAGEFILEMANAGER_CANTOPEN_TMPPKGFILE
throws PEAR_PACKAGEFILEMANAGER_CANTCOPY_PKGFILE
throws PEAR_PACKAGEFILEMANAGER_DEST_UNWRITABLE
see PEAR_PackageFileManager::debugPackageFile() - calls with the debug parameter set based on whether it is called from the command-line or web interface
Note that this will NOT work on a repository, only on a checked out CVS module
PEAR_PackageFileManager_CVS
PEAR_PackageFileManager_CVS Inherited Methods
Таблица 52-1. Inherited from PEAR_PackageFileManager_File
Method Name | Summary |
---|---|
Constructor PEAR_PackageFileManager_File::PEAR_PackageFileManager_File() | Set up the File filelist generator |
PEAR_PackageFileManager_File::dirList() | Retrieve a listing of every file in $directory and all subdirectories. |
PEAR_PackageFileManager_File::getFileList() | Generate the <filelist></filelist> section of the package file. |
This function is like parent::dirList() except that instead of retrieving a regular filelist, it first retrieves a listing of all the CVS/Entries files in $directory and all of the subdirectories. Then, it reads the Entries file, and creates a listing of files that are a part of the CVS repository. No check is made to see if they have been modified, but newly added or removed files are ignored.
This class is used to retrieve a raw directory listing. Use the PEAR_PackageFileManager_CVS class to only retrieve the contents of a cvs repository when generating the package.xml
PEAR_PackageFileManager_File
Таблица 52-1. Classes that extend PEAR_PackageFileManager_File
Class | Summary |
---|---|
PEAR_PackageFileManager_CVS | Generate a file list from a CVS checkout |
'ignore' and 'include' are the only options that this class uses. See PEAR_PackageFileManager::setOptions() for more information and formatting of this option
This function performs the backend generation of the array containing all files in this package
Таблица 52-1. Constants defined in PackageFileManager.php
Name | Value | Line Number |
---|---|---|
PEAR_PACKAGEFILEMANAGER_ADD_MAINTAINERS | 19 | 50 |
PEAR_PACKAGEFILEMANAGER_CANTCOPY_PKGFILE | 9 | 40 |
PEAR_PACKAGEFILEMANAGER_CANTOPEN_TMPPKGFILE | 10 | 41 |
PEAR_PACKAGEFILEMANAGER_CANTWRITE_PKGFILE | 7 | 38 |
PEAR_PACKAGEFILEMANAGER_CVS_PACKAGED | 26 | 57 |
PEAR_PACKAGEFILEMANAGER_DEST_UNWRITABLE | 8 | 39 |
PEAR_PACKAGEFILEMANAGER_DIR_DOESNT_EXIST | 13 | 44 |
PEAR_PACKAGEFILEMANAGER_GENERATOR_NOTFOUND | 5 | 36 |
PEAR_PACKAGEFILEMANAGER_GENERATOR_NOTFOUND_ANYWHERE | 6 | 37 |
PEAR_PACKAGEFILEMANAGER_IGNORED_EVERYTHING | 21 | 52 |
PEAR_PACKAGEFILEMANAGER_INVALID_PACKAGE | 22 | 53 |
PEAR_PACKAGEFILEMANAGER_INVALID_REPLACETYPE | 23 | 54 |
PEAR_PACKAGEFILEMANAGER_INVALID_ROLE | 24 | 55 |
PEAR_PACKAGEFILEMANAGER_NOBASEDIR | 4 | 35 |
PEAR_PACKAGEFILEMANAGER_NOCVSENTRIES | 12 | 43 |
PEAR_PACKAGEFILEMANAGER_NODESC | 18 | 49 |
PEAR_PACKAGEFILEMANAGER_NOPACKAGE | 15 | 46 |
PEAR_PACKAGEFILEMANAGER_NOPKGDIR | 3 | 34 |
PEAR_PACKAGEFILEMANAGER_NOSTATE | 1 | 32 |
PEAR_PACKAGEFILEMANAGER_NOSUMMARY | 17 | 48 |
PEAR_PACKAGEFILEMANAGER_NOVERSION | 2 | 33 |
PEAR_PACKAGEFILEMANAGER_NO_FILES | 20 | 51 |
PEAR_PACKAGEFILEMANAGER_PATH_DOESNT_EXIST | 11 | 42 |
PEAR_PACKAGEFILEMANAGER_PHP_NOT_PACKAGE | 25 | 56 |
PEAR_PACKAGEFILEMANAGER_RUN_SETOPTIONS | 14 | 45 |
PEAR_PACKAGEFILEMANAGER_WRONG_MROLE | 16 | 47 |
Таблица 52-1. Global Variables defined in PackageFileManager.php
Name | Value | Line Number | |
---|---|---|---|
$GLOBALS['_PEAR_PACKAGEFILEMANAGER_ERRORS'] |
| 63 |
Что-то вроде общей категории.
The phpDocumentor package provides automatic documenting of php api directly from the source.
The phpDocumentor tool is a standalone auto-documentor similar to JavaDoc written in PHP. It differs from PHPDoc in that it is MUCH faster, parses a much wider range of PHP files, and comes with many customizations including 11 HTML templates, Windows help file CHM output, PDF output, and XML DocBook output that is compatible with the markup used in this manual. In addition, it can do PHPXref source code highlighting and linking.
Provides missing functionality for older versions of PHP.
PHP_Compat provides missing functionality in the form of functions and constants for older versions of PHP.
The replicated functions are designed to be interchangable with their native equivilants. They have the same signature, same return values and throw the same errors. Each function is unit tested to ensure accuracy.
Пример 53-1. Loading a component with PHP_Compat:
|
Or, if you don't wish to use the class, you can load it manually.
Пример 53-2. Loading a component manually:
|
The function is then ready to use like you would normally.
PHP_Compat is designed for ease of use. It has no dependencies and can be used completely outside the PEAR infrastructure.
The following functions have been replicated:
Таблица 53-1. Functions
Function | Since |
---|---|
array_change_key_case | PHP 4.2.0 |
array_chunk | PHP 4.2.0 |
array_combine | PHP 5.0.0 |
array_diff_assoc | PHP 4.3.0 |
array_diff_key | PHP 5.0.2 |
array_diff_ukey | PHP 5.0.2 |
array_intersect_assoc | PHP 5.0.0 |
array_intersect_key | PHP 5.0.2 |
array_intersect_uassoc | PHP 5.0.0 |
array_intersect_ukey | PHP 5.0.2 |
array_key_exists | PHP 4.1.0 |
array_product | PHP 5.1.0 |
array_search | PHP 4.0.5 |
array_udiff | PHP 5.0.0 |
array_udiff_assoc | PHP 5.0.0 |
array_udiff_uassoc | PHP 5.0.0 |
array_uintersect | PHP 5.0.0 |
array_uintersect_assoc | PHP 5.0.0 |
array_uintersect_uassoc | PHP 5.0.0 |
array_walk_recursive | PHP 5.0.0 |
call_user_func_array | PHP 4.0.4 |
bcinvert | PHP 5.2.0 |
bcpowmod | PHP 5.0.0 |
clone | PHP 5.0.0 |
constant | PHP 4.0.4 |
convert_uudecode | PHP 5.0.0 |
convert_uuencode | PHP 5.0.0 |
debug_print_backtrace | PHP 5.0.0 |
file_get_contents | PHP 4.3.0 |
file_put_contents | PHP 5.0.0 |
floatval | PHP 4.2.0 |
fprintf | PHP 5.0.0 |
fputcsv | PHP 5.0.0 |
get_headers | PHP 5.0.0 |
get_include_path | PHP 4.3.0 |
html_entity_decode | PHP 4.3.0 |
htmlspecialchars_decode | PHP 5.1.0 |
http_build_query | PHP 5.0.0 |
ibase_timefmt | PHP 5.0.0 |
idate | PHP 5.1.0 |
image_type_to_mime_type | PHP 4.3.0 |
inet_ntop | PHP 5.1.0 |
inet_pton | PHP 5.1.0 |
ini_get_all | PHP 4.2.0 |
is_a | PHP 4.2.0 |
is_scalar | PHP 4.0.5 |
md5_file | PHP 4.2.0 |
mhash | PHP 4.1.0 |
mime_content_type | PHP 4.3.0 |
ob_clean | PHP 4.2.0 |
ob_flush | PHP 4.2.0 |
ob_get_clean | PHP 4.3.0 |
ob_get_flush | PHP 4.3.0 |
php_strip_whitespace | PHP 5.0.0 |
property_exists | PHP 5.1.0 |
pg_affected_rows | PHP 4.2.0 |
pg_escape_bytea | PHP 4.2.0 |
pg_unescape_bytea | PHP 4.2.0 |
restore_include_path | PHP 4.3.0 |
scandir | PHP 5.0.0 |
set_include_path | PHP 4.3.0 |
str_ireplace | PHP 5.0.0 |
str_rot13 | PHP 4.2.0 |
str_shuffle | PHP 4.3.0 |
str_split | PHP 5.0.0 |
str_word_count | PHP 4.3.0 |
stripos | PHP 5.0.0 |
strpbrk | PHP 5.0.0 |
strripos | PHP 5.0.0 |
substr_compare | PHP 5.0.0 |
time_sleep_until | PHP 5.1.0 |
var_export | PHP 4.2.0 |
version_compare | PHP 4.1.0 |
vprintf | PHP 4.1.0 |
vsprintf | PHP 4.1.0 |
The following constants have been replicated:
Таблица 53-2. Constants
File | Constants | Since | |||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
DIRECTORY_SEPARATOR | DIRECTORY_SEPARATOR | PHP 4.0.6 | |||||||||||||
E_STRICT |
| PHP 5 | |||||||||||||
FILE |
| PHP 5 | |||||||||||||
PATH_SEPARATOR |
| PHP 4.3.0 | |||||||||||||
PHP_EOL |
| PHP 5 | |||||||||||||
STD |
| PHP 4.3.0 | |||||||||||||
T |
| PHP 5 | |||||||||||||
UPLOAD_ERR |
| PHP 4.3.0 |
In order to create portable code, it's best to assume all the native functions already exist. Littering a script with calls to PHP_Compat can become messy, and increase the work required to port the code.
To solve this there are a number of approaches. The first would be adding the load statements to a file which is included at the top of every document. The second, and prefered method is to make use of php_auto_append php.ini value. This can be set in a .htaccess file, and no modifications to the actual code are required.
If phpcompat.php was the name of the file, an example entry in a .htaccess could be php_value php_auto_append phpcompat.php. The phpcompat.php file would make use of either the loadVersion or loadFunction/loadConstant methods discussed in the next page.
mixed
TRUE if the function was loaded. |
FALSE if the function was not loaded. Either unable to be included or already defined. |
If you specified an array of functions to load, an array of TRUE/FALSE values is returned. |
Пример 53-1. Loading a function with the class:
|
You may also load a function without using the class.
Пример 53-2. Loading a function manually:
|
mixed
TRUE if the constant was loaded. |
FALSE if the constant was not loaded. Either unable to be included or already defined. |
If you specified an array of constants to load, an array of TRUE/FALSE values is returned. |
Пример 53-1. Loading a constant with the class:
|
You may also load a constant without using the class.
Пример 53-2. Loading a constant manually:
|
array
An associative array of boolean values. The key is the name of the component loaded. The value for whether or not the component was loaded correctly. |
Пример 53-1. Loading all components:
This example would show a long list of components which were loaded. |
Пример 53-2. Loading up to a specific version: The components loaded would be those with versions lower than, or equal to the supplied version and greater than the current PHP version.
This would output an array of components which were loaded. The output would be simular to:
|
Provides a simple framework for creating a test application to automate testing of functions and classes.
PHPUnit provides a simple framework for creating a test suite to automate testing of functions and classes. PHPUnit is inspired by JUnit which was created by Kent Beck and Erich Gamma as a tool for eXtreme Programming. One of the rules of XP is to test small software components as often and early as possible, this way you will not have to fix bugs and errors in the API while setting up and testing larger applications which depend on the class. While unit testing is one of the fundimental rules in XP, you don't have to switch to XP to benefit from PHPUnit. PHPUnit stands alone as a good tool for testing classes or a set of functions and will ease your development cycle and help you to avoid endless debug sessions.
Normally, you would write a class, do some unsystematic tests using echo() or var_dump(). After this, you use the class in your application and hope everything is ok. To benefit from PHPUnit you should rethink the flow. The best way is to do this:
1. design your class/API
2. create a test suite
3. implement the class/API
4. run the test suite
5. fix failures or errors and go to #4 again
Let's start with a small example: a string class. First we create a bunch of functions declarations to work on a string:
---- string.php ---- <?php class String { //contains the internal data var $data; // constructor function String($data) { $this->data = $data; } // creates a deep copy of the string object function copy() { } // adds another string object to this class function add($string) { } // returns the formated string function toString($format) { } } ?> |
Now we can create a test suite, which checks every function of your string class. A test suite is normal PHP class inherited from PHPUnit_TestCase containing test functions, identified by a leading 'test' in the function name. In the test function an expected value has to be compared with the result of the function to test. The result of this compare must delegate to a function of the assert*()-family, which decides if a function passes or fails the test.
---- testcase.php ---- <?php require_once 'string.php'; require_once 'PHPUnit.php'; class StringTest extends PHPUnit_TestCase { // contains the object handle of the string class var $abc; // constructor of the test suite function StringTest($name) { $this->PHPUnit_TestCase($name); } // called before the test functions will be executed // this function is defined in PHPUnit_TestCase and overwritten // here function setUp() { // create a new instance of String with the // string 'abc' $this->abc = new String("abc"); } // called after the test functions are executed // this function is defined in PHPUnit_TestCase and overwritten // here function tearDown() { // delete your instance unset($this->abc); } // test the toString function function testToString() { $result = $this->abc->toString('contains %s'); $expected = 'contains abc'; $this->assertTrue($result == $expected); } // test the copy function function testCopy() { $abc2 = $this->abc->copy(); $this->assertEquals($abc2, $this->abc); } // test the add function function testAdd() { $abc2 = new String('123'); $this->abc->add($abc2); $result = $this->abc->toString("%s"); $expected = "abc123"; $this->assertTrue($result == $expected); } } ?> |
Now, we can run a first test. Make sure that all the paths are correct and then execute this PHP program.
---- stringtest.php ---- <?php require_once 'testcase.php'; require_once 'PHPUnit.php'; $suite = new PHPUnit_TestSuite("StringTest"); $result = PHPUnit::run($suite); echo $result -> toString(); ?> |
If you call this script from the commandline, you will get the following output:
TestCase stringtest->testtostring() failed: expected true, actual false TestCase stringtest->testcopy() failed: expected , actual Object TestCase stringtest->testadd() failed: expected true, actual false |
If you want to call the script through your browser, you have to put the script in a correct html page and call $result->toHTML () instead of $result->toString().
Ok, let's start with implementation of the our string class.
---- string.php ---- <?php class String { //contains the internal data var $data; // constructor function String($data) { $this->data = $data; } // creates a deep copy of the string object function copy() { $ret = new String($this->data); return $ret; } // adds another string object to this class function add($string) { $this->data = $this->data.$string->toString("%ss"); } // returns the formated string function toString($format) { $ret = sprintf($format, $this->data); return $ret; } } ?> |
The implementation is complete and we can run the test again:
~> php -f stringtest.php TestCase stringtest->testtostring() passed TestCase stringtest->testcopy() passed TestCase stringtest->testadd() failed: expected true, actual false |
$this->data = $this->data.$string->toString("%s"); |
~> php -f stringtest.php TestCase stringtest->testtostring() passed TestCase stringtest->testcopy() passed TestCase stringtest->testadd() passed |
Does it seem like a lot of work for testing three simple functions? Don't forget, this is a small example. Think about bigger, more complex API's like database abstraction or basket classes in a shop application. PHPUnit is an excellent tool to detect errors in the implementation of your class.
Often you will want to reimplement or refactor a large class which is used in several different applications. Without a test suite the likeliness of you breaking something in one of the applications that depends on your class is very high. Thanks to unit tests, you can create a test suite for your class, and then reimplement your class with the security of knowing that as long as the new class passes the tests, applications that depend on the class will work.
Пример 53-1. Using PHPUnit::run()
|
1) Implement a subclass of PHPUnit_TestCase.
2) Define instance variables that store the state of the fixture.
3) Initialize the fixture state by overriding setUp().
4) Clean-up after a test by overriding tearDown().
<?php class MathTest extends PHPUnit_TestCase { var $fValue1; var $fValue2; function MathTest($name) { $this->PHPUnit_TestCase($name); } function setUp() { $this->fValue1 = 2; $this->fValue2 = 3; } } ?> |
For each test implement a method which interacts with the fixture. Verify the expected results with assertions specified by calling assert with a boolean.
function testPass() { $this->assertTrue($this->fValue1 + $this->fValue2 == 5); } |
Tools to ensure the quality of something.
Documentation coverage analysis for the PEAR packages documentation.
Daily updated pear documentation stats can be found at pear.cweiske.de/coverage/.
A great library is almost useless without documentation. PEAR has over 300 packages, automatically generated API documentation and a manual. The PEAR manual (the one you are reading) shall provide an overview on the packages and instructions about how to use them, and give an understanding about the classes in a package, and their methods. Further information about them can looked up in the API docs.
With the amount of packages PEAR provides, it's hard to keep track of the state of documentation of the packages - a tool to track this was needed. QA_Peardoc_Coverage is it's incarnation.
QA_Peardoc_Coverage uses a CVS checkout of PEAR and PEARDOC to find out which packages are documented, which classes and method are mentioned in the docs, and which developers do a good job in documenting their code.
The documentation analysis report generation is split into two processes:
Collect data and save it
Generate different reports from saved data
generateCoverage() in QA_Peardoc_Coverage generates and returns the array with the computed coverage data. It can be serialized and saved, since all the Renderer classes use it as input.
Classes implementing the QA_Peardoc_Coverage_Renderer interface provide a render() method that takes the data returned by generateCoverage() and return the analysis, most times a string containing HTML code.
Make sure you have a fresh checkout of pear and peardoc directories from cvs.php.net.
Configure peardoc to generate the manual.xml in there ( autoconf, ./configure).
Call genData.php with the path to peardoc's manual.xml as first, and path to the pear cvs directory as second parameter.
A file called doc.dat will be generated in the current working directory.
Once the coverage data is generated and serialized, you can generate some HTML reports. For this, the packages provides four Renderer classes that all implement the QA_Peardoc_Coverage_Renderer interface:
QA_Peardoc_Coverage_Renderer_DeveloperList lists all developers with the number of packages they have, the number of undocumented packages and lists the undocumented ones. The list is sorted by percentage of documented packages.
QA_Peardoc_Coverage_Renderer_SimplePackageList lists all categories in PEAR, the packages in them and shows which of them have docs and which not. A final summary with the total number of existing and documented packages, and a percentage number is also given.
QA_Peardoc_Coverage_Renderer_ExtendetPackageList is similar to the simple list, but also shows the package's classes, their documentation state and their methods and their doc state. This list can be used to check which methods aren't yet covered by your documentation.
QA_Peardoc_Coverage_Renderer_MissingDocsPerDeveloper generates an array of developer email => array(package names) assignments that can be used as base data to send reminder emails.
All the renderers have a examples/gen*.php file that uses the doc.dat file written by examples/genData.php. They echo the html to the console, so you should redirect it into a file.
Simple little tool that walks over a checkout of PEAR's CVS directory (pear) and reports the following issues:
Version of package.xml
If the version in package.xml is missing
Package stability
Last release date
Time since the last release
After listing this stats for each single package, a summary of percentages is given.
Daily updated package stats can be found at pear.cweiske.de/packagestatus/.
Provides Packages for streams API. For more information on stream wrappers see the PHP Manual.
Allows stream based access to variables.
Stream_Var supplies a class that can be used as a wrapper for PHP'' stream functions. This allows you to access variables with fopen(), fclose(), fwrite(), fread(), opendir() and all other filesystem functions.
You may use stream_wrapper_register() to register Stream_Var as a wrapper.
Scalar variables (strings, integers, floats) are treated as files, while arrays represent directories.
Please see the PHP Manual or the example for more information on how to register streams.
Stream_Var could be used in various scenarios. Imagine you are using a class that reads data from a file but you are creating the data on-the-fly and do not want to save the data before it can be processed by the class.
This is, where Stream_Var can be used. Just register it as a wrapper for fopen() and pass var://GLOBAL/yourVar as a parameter to the class.
It will read from the variable as if it was a file.
The following example shows you how to register Stream_Var as a wrapper for the stream functions.
Пример 56-1. Registering Stream_Var
|
The following example show you how to access scalar variables with fopen(), fread(), frwite() and fclose().
Пример 56-2. Accessing scalar variables
|
The following example shows how to use opendir() to access an array.
Пример 56-3. Accessing an array
|
Provides structures-related Packages
Parsing BibTex Data to an array and exporting to BibTex and RTF.
This package provides methods to access information stored in a BibTex file. During parsing it is possible to let the data be validated. In addition. the creation of BibTex Strings as well as RTF Strings is also supported.
Пример 57-1. Loading a BibTex File and printing the parsed array
|
Options can be set either in the constructor or with the method setOption(). When setting in the constructor the options are given in an associative array. The options are:
stripDelimiter (default: true) Stripping the delimiter surrounding the entries.
validate (default: true) Validation while parsing.
unwrap (default: false) Unwrapping entries while parsing.
wordWrapWidth (default: false) If set to a number higher one that the entries are wrapped after that amount of characters.
wordWrapBreak (default: \n) String used to break the line (attached to the line).
wordWrapCut (default: 0) If set to zero the line will we wrapped at the next possible space, if set to one the line will be wrapped exactly after the given amount of characters.
removeCurlyBraces (default: false) If set to true Curly Braces will be removed.
Пример 57-2. Setting options in the constructor
|
Пример 57-3. Setting options using setOption
|
The data is stored in the class variable data. This is a a list where each entry is a hash table representing one bibtex-entry. The keys of the hash table correspond to the keys used in bibtex and the values are the corresponding values. Some of these keys are:
cite - The key used in a LaTeX source to do the citing.
type - The type of the entry, like techreport, book and so on.
author - One or more authors of the entry. This entry is also a list with hash tables representing the authors as entries. The author has table is explained later.
title - Title of the entry.
As described before the authors are stored in a list. Every entry representing one author as a has table. The hash table consits of four keys: first, von, last and jr. The keys are explained in the following list:
first - The first name of the author.
von - Some names have a 'von' part in their name. This is usually a sign of nobleness.
last - The last name of the author.
jr - Sometimes a author is the son of his father and has the same name, then the value would be jr. The same is true for the value sen but vice versa.
To add an entry simply create a hash table with the needed keys and values and call the method addEntry().
Пример 57-4. Adding an entry
|
The class Structures_BibTex introduces a system to collect warnings that may happen during parsing. Warnings are things in the BibTex source which are not correct but do not cause the parser to fail. One example would be a double cite entry. These warnings should help to improve the quality of your BibTex code. Whether warnings are generated or not is controlled by the option validate. Per default warnings are generated. If you want to not generate warnings you should use the setOption() method like this.
Пример 57-1. Switching off creation of warnings
|
The warnings are stored in an array called warnings which is public accessible. To check is a warning exists you can use the method hasWarning(). This method returns true if there are warnings and false otherwise.
Пример 57-2. Checking for warnings
|
warning - Type of the warning
entry - The line that caused the warning
wholeentry - The whole entry in which the warning occurred
Пример 57-3. Checking for warnings
|
The following Warnings are known:
WARNING_MISSING_END_BRACE - This warning is generated when the end brace in an entry is missing. Take this warning seriously!
WARNING_AT_IN_BRACES - A Value is delimited by Braces. Then inside a @ is not allowed.
WARNING_ESCAPED_DOUBLE_QUOTE_INSIDE_DOUBLE_QUOTES - A Value is delimited by double quotes. Then inside no escaped double quote is allowed.
WARNING_UNBALANCED_AMOUNT_OF_BRACES - The amount of braces inside a value is not equal (opening and closing). The parses fails if in the complete entry this amount is not correct. But if only on an entry it is not correct then this is only a warning. As a matter of fact of the parser does not fail but there is an unbalanced amount of braces in an entry this warning has to be generated something times two.
WARNING_MULTIPLE_ENTRIES - Every entry is identified by a unique string. This warning is created if there are at least two entries with the same identification.
WARNING_LINE_WAS_NOT_CONVERTED - This warning is created if during exporting (for example in RTF or HTML) one entry was ignored because of no matching data in the entry. At least one of the following entries have to exist in the entry to get converted: title, journal, year or authors.
STRING_ENTRY_NOT_YET_SUPPORTED - BibTex defines some special entry types, String is one of them and is used to define abbreviations. This is not yet supported by Structres_BibTex.
PREAMBLE_ENTRY_NOT_YET_SUPPORTED - BibTex defines some special entry types, Preamble is one of them and is used to define formatted code. This is not yet supported by Structres_BibTex.
WARNING_NOT_ALLOWED_TYPE - BibTex allows to define own types. This warning is genereated when a type was detected which is not part of the standard types. The allowed or standard type are defined in the class variable allowedTypes as array.
The class Structures_BibTex provides some methods to export the data stored in the class. Currently the class exports the data in the following formats:
BibTeX - The whole data in BibTeX
RTF - The data with enough matching data as a short list in RTF format
HTML - The data with enough matching data as a short list in HTML format
The default is to export the name of the author in this format: "VON LAST, JR, FIRST". The corresponding placeholder will be substituted. The placeholders have to be uppercase. The format string is defined in the class variable authorstring. Changing the ouput of the author in the entries to this format "FIRST LAST" can be done like this:
Пример 57-1. Changing author format
|
One of the basic features is of course the export in BibTeX format. This is simply done by invoking the bibTex() method.
Пример 57-2. Exporting in BibTeX format
|
This feature was introduced to enable some kind of import into Word. Word (of course also Open Office or kword) understands the RTF format. It is simply possible to save the output as 'somefile.rtf' and be opened in Word. This will satisfy the Windows users. To use it simply call the method rtf().
Пример 57-3. Exporting in RTF format
|
The default format for every entry is first the authors, then the title bold and in double quotes, then the journal italic and finally the year. To change the default format you should override the class variable rtfstring. The default rtfstring looks like this: 'AUTHORS, "{\b TITLE}", {\i JOURNAL}, YEAR'. The string AUTHORS, TITLE, JOURNAL and YEAR are substituted with the corresponding values.
Пример 57-4. Exporting in RTF format with different RTF string
|
This feature is just a simple HTML generation. The default formatting is the same as in rtf. To use it call the method html().
Пример 57-5. Exporting in HTML format
|
As with the RTF export it is possible to override the default HTML string.The default string is stored in the class variable htmlstring and looks like this: AUTHORS, "<strong>TITLE</strong>", <em>JOURNAL</em>, YEAR<br />.
Пример 57-6. Exporting in HTML format with different HTML string
|
On this page miscellaneous methods of the class Structures_BibTex are described. These methods include:
amount - The amount of BibTex entries
getStatistic - Statistics about BibTex entries
Structures_DataGrid is a class for building, manipulating and rendering a tabular structure of data. It has the ability to allow you to render a datagrid in HTML format as well as many other formats such as an XML Document, an Excel Spreadsheet, an XUL Document and more.
It also offers paging and sorting functionality to limit the data that is presented. This concept is based on the .NET Framework DataGrid control and works very well with database and XML result sets.
Structures_DataGrid is a package with the purpose of rendering a data set into a tabular structure in a specific output format. Possible output formats are (X)HTML, XML, XUL, Excel .xls spreadsheets, CSV, or console tables.
The input data format is independent of the underlying data storage layer: It does not matter if the data has been selected from a database, has been harvested from plain text files or converted from a web service call. The data can be sorted and paged, and each cell of the table can have a custom look by using CSS for the HTML output.
So to begin, you will want to find a datasource, commonly you might use a Database like MySQL or an XML document. You can then easily bind this datasource to the datagrid, to do so you have 3 options. The first, is to fetch your data into a 2 dimension array and pass it into the bind method. The second way is to bind a record set that is not already an array, such as a DB_DataObject or a DB_Result object. To do so, you can use the bindDataSource method by creating a DataSource object. The third way is to loop through your record set and add each record individually, this practice is the least efficient.
Замечание: If you bind the datagrid to a datasource that is an object such as a DB_DataObject, you do not need to fetch the data as the DataGrid will handle that for you.
Once your datagrid has been populated with your records, you have many options on how to manipulate what is to be shown. You can sort the data, choose to show only a certain amount of data per page and also choose what format the data should be rendered into. You can render the datagrid in many formats including HTML.
This document is based on questions asked on PEAR general mailing list and other mailing lists and forums.
The setRequestPrefix() method is the solution for this problem. Each DataGrid for the page needs such a prefix that is internally used before the GET parameters for sorting and paging. An example of the usage:
require_once 'Structures/DataGrid.php'; $datagrid1 = new Structures_DataGrid(); $datagrid2 = new Structures_DataGrid(); $datagrid1->setRequestPrefix('trade_'); $datagrid2->setRequestPrefix('stock_'); $datagrid1->bind('SELECT * FROM trade', array('dsn' => DSN)); $datagrid2->bind('SELECT * FROM stock', array('dsn' => DSN)); $datagrid1->render(); $datagrid2->render(); |
Замечание: You need to call setRequestPrefix() before calling bind().
Currently there are four DataSource drivers that are recommended in the sense of efficiency:
DB_DataObject
DB_Table
DBQuery
MDB2
These four drivers will only fetch the needed records from the database. For example, if you have a row limit of 15 records per page, they will only fetch (up to) 15 records.
All other DataSource drivers can, of course, also be used. But there is no logic implemented (better said: implementable) to avoid fetching (or keeping in memory) unneeded records.
You need a formatter for the new column that should hold the row number. The first parameter that is passed to such a formatter function contains a currRow value with the row number per page. For calculating the row number relative to the whole table, you need to take also the getCurrentRecordNumberStart() method into account.
The following code snippet shows you how to define the formatter function and how to add the column (with # as the column label and right aligned values):
function formatRowNumber($params, $recordNumberStart) { return $params['currRow'] + $recordNumberStart; } $datagrid->addColumn( new Structures_DataGrid_Column( '#', null, null, array('style' => 'text-align: right;'), null, 'formatRowNumber', $datagrid->getCurrentRecordNumberStart() )); |
4. I'm using the Excel Renderer and would like to have the € sign in the resulting Excel file, but I always get only a box or some funny characters. How can I get the right € sign?
Instead of using an encoding like ISO-8859-15, you need to use Windows-1252.
Streaming support in Structures_DataGrid is intended to be used with large datasets. But it can also be used with very small datasets without loss of performance.
As always, there is an exception to this rule: When you're using one of the DataSource drivers that fetch data from a database and you have queries that need a lot of time for computation of the results, you should not use streaming, as running such a complex query multiple times will need even more time, of course.
If you are not familiar with PEAR, we recommend that you first read the PEAR general installation instructions
Structures_DataGrid use drivers that are provided separately. It means that installing the core package named Structures_DataGrid is not enough to get something working.
You will at least need one DataSource driver, for handling the input, and one Rendering driver (or Renderer), for the output.
The following commands will install the core package, as well as the MDB2 DataSource (for binding SQL queries), HTML_Table Renderer and the Pager renderer (for paging links). That should cover your most common needs.
$ pear install -o Structures_DataGrid $ pear install -o Structures_DataGrid_DataSource_MDB2 $ pear install -o Structures_DataGrid_Renderer_HTMLTable $ pear install -o Structures_DataGrid_Renderer_Pager |
Замечание: If you get an error message like Failed to download pear/Structures_DataGrid within preferred state "stable", latest release is [...], you can simply append -beta to the package name, for example:
$ pear install -o Structures_DataGrid-beta
Of course, you may want to use other input/output formats, such as XML, MS Excel, DB_DataObject, XUL, etc... Just install the corresponding drivers.
It is possible to install DataSource drivers or all Renderer drivers at once. The following two commands will install Structures_DataGrid and either all DataSource or all Renderer drivers at once.
$ pear install Structures_DataGrid#datasources $ pear install Structures_DataGrid#renderers |
Please note that the individual drivers will be installed only if the requirements are fulfilled. That means that the MDB2 DataSource won't be installed if you don't have MDB2 installed. The same holds for the Excel Renderer if you don't have Spreadsheet_Excel_Writer installed.
Of course, the same holds for the uninstallation. For example:
$ pear uninstall Structures_DataGrid#datasources $ pear uninstall Structures_DataGrid#renderers |
A DataSource has a rather self-explanatory name; however, a DataSource driver in context to the DataGrid can become a very essential key to your software. A DataSource driver will interact with your data source directly, such as a DB_DataObject or a MDB2 query and handle all of the paging and sorting code for you, resulting in very few lines of code that you will need to write.
There are two methods intended to be used for binding a DataSource driver: bind() and bindDataSource().
The bind() method is able to autodetect the right driver in many cases. For example, you can pass DB_Table or DB_DataObject instances to it. Strings can't be autodetected because they could contain CSV or XML data, for example. In such cases, you can specify the type as the third parameter in the bind() method call (e.g. 'CSV' or 'XML').
If you are building your own custom DataSource driver, using bindDataSource() is the method of choice. Just instantiate your DataSource class and pass this instance to the bindDataSource() method.
A list with the currently available DataSources can be found on the overview page.
Please also note the following FAQ entry: Which DataSource drivers are recommended?
The DataGrid offers the ability to build out your data in a grid format in an HTML table, which is the most common method due to the nature of PHP. However, the DataGrid offers many other ways of outputting the tabular data structure such as an Excel spreadsheet or an XML document.
To use a different renderer other than the HTML_Table renderer, you can specify the name of the renderer (e.g. 'CSV', 'Pager' or 'XML') as the first parameter of the fill(), getOutput(), and render() methods. Another possibility is to use setRenderer() method. The old way of using the third parameter of the constructor to define the renderer is deprecated since version 0.7.0.
A list with the currently available renderers can be found on the overview page.
Large recordsets can exceed PHP's memory limit. Structures_DataGrid offers streaming support with many DataSource drivers and some Renderer drivers to avoid problems with the memory limit.
Streaming can be enabled by calling the enableStreaming() method of the Structures_DataGrid object. An optimal parameter allows to set the number of records that should be read and written on each stream iteration. The default buffer size is 500 records.
Once streaming is enabled, only up to the number of records specified in the buffer size records will be fetched and rendered. This will be repeated until this was done for all records.
Пример 57-1. Enabling streaming with buffer size of 1,000 records
|
Although streaming can be used with every DataSource driver, only the following drivers support streaming in a meaningful way: DataObject, DBQuery, DB_Table and MDB2. Streaming support is planned to be added also to the CSV and XML DataSources.
Streaming support is also compatible with every Renderer driver but can currently be used only with CSV and XML Renderers in a meaningful way. Other Renderers might be rewritten in the future for streaming support.
The column formatter method can be a very powerful solution to a very common need. The need is to customize the output for a cell in the grid such as a link for a form element. This can be easily done by specifying a "callback" function. This function will then return the string that is needed to be printed.
Пример 57-1. Using the column formatter
|
Each callback function needs to accept at least one parameter ($params in the example above). This parameter will contain various information:
'record': An array containing the complete current record
'fieldName': The field name of the current column
'columnName': The column name of the current column
'orderBy': The 'orderBy' argument of the current column
'attribs': The attributes of the current column
'currRow': The number of the current row
'currCol': The number of the current column
An optional second parameter ($args in the example) allows you to pass additional information to the callback functions. In the example above, an array with length information is passed when the callback function printDesc() is called for the description column. Please note that this second parameter is only passed when you specify something in the column constructor. Therefore, it is a good practice to use $args = array() in the parameter list of your callback functions.
To retrieve the data that the datagrid will display you can begin by passing a simple SQL statement to the bind() method.
Пример 57-1. Using an SQL query as datasource
|
If you are familiar with the SQL language you'll certainly find many ways to adapt the above example to your needs, using more complex queries.
You can also page through your dataset with the automatic paging feature as shown below. This feature transparently adds LIMIT clauses to your SQL statement, providing optimized database access.
Пример 57-2. Automatic paging
|
This example will show you how to create an interface to a User Management System using the DB_DataObject package to handle the database aspects of this example.
Warning: this example makes use of new features that will be available in the upcoming Structures_DataGrid 0.7 release. In the meantime, please use the CVS version.
Пример 57-1. User Management System Example
|
Writing your own DataSource driver is the way to go when none of the existing driver suit your needs. It is actually pretty easy, and allows for great flexibility.
Of course, if you're trying to fetch data from an exotic source, writing your own driver is required. But, sometimes it's also the best way to achieve the best optimization, especially (but not only) with databases.
This document will present you the DataSource interface, and how to implement it.
A DataSource driver is a descendent of the Structures_DataGrid_DataSource class, which implements the DataSource interface.
DataSource is a synomym for DataSource driver.
The DataSource interface consists in a set of methods that drivers must or may overload and protected properties that drivers can use, as well as recommended practices.
A DataSource container is a constant or a variable of any type (string, array, object, etc...) that either contains data or describes how to retrieve data.
Every DataSource driver is specific to, and knows how to handle, a given DataSource container type.
array $_options - Data binding options as an associative array. You can read the content of this property but you shouldn't change it directly.
The constructor must set default options, if any, and call the parent constructor. This method is optional.
bind() is reponsible for loading a DataSource container into the driver, according to some binding options. This method is optional. It must return a PEAR_Error object in case of failure.
count() must return the total number or records found in the container. This method is required, and is always called before fetch(). It must return a PEAR_Error object in case of failure.
sort() must sort the data according to sortSpec and the optional sortDir. This method is required, and is always called before fetch(). It must return a PEAR_Error object in case of failure.
fetch() must return a 2-dimension array of data, starting from record offset, containing len records..This method is required It must return a PEAR_Error object in case of failure.
_addDefaultOptions() is used to declare the driver-specific options, if any, as well as their default values. It must be called from the constructor.
setOptions() is a public method used to set options. If they ever need to change options, drivers should use this method.
Let's start with a very simple driver. It is rather readable and you shouldn't have much trouble understanding it. It is not extremely useful to write a custom driver for a such simple SQL query, but it should get you started.
Пример 57-1. A simple SQL adaptor
|
Before going live, it is very recommended to test your driver with the dump() method.
Пример 57-2. Testing with dump()
|
That should output a nicely formated ascii table like:
There are 23 cats in the farm. Here are the 5 lightest ones: +---------+---------+-----------+--------+ | name | species | birthDate | weight | +---------+---------+-----------+--------+ | sarge | cat | 20021220 | 1.8 | | etch | cat | 20000509 | 2.5 | | potato | cat | 19980128 | 3.8 | | sid | cat | 20011101 | 4.1 | | woody | cat | 19970712 | 6.0 | +---------+---------+-----------+--------+ |
Okay, so you have written a driver that's tailored to your needs, and tested it. It is now time to connect it to Structures_DataGrid.
For this purpose we're going to use the bindDataSource() method.
Пример 57-3. Binding a custom datasource
|
That should output a sortable HTML table.
Of course, the usual features of Structures_DataGrid are now available to you: paging, other output formats as XML, MS-Excel, etc...
Writing your own Renderer allows you to fine tune every aspect of Structures_DataGrid output.
You may need to output the datagrid in a completely unsupported format. Then writing your own Renderer is the only option
But you may also need a unsupported variant of an existing renderer, say, for example, a very specific HTML output. In this case, you generally have two options : either writing a Rendering driver from scratch, or customizing (subclassing) an existing one.
This document will present you the Rendering driver interface, and how to implement it. You will certainly see how flexible Structures_DataGrid can become with custom Renderers, but also how easy we have to tried to make this process.
A Rendering driver is a descendent of the Structures_DataGrid_Renderer class, which implements the Renderer interface.
Renderer is a synomym for Rendering driver.
The Renderer interface consists in a set of methods that drivers must or may overload and protected properties that drivers can use, as well as recommended practices.
A Rendering container is either an object that contain a sort of rendering engine, or a variable of any type (string, array, object, etc...) that can contain the output of a Renderer.
A Renderer with Container Support driver is specific to, and knows how to handle, a given type of Rendering container.
A driver is said to provide Container Support when it is able to handle a given type of Rendering container. Drivers with Container Support must implement the setContainer() and getContainer() public methods. They must be able to use a Rendering container provided by the user with setContainer(). They must also be able to create and intialize a Rendering container if the user does not provide any.
A driver is said to provide Output Buffering when it buffers the output that it generates, implements the flatten() method and is able to return the generated output from flatten().
A Direct Rendering driver is the simplest form of Renderer. It directs all of its output to standard output. By definition, a such driver neither provide Container support nor Output Buffering
All of the following properties are read-only : drivers can access their content but must not change it directly.
array $_options -Common and driver-specific options
array $_columns - Columns fields names and labels
int $_columnsNum - Number of columns
array $_records - Records content
int $_recordsNum - Number of records in the current page
int $_totalRecordsNum - Total number of records as reported by the datasource
int $_firstRecord - First record number (starting from 1), in the current page
int $_lastRecord - Last record number (starting from 1), in the current page
int $_page - Current page number (starting from 1)
int $_pageLimit - Number of records per page
int $_pagesNum - Number of pages
string $_requestPrefix - GET/POST/Cookie parameters prefix
array $_currentSort - Fields/directions the data is currently sorted by
array $_sortableFields - Which fields the datagrid may be sorted by
All of the following methods are optional.
The constructor must set default options via _addDefaultOptions(), if any, and call the parent constructor.
setContainer() is responsible for attaching a rendering container provided by the user. It must return a PEAR_Error object in case of failure.
getContainer() must return a reference to the container used by the driver. It must return a PEAR_Error object in case of failure.
init() must initialize the rendering process. This method is also responsible for creating the container if it has not already been provided with setContainer().
buildHeader() must build the header. $columns is a convenient reference to the $_columns property.
_addDefaultOptions() is used to declare the driver-specific options, if any, as well as their default values. It must be called from the constructor.
setOptions() is a public method used to set options. If they ever need to change options, drivers should use this method.
Builds the DataGrid class. The Core functionality and Renderer are seperated for maintainability and to keep cohesion high.
The number of records to display per page.
The current page viewed. In most cases, this is useless. Note: if you specify this, the "page" GET variable will be ignored.
The type of renderer to use. You may prefer to use the $type argument of render() , fill() or getOutput()
Пример 57-1. Instantiation
|
One of: "last", "first", "after" or "before" (default: "last")
The name (label) or field name of the relative column, if $position is "after" or "before"
The Structures_DataGrid_Column object (reference to)
Пример 57-1. Adding a simple column
|
The record set in any of the supported data source types
Optional. The options to be used for the data source
Optional. The data source type
Пример 57-1. Bind an SQL query
|
Пример 57-2. Bind a DB_DataObject
|
A clever method which loads and instantiate data source drivers.
Can be called in various ways:
Detect the source type and load the appropriate driver with default options:
$driver =& Structures_DataGrid::dataSourceFactory($source); |
Detect the source type and load the appropriate driver with custom options:
$driver =& Structures_DataGrid::dataSourceFactory($source, $options); |
Load a driver for an explicit type (faster, bypasses detection routine):
$driver =& Structures_DataGrid::dataSourceFactory($source, $options, $type); |
The data source respective to the driver
An associative array of the form: array(optionName => optionValue, ...)
The data source type constant (of the form DATAGRID_SOURCE_*)
A rendering container of any of the supported types (example: an HTML_Table object, a Spreadsheet_Excel_Writer object, etc...)
Options for the corresponding rendering driver
Explicit type in case the container type can't be detected
Пример 57-1. Filling a Pager object
|
Пример 57-2. Fill a form with sort fields
|
This is a shortcut for adding simple columns easily, instead of creating them manually and calling addColumn() for each.
The generated columns are appended to the current column set.
Fields and labels. Array of the form: array(field => label, ...) The default is an empty array, which means: all fields fetched from the datasource
returns Structures_DataGrid_Column objects (references to). This is a numerically indexed array (starting from 0).
returns the number of the first record currently shown, or: 0 if there are no records, 1 if there is no row limit
Renderer type (optional)
An associative array of the form: array(optionName => optionValue, ...)
returns The datagrid output (Usually a string: HTML, CSV, etc...) or a PEAR_Error
returns the total number of pages or 1 if there are no records or if there is no row limit
Пример 57-1. Remove an unneeded column
|
Renderer type or instance (optional)
An associative array of the form: array(optionName => optionValue, ...)
An associative array of the form: array("option_name" => "option_value",...)
If there is no sorting query in the HTTP request, and if the sortRecordSet() method is not called, then the specification passed to setDefaultSort() will be used.
This is especially useful if you want the data to already be sorted when a user first see the datagrid.
Defines which renderer to be used by the DataGrid based on given $type and $options. To attach an existing renderer instance, use attachRenderer() instead.
An associative array of the form: array("option_name" => "option_value",...)
If you need to change the request variables, you can define a prefix. This is extra useful when using multiple datagrids.
Do not use this method if data is coming from a database as sorting is much faster coming directly from the database itself.
require_once 'Structures/DataGrid/Column.php'; |
void constructor
Structures_DataGrid_Column::Structures_DataGrid_Column
(string
$label, string
[$field = NULL], string
[$orderBy = NULL], array
[$attributes = array()], string
[$autoFillValue = NULL], mixed
[$formatter = NULL], array
[$formatterArgs = array()])
The label of the column to be printed
The name of the field for the column to be mapped to
The field or expression to order the data by
The attributes for the XML or HTML TD tag; form: array(name => value, ...)
The value to use for the autoFill
Formatter callback. See setFormatter()
Associative array of arguments passed as second argument to the formatter callback
EXPERIMENTAL: the behaviour of this method may change in future releases.
This method allows to associate an "automatic" predefined formatter to the column, for common needs as formatting dates, numbers, ...
The currently supported predefined formatters are :
dateFromTimestamp: format a UNIX timestamp according to the date()-like format string passed as second argument
dateFromMysql : format a MySQL DATE, DATETIME, or TIMESTAMP MySQL according to the date() like format string passed as second argument
number: format a number, according to the same optional 2nd, 3rd and 4th arguments that the number_format() PHP function accepts.
printf: format using the printf expression passed as 2nd argument.
printfURL: url-encode and format using the printf expression passed as 2nd argument
Пример 57-1. Common formats
|
This method is not meant to be called by user-space code.
Calls a predefined function to develop custom output for the column. The defined function can accept parameters so that each cell in the column can be unique based on the record. The function will also automatically receive the record array as a parameter. All parameters passed into the function will be in one array.
Return the attributes applied to all cells in this column. This only makes sense for HTML or XML rendering
Returns the name of the field to order the data by. With SQL based datasources, this may be an SQL expression (function, etc..).
Set the attributes to be applied to all cells in this column. This only makes sense for HTML or XML rendering
Callback PHP pseudo-type (Array or String)
Associative array of parameters passed to as second argument to the callback function
This driver supports the following operation modes:
Таблица 57-1. Supported operations modes of this driver
Mode | Supported? |
---|---|
Multiple field sorting | no |
Insert, update and delete records | no |
This driver accepts the following options:
Таблица 57-2. Options for this driver
Option | Type | Description | Default Value |
---|---|---|---|
fields | array | Which data fields to fetch from the datasource. An empty array means: all fields. Form: array(field1, field2, ...) | array() |
generate_columns | bool | Generate Structures_DataGrid_Column objects with labels. See the 'labels' option. DEPRECATED: use Structures_DataGrid::generateColumns() instead | false |
labels | array | Data field to column label mapping. Only used when 'generate_columns' is true. Form: array(field => label, ...) DEPRECATED: use Structures_DataGrid::generateColumns() instead | array() |
primary_key | array | Name(s), or numerical index(es) of the field(s) which contain a unique record identifier (only use several fields in case of a multiple-fields primary key) | null |
This class is a data source driver for a CSV File. It will also support any other delimiter.
This driver supports the following operation modes:
Таблица 57-1. Supported operations modes of this driver
Mode | Supported? |
---|---|
Multiple field sorting | no |
Insert, update and delete records | no |
This driver accepts the following options:
Таблица 57-2. Options for this driver
Option | Type | Description | Default Value |
---|---|---|---|
delimiter | string | Field delimiter | ',' |
fields | array | Which data fields to fetch from the datasource. An empty array means: all fields. Form: array(field1, field2, ...) | array() |
generate_columns | bool | Generate Structures_DataGrid_Column objects with labels. See the 'labels' option. DEPRECATED: use Structures_DataGrid::generateColumns() instead | false |
header | bool | Whether the CSV file (or string) contains a header row | false |
labels | array | Data field to column label mapping. Only used when 'generate_columns' is true. Form: array(field => label, ...) DEPRECATED: use Structures_DataGrid::generateColumns() instead | array() |
primary_key | array | Name(s), or numerical index(es) of the field(s) which contain a unique record identifier (only use several fields in case of a multiple-fields primary key) | null |
This driver supports the following operation modes:
Таблица 57-1. Supported operations modes of this driver
Mode | Supported? |
---|---|
Multiple field sorting | yes |
Insert, update and delete records | no |
This driver accepts the following options:
Таблица 57-2. Options for this driver
Option | Type | Description | Default Value |
---|---|---|---|
fields | array | Which data fields to fetch from the datasource. An empty array means: all fields. Form: array(field1, field2, ...) | array() |
fields_property | string | The name of a property that you can set within your DataObject. This property is expected to contain the same kind of information as the 'fields' option. If the 'fields' option is set, this one will not be used. | 'fb_fieldsToRender' |
generate_columns | bool | Generate Structures_DataGrid_Column objects with labels. See the 'labels' option. DEPRECATED: use Structures_DataGrid::generateColumns() instead | false |
labels | array | Data field to column label mapping. Only used when 'generate_columns' is true. Form: array(field => label, ...) DEPRECATED: use Structures_DataGrid::generateColumns() instead | array() |
labels_property | string | The name of a property that you can set within your DataObject. This property is expected to contain the same kind of information as the 'labels' option. If the 'labels' option is set, this one will not be used. | 'fb_fieldLabels' |
primary_key | array | Name(s), or numerical index(es) of the field(s) which contain a unique record identifier (only use several fields in case of a multiple-fields primary key) | null |
This driver supports the following operation modes:
Таблица 57-1. Supported operations modes of this driver
Mode | Supported? |
---|---|
Multiple field sorting | no |
Insert, update and delete records | no |
This driver accepts the following options:
Таблица 57-2. Options for this driver
Option | Type | Description | Default Value |
---|---|---|---|
fields | array | Which data fields to fetch from the datasource. An empty array means: all fields. Form: array(field1, field2, ...) | array() |
generate_columns | bool | Generate Structures_DataGrid_Column objects with labels. See the 'labels' option. DEPRECATED: use Structures_DataGrid::generateColumns() instead | false |
labels | array | Data field to column label mapping. Only used when 'generate_columns' is true. Form: array(field => label, ...) DEPRECATED: use Structures_DataGrid::generateColumns() instead | array() |
primary_key | array | Name(s), or numerical index(es) of the field(s) which contain a unique record identifier (only use several fields in case of a multiple-fields primary key) | null |
This driver supports the following operation modes:
Таблица 57-1. Supported operations modes of this driver
Mode | Supported? |
---|---|
Multiple field sorting | yes |
Insert, update and delete records | no |
This driver accepts the following options:
Таблица 57-2. Options for this driver
Option | Type | Description | Default Value |
---|---|---|---|
dbc | object | A PEAR::DB instance that will be used by this driver. Either this or the 'dsn' option is required. | null |
dsn | string | A PEAR::DB dsn string. The DB connection will be established by this driver. Either this or the 'dbc' option is required. | null |
fields | array | Which data fields to fetch from the datasource. An empty array means: all fields. Form: array(field1, field2, ...) | array() |
generate_columns | bool | Generate Structures_DataGrid_Column objects with labels. See the 'labels' option. DEPRECATED: use Structures_DataGrid::generateColumns() instead | false |
labels | array | Data field to column label mapping. Only used when 'generate_columns' is true. Form: array(field => label, ...) DEPRECATED: use Structures_DataGrid::generateColumns() instead | array() |
primary_key | array | Name(s), or numerical index(es) of the field(s) which contain a unique record identifier (only use several fields in case of a multiple-fields primary key) | null |
You need to specify either a DB instance or a DB compatible dsn string as an option to use this driver.
If you use complex queries (e.g. with complex joins or with aliases), $datagrid->getRecordCount() might return a wrong result. For the case of GROUP BY, UNION, or DISTINCT in your queries, this driver already has special handling. However, if you observe wrong record counts, you need to specify a special query that returns only the number of records (e.g. 'SELECT COUNT(*) FROM ...') as an additional option 'count_query' to the bind() call.
You can specify a ORDER BY statement in your query. Please be aware that this sorting statement is then used in *every* query before the sorting options that come from a renderer (e.g. by clicking on the column header when using the HTML_Table renderer which is sent in the HTTP request). If you want to give a default sorting statement that is only used if there is no sorting query in the HTTP request, then use $datagrid->setDefaultSort().
This driver supports the following operation modes:
Таблица 57-1. Supported operations modes of this driver
Mode | Supported? |
---|---|
Multiple field sorting | yes |
Insert, update and delete records | yes |
This driver accepts the following options:
Таблица 57-2. Options for this driver
Option | Type | Description | Default Value |
---|---|---|---|
fields | array | Which data fields to fetch from the datasource. An empty array means: all fields. Form: array(field1, field2, ...) | array() |
generate_columns | bool | Generate Structures_DataGrid_Column objects with labels. See the 'labels' option. DEPRECATED: use Structures_DataGrid::generateColumns() instead | false |
labels | array | Data field to column label mapping. Only used when 'generate_columns' is true. Form: array(field => label, ...) DEPRECATED: use Structures_DataGrid::generateColumns() instead | array() |
params | array | Placeholder parameters for prepare/execute | array() |
primary_key | array | Name(s), or numerical index(es) of the field(s) which contain a unique record identifier (only use several fields in case of a multiple-fields primary key) | null |
view | string | The view from $sql array in your DB_Table object. This option is required. | null |
where | string | A where clause for the SQL query. | null |
If you use aliases in the select part of your view, the count() method from DB_Table and, therefore, $datagrid->getRecordCount() might return a wrong result. To avoid this, DB_Table uses a special query for counting if it is given via a view that needs to be named as '__count_' followed by the name of the view that this counting view belongs to. (For example: if you have a view named 'all', the counting view needs to be named as '__count_all'.)
To use update() and delete() methods, it is required that the indexes are properly defined in the $idx array in your DB_Table subclass. If you have, for example, created your database table yourself and did not setup the $idx array, you can use the 'primary_key' option to define the primary key field.
This driver supports the following operation modes:
Таблица 57-1. Supported operations modes of this driver
Mode | Supported? |
---|---|
Multiple field sorting | no |
Insert, update and delete records | no |
This driver accepts the following options:
Таблица 57-2. Options for this driver
Option | Type | Description | Default Value |
---|---|---|---|
fields | array | Which data fields to fetch from the datasource. An empty array means: all fields. Form: array(field1, field2, ...) | array() |
generate_columns | bool | Generate Structures_DataGrid_Column objects with labels. See the 'labels' option. DEPRECATED: use Structures_DataGrid::generateColumns() instead | false |
header | bool | Whether the Excel file contains a header row | false |
labels | array | Data field to column label mapping. Only used when 'generate_columns' is true. Form: array(field => label, ...) DEPRECATED: use Structures_DataGrid::generateColumns() instead | array() |
primary_key | array | Name(s), or numerical index(es) of the field(s) which contain a unique record identifier (only use several fields in case of a multiple-fields primary key) | null |
This class expects the file reader.php in the directory Spreadsheet/Excel/.
Please note that the current version (2i) of Spreadsheet_Excel_Reader contains a die() statement in the read() method in reader.php (line 171). This makes a reasonable PEAR error handling for the "file not found" error impossible.
It is therefore recommended that you replace the die() statement by something like this:
return PEAR::raiseError('The filename ' . $sFileName . ' is not readable'); |
This driver supports the following operation modes:
Таблица 57-1. Supported operations modes of this driver
Mode | Supported? |
---|---|
Multiple field sorting | yes |
Insert, update and delete records | no |
This driver accepts the following options:
Таблица 57-2. Options for this driver
Option | Type | Description | Default Value |
---|---|---|---|
dbc | object | A PEAR::MDB2 instance that will be used by this driver. Either this or the 'dsn' option is required. | null |
dsn | string | A PEAR::MDB2 dsn string. The MDB2 connection will be established by this driver. Either this or the 'dbc' option is required. | null |
fields | array | Which data fields to fetch from the datasource. An empty array means: all fields. Form: array(field1, field2, ...) | array() |
generate_columns | bool | Generate Structures_DataGrid_Column objects with labels. See the 'labels' option. DEPRECATED: use Structures_DataGrid::generateColumns() instead | false |
labels | array | Data field to column label mapping. Only used when 'generate_columns' is true. Form: array(field => label, ...) DEPRECATED: use Structures_DataGrid::generateColumns() instead | array() |
primary_key | array | Name(s), or numerical index(es) of the field(s) which contain a unique record identifier (only use several fields in case of a multiple-fields primary key) | null |
You need to specify either a MDB2 instance or a MDB2 compatible dsn string as an option to use this driver.
If you use complex queries (e.g. with complex joins or with aliases), $datagrid->getRecordCount() might return a wrong result. For the case of GROUP BY, UNION, or DISTINCT in your queries, this driver already has special handling. However, if you observe wrong record counts, you need to specify a special query that returns only the number of records (e.g. 'SELECT COUNT(*) FROM ...') as an additional option 'count_query' to the bind() call.
You can specify a ORDER BY statement in your query. Please be aware that this sorting statement is then used in *every* query before the sorting options that come from a renderer (e.g. by clicking on the column header when using the HTML_Table renderer which is sent in the HTTP request). If you want to give a default sorting statement that is only used if there is no sorting query in the HTTP request, then use $datagrid->setDefaultSort().
This driver supports the following operation modes:
Таблица 57-1. Supported operations modes of this driver
Mode | Supported? |
---|---|
Multiple field sorting | no |
Insert, update and delete records | no |
This driver accepts the following options:
Таблица 57-2. Options for this driver
Option | Type | Description | Default Value |
---|---|---|---|
fields | array | Which data fields to fetch from the datasource. An empty array means: all fields. Form: array(field1, field2, ...) | array() |
generate_columns | bool | Generate Structures_DataGrid_Column objects with labels. See the 'labels' option. DEPRECATED: use Structures_DataGrid::generateColumns() instead | false |
labels | array | Data field to column label mapping. Only used when 'generate_columns' is true. Form: array(field => label, ...) DEPRECATED: use Structures_DataGrid::generateColumns() instead | array() |
primary_key | array | Name(s), or numerical index(es) of the field(s) which contain a unique record identifier (only use several fields in case of a multiple-fields primary key) | null |
This driver supports the following operation modes:
Таблица 57-1. Supported operations modes of this driver
Mode | Supported? |
---|---|
Multiple field sorting | no |
Insert, update and delete records | no |
This driver accepts the following options:
Таблица 57-2. Options for this driver
Option | Type | Description | Default Value |
---|---|---|---|
fieldAttribute | string | Which attribute of the XML source should be used as column field name (only used if the XML source has attributes). | null |
fields | array | Which data fields to fetch from the datasource. An empty array means: all fields. Form: array(field1, field2, ...) | array() |
generate_columns | bool | Generate Structures_DataGrid_Column objects with labels. See the 'labels' option. DEPRECATED: use Structures_DataGrid::generateColumns() instead | false |
labelAttribute | string | Which attribute of the XML source should be used as column label (only used if 'generate_columns' is true and the XML source has attributes). | null |
labels | array | Data field to column label mapping. Only used when 'generate_columns' is true. Form: array(field => label, ...) DEPRECATED: use Structures_DataGrid::generateColumns() instead | array() |
primary_key | array | Name(s), or numerical index(es) of the field(s) which contain a unique record identifier (only use several fields in case of a multiple-fields primary key) | null |
xpath | string | XPath to a subset of the XML data. | '' |
This driver supports the following operation modes:
Таблица 57-1. Supported operations modes of this driver
Mode | Supported? |
---|---|
Container Support | yes |
Output Buffering | yes |
Direct Rendering | no |
Streaming | no |
This driver accepts the following options:
Таблица 57-2. Options for this driver
Option | Type | Description | Default Value |
---|---|---|---|
buildFooter | bool | Whether to build the footer. | true |
buildHeader | bool | Whether to build the header. | true |
defaultCellValue | string | What value to put by default into empty cells. | null |
defaultColumnValues | array | Per-column default cell value. This is an array of the form: array(fieldName => value, ...). | array() |
encoding | string | The content encoding. If the mbstring extension is present the default value is set from mb_internal_encoding(), otherwise it is ISO-8859-1. | 'ISO-8859-1' |
excludeVars | array | Variables to be removed from the generated HTTP queries. | array() |
extraVars | array | Variables to be added to the generated HTTP queries. | array() |
fillWithEmptyRows | bool | Ensures that all pages have the same number of rows. | false |
hideColumnLinks | array | By default sorting links are enabled on all columns. With this option it is possible to disable sorting links on specific columns. This is an array of the form: array(fieldName, ...). This option only affects drivers that support sorting. | array() |
numberAlign | bool | Whether to right-align numeric values. | true |
This driver supports the following operation modes:
Таблица 57-1. Supported operations modes of this driver
Mode | Supported? |
---|---|
Container Support | no |
Output Buffering | yes |
Direct Rendering | yes |
Streaming | yes |
This driver accepts the following options:
Таблица 57-2. Options for this driver
Option | Type | Description | Default Value |
---|---|---|---|
buildFooter | bool | Whether to build the footer. | true |
buildHeader | bool | Whether to build the header. | true |
defaultCellValue | string | What value to put by default into empty cells. | null |
defaultColumnValues | array | Per-column default cell value. This is an array of the form: array(fieldName => value, ...). | array() |
delimiter | string | Field delimiter | ',' |
enclosure | string | Field enclosure | '"' |
encoding | string | The content encoding. If the mbstring extension is present the default value is set from mb_internal_encoding(), otherwise it is ISO-8859-1. | 'ISO-8859-1' |
excludeVars | array | Variables to be removed from the generated HTTP queries. | array() |
extraVars | array | Variables to be added to the generated HTTP queries. | array() |
filename | string | Filename of the generated CSV file; boolean false means that no filename will be sent | false |
fillWithEmptyRows | bool | Ensures that all pages have the same number of rows. | false |
hideColumnLinks | array | By default sorting links are enabled on all columns. With this option it is possible to disable sorting links on specific columns. This is an array of the form: array(fieldName, ...). This option only affects drivers that support sorting. | array() |
lineBreak | string | The character(s) to use for line breaks | '\n' |
numberAlign | bool | Whether to right-align numeric values. | true |
saveToFile | boolean | Whether the output should be saved on the local filesystem. Please note that the 'filename' option must be given if this option is set to true. | false |
useQuotes | mixed | Whether or not to encapsulate the values with the enclosure value. true: always, false: never, 'auto': when needed | 'auto' |
This driver supports the following operation modes:
Таблица 57-1. Supported operations modes of this driver
Mode | Supported? |
---|---|
Container Support | yes |
Output Buffering | yes |
Direct Rendering | no |
Streaming | no |
This driver accepts the following options:
Таблица 57-2. Options for this driver
Option | Type | Description | Default Value |
---|---|---|---|
buildFooter | bool | Whether to build the footer. | true |
buildHeader | bool | Whether to build the header. | true |
defaultCellValue | string | What value to put by default into empty cells. | null |
defaultColumnValues | array | Per-column default cell value. This is an array of the form: array(fieldName => value, ...). | array() |
encoding | string | The content encoding. If the mbstring extension is present the default value is set from mb_internal_encoding(), otherwise it is ISO-8859-1. | 'ISO-8859-1' |
excludeVars | array | Variables to be removed from the generated HTTP queries. | array() |
extraVars | array | Variables to be added to the generated HTTP queries. | array() |
fillWithEmptyRows | bool | Ensures that all pages have the same number of rows. | false |
hideColumnLinks | array | By default sorting links are enabled on all columns. With this option it is possible to disable sorting links on specific columns. This is an array of the form: array(fieldName, ...). This option only affects drivers that support sorting. | array() |
numberAlign | bool | Whether to right-align numeric values. | true |
textSubmit | string | Label for the submit button | 'Submit' |
Пример 57-1. Basic usage
|
Пример 57-2. Usage with tableless renderer and DHTMLRules
|
This driver renders a form (using HTML_QuickForm) so that the user can select several fields and directions to sort the datagrid by.
This driver supports the following operation modes:
Таблица 57-1. Supported operations modes of this driver
Mode | Supported? |
---|---|
Container Support | yes |
Output Buffering | yes |
Direct Rendering | no |
Streaming | no |
This driver accepts the following options:
Таблица 57-2. Options for this driver
Option | Type | Description | Default Value |
---|---|---|---|
buildFooter | bool | Whether to build the footer. | true |
buildHeader | bool | Whether to build the header. | true |
defaultCellValue | string | What value to put by default into empty cells. | null |
defaultColumnValues | array | Per-column default cell value. This is an array of the form: array(fieldName => value, ...). | array() |
directionStyle | string | Whether to render the direction form elements as 'select' or 'radio' elements | 'select' |
encoding | string | The content encoding. If the mbstring extension is present the default value is set from mb_internal_encoding(), otherwise it is ISO-8859-1. | 'ISO-8859-1' |
excludeVars | array | Variables to be removed from the generated HTTP queries. | array() |
extraVars | array | Variables to be added to the generated HTTP queries. | array() |
fillWithEmptyRows | bool | Ensures that all pages have the same number of rows. | false |
hideColumnLinks | array | By default sorting links are enabled on all columns. With this option it is possible to disable sorting links on specific columns. This is an array of the form: array(fieldName, ...). This option only affects drivers that support sorting. | array() |
numberAlign | bool | Whether to right-align numeric values. | true |
sortFieldsNum | int | How many fields the user will be able to sort by. This has no effect if the backend does not support sorting by multiple fields. | 3 |
textAscending | string | Label for the ASC direction | 'Ascending' |
textChoose | string | What to display in the select box when no field is selected (first option) | 'Choose...' |
textDescending | string | Label for the DESC direction | 'Descending' |
textSortBy | string | Label for the first field | 'Sort by:' |
textSubmit | string | Label for the submit button | 'Submit' |
textThenBy | string | Label for the second and following fields | 'Then by:' |
This driver supports the following operation modes:
Таблица 57-1. Supported operations modes of this driver
Mode | Supported? |
---|---|
Container Support | yes |
Output Buffering | yes |
Direct Rendering | no |
Streaming | no |
This driver accepts the following options:
Таблица 57-2. Options for this driver
Option | Type | Description | Default Value |
---|---|---|---|
buildFooter | bool | Whether to build the footer. | true |
buildHeader | bool | Whether to build the header. | true |
columnAttributes | array | Column cells attributes. This is an array of the form: array(fieldName => array(attribute => value, ...) ...) This option is only used by XML/HTML based drivers. | array() |
convertEntities | bool | Whether or not to convert html entities. This calls htmlspecialchars(). | true |
defaultCellValue | string | What value to put by default into empty cells. | null |
defaultColumnValues | array | Per-column default cell value. This is an array of the form: array(fieldName => value, ...). | array() |
emptyRowAttributes | array | An associative array containing the attributes for empty rows. | array() |
encoding | string | The content encoding. If the mbstring extension is present the default value is set from mb_internal_encoding(), otherwise it is ISO-8859-1. | 'ISO-8859-1' |
evenRowAttributes | array | An associative array containing each attribute of the even rows. | array() |
excludeVars | array | Variables to be removed from the generated HTTP queries. | array() |
extraVars | array | Variables to be added to the generated HTTP queries. | array() |
fillWithEmptyRows | bool | Ensures that all pages have the same number of rows. | false |
headerAttributes | array | Attributes for the header row. This is an array of the form: array(attribute => value, ...) | array() |
hideColumnLinks | array | By default sorting links are enabled on all columns. With this option it is possible to disable sorting links on specific columns. This is an array of the form: array(fieldName, ...). This option only affects drivers that support sorting. | array() |
numberAlign | bool | Whether to right-align numeric values. | true |
oddRowAttributes | array | An associative array containing each attribute of the odd rows. | array() |
selfPath | string | The complete path for sorting and paging links. | $_SERVER['PHP_SELF'] |
sortIconASC | string | The icon to define that sorting is currently ascending. Can be text or HTML to define an image. | '' |
sortIconDESC | string | The icon to define that sorting is currently descending. Can be text or HTML to define an image. | '' |
sortingResetsPaging | bool | Whether sorting HTTP queries reset paging. | true |
This driver provides generic paging. This driver has full container support. You can use the Structures_DataGrid::fill() method with it. It buffers output, you can use Structures_DataGrid::getOutput()
This driver supports the following operation modes:
Таблица 57-1. Supported operations modes of this driver
Mode | Supported? |
---|---|
Container Support | yes |
Output Buffering | yes |
Direct Rendering | no |
Streaming | no |
This driver accepts the following options:
Таблица 57-2. Options for this driver
Option | Type | Description | Default Value |
---|---|---|---|
buildFooter | bool | Whether to build the footer. | true |
buildHeader | bool | Whether to build the header. | true |
defaultCellValue | string | What value to put by default into empty cells. | null |
defaultColumnValues | array | Per-column default cell value. This is an array of the form: array(fieldName => value, ...). | array() |
encoding | string | The content encoding. If the mbstring extension is present the default value is set from mb_internal_encoding(), otherwise it is ISO-8859-1. | 'ISO-8859-1' |
excludeVars | array | Variables to be removed from the generated HTTP queries. | array() |
extraVars | array | Variables to be added to the generated HTTP queries. | array() |
fillWithEmptyRows | bool | Ensures that all pages have the same number of rows. | false |
hideColumnLinks | array | By default sorting links are enabled on all columns. With this option it is possible to disable sorting links on specific columns. This is an array of the form: array(fieldName, ...). This option only affects drivers that support sorting. | array() |
numberAlign | bool | Whether to right-align numeric values. | true |
pagerOptions | array | Options passed to Pager::factory(). Basic defaults are: mode: Sliding, delta: 5, separator: "|", prevImg: "<<" (<<), nextImg: ">>" (>>). The extraVars and excludeVars options are populated according to the Renderer common extraVars and excludeVars options. You may also specify some variables to be added or excluded here. The totalItems, perPage, urlVar, and currentPage options are set accordingly to the data statistics reported by the DataGrid and DataSource. You may overload these values here if you know what you are doing. |
This driver supports the following operation modes:
Таблица 57-1. Supported operations modes of this driver
Mode | Supported? |
---|---|
Container Support | yes |
Output Buffering | no |
Direct Rendering | no |
Streaming | no |
This driver accepts the following options:
Таблица 57-2. Options for this driver
Option | Type | Description | Default Value |
---|---|---|---|
buildFooter | bool | Whether to build the footer. | true |
buildHeader | bool | Whether to build the header. | true |
columnAttributes | array | Column cells attributes. This is an array of the form: array(fieldName => array(attribute => value, ...) ...) This option is only used by XML/HTML based drivers. | array() |
convertEntities | bool | Whether or not to convert html entities. This calls htmlspecialchars(). | true |
defaultCellValue | string | What value to put by default into empty cells. | null |
defaultColumnValues | array | Per-column default cell value. This is an array of the form: array(fieldName => value, ...). | array() |
encoding | string | The content encoding. If the mbstring extension is present the default value is set from mb_internal_encoding(), otherwise it is ISO-8859-1. | 'ISO-8859-1' |
excludeVars | array | Variables to be removed from the generated HTTP queries. | array() |
extraVars | array | Variables to be added to the generated HTTP queries. | array() |
fillWithEmptyRows | bool | Ensures that all pages have the same number of rows. | false |
hideColumnLinks | array | By default sorting links are enabled on all columns. With this option it is possible to disable sorting links on specific columns. This is an array of the form: array(fieldName, ...). This option only affects drivers that support sorting. | array() |
numberAlign | bool | Whether to right-align numeric values. | true |
selfPath | string | The complete path for sorting and paging links. | $_SERVER['PHP_SELF'] |
sortingResetsPaging | bool | Whether sorting HTTP queries reset paging. | true |
This driver does not support the render() method, it only is able to "fill" a Smarty object, by calling Smarty::assign() and Smarty::register_function().
It's up to you to called Smarty::display() after the Smarty object has been filled.
This driver assigns the following Smarty variables: - $columnSet: array of columns specifications structure: array ( 0 => array ( 'name' => field name, 'label' => column label, 'link' => sorting link, 'attributes' => attributes string, ), ... ) - $recordSet: array of records values - $currentPage: current page (starting from 1) - $recordLimit: number of rows per page - $pagesNum: number of pages - $columnsNum: number of columns - $recordsNum: number of records in the current page - $totalRecordsNum: total number of records - $firstRecord: first record number (starting from 1) - $lastRecord: last record number (starting from 1) - $currentSort: array with column names and the directions used for sorting
This driver also registers a Smarty custom function named getPaging that can be called from Smarty templates with {getPaging} in order to print paging links. This function accepts any of the Pager::factory() options as parameters.
Template example, featuring sorting and paging:
<!-- Show paging links using the custom getPaging function --> {getPaging prevImg="<<" nextImg=">>" separator=" | " delta="5"} <p>Showing records {$firstRecord} to {$lastRecord} from {$totalRecordsNum}, page {$currentPage} of {$pagesNum}</p> <table cellspacing="0"> <!-- Build header --> <tr> {section name=col loop=$columnSet} <th {$columnSet[col].attributes}> <!-- Check if the column is sortable --> {if $columnSet[col].link != ""} <a href="{$columnSet[col].link}">{$columnSet[col].label}</a> {else} {$columnSet[col].label} {/if} </th> {/section} </tr> <!-- Build body --> {section name=row loop=$recordSet} <tr {if $smarty.section.row.iteration is even}bgcolor="#EEEEEE"{/if}> {section name=col loop=$recordSet[row]} <td {$columnSet[col].attributes}>{$recordSet[row][col]}</td> {/section} </tr> {/section} </table> |
This template can be used with code similar to this prototype:
$smarty = new Smarty(...); $datagrid =& new Structures_DataGrid(...); $datagrid->bind(...); $datagrid->fill($smarty); $smarty->display(PATH TO YOUR TEMPLATE); |
This driver supports the following operation modes:
Таблица 57-1. Supported operations modes of this driver
Mode | Supported? |
---|---|
Container Support | yes |
Output Buffering | no |
Direct Rendering | not really, see below |
Streaming | no |
This driver accepts the following options:
Таблица 57-2. Options for this driver
Option | Type | Description | Default Value |
---|---|---|---|
bodyFormat | mixed | The format for body cells (either 0 [= "no format"] or a Spreadsheet_Excel_Writer_Format object) Please see the NOTE ABOUT FORMATTING below. | 0 |
border | int | Border drawn around the whole datagrid: 0 => none, 1 => thin, 2 => thick (NOT IMPLEMENTED YET) | 0 |
buildFooter | bool | Whether to build the footer. | true |
buildHeader | bool | Whether to build the header. | true |
defaultCellValue | string | What value to put by default into empty cells. | null |
defaultColumnValues | array | Per-column default cell value. This is an array of the form: array(fieldName => value, ...). | array() |
encoding | string | The content encoding. If the mbstring extension is present the default value is set from mb_internal_encoding(), otherwise it is ISO-8859-1. | 'ISO-8859-1' |
excludeVars | array | Variables to be removed from the generated HTTP queries. | array() |
extraVars | array | Variables to be added to the generated HTTP queries. | array() |
filename | string | The filename of the spreadsheet | 'spreadsheet.xls' |
fillWithEmptyRows | bool | Ensures that all pages have the same number of rows. | false |
headerBorder | int | Border between the header and body: 0 => none, 1 => thin, 2 => thick (NOT IMPLEMENTED YET) | 0 |
headerFormat | mixed | The format for header cells (either 0 [= "no format"] or a Spreadsheet_Excel_Writer_Format object) Please see the NOTE ABOUT FORMATTING below. | 0 |
hideColumnLinks | array | By default sorting links are enabled on all columns. With this option it is possible to disable sorting links on specific columns. This is an array of the form: array(fieldName, ...). This option only affects drivers that support sorting. | array() |
numberAlign | bool | Whether to right-align numeric values. | true |
sendToBrowser | bool | Should the spreadsheet be send to the browser? (true = send to browser, false = write to a file) | true |
startCol | int | The Worksheet column number to start rendering at | 0 |
startRow | int | The Worksheet row number to start rendering at | 0 |
worksheet | object | Optional reference to a Spreadsheet_Excel_Writer_Worksheet object. You can leave this to null except if your workbook contains several worksheets and you want to fill a specific one. | null |
This driver does not support the flatten() method. You can not retrieve its output with DataGrid::getOutput(). You can either render it directly to the browser or save it to a file. See the "sendToBrowser" and "filename" options.
This driver has container support. You can use Structures_DataGrid::fill() with it; that's even recommended.
NOTE ABOUT FORMATTING:
You can specify some formatting with the 'headerFormat' and 'bodyFormat' options, or with setBodyFormat() and setHeaderFormat().
But beware of the following from the Spreadsheet_Excel_Writer manual: "Formats can't be created directly by a new call. You have to create a format using the addFormat() method from a Workbook, which associates your Format with this Workbook (you can't use the Format with another Workbook)."
What this means is that if you want to pass a format to this driver you have to "derive" the Format object out of the workbook used in the driver.
The easiest way to do this is:
// Create a workbook $workbook = new Spreadsheet_Excel_Writer(); // Specify that spreadsheet must be sent the browser $workbook->send('test.xls'); // Create your format $format_bold =& $workbook->addFormat(); $format_bold->setBold(); // Fill the workbook, passing the format as an option $options = array('headerFormat' => &$format_bold); $datagrid->fill($workbook, $options); |
This driver supports the following operation modes:
Таблица 57-1. Supported operations modes of this driver
Mode | Supported? |
---|---|
Container Support | no |
Output Buffering | yes |
Direct Rendering | yes |
Streaming | yes |
This driver accepts the following options:
Таблица 57-2. Options for this driver
Option | Type | Description | Default Value |
---|---|---|---|
buildFooter | bool | Whether to build the footer. | true |
buildHeader | bool | Whether to build the header. | true |
columnAttributes | array | Column cells attributes. This is an array of the form: array(fieldName => array(attribute => value, ...) ...) This option is only used by XML/HTML based drivers. | array() |
defaultCellValue | string | What value to put by default into empty cells. | null |
defaultColumnValues | array | Per-column default cell value. This is an array of the form: array(fieldName => value, ...). | array() |
encoding | string | The content encoding. If the mbstring extension is present the default value is set from mb_internal_encoding(), otherwise it is ISO-8859-1. | 'ISO-8859-1' |
excludeVars | array | Variables to be removed from the generated HTTP queries. | array() |
extraVars | array | Variables to be added to the generated HTTP queries. | array() |
fieldAttribute | string | The name of the attribute for the field name. null stands for no attribute | null |
fieldTag | string | The name of the tag for each field inside a row, without brackets. The special value '{field}' is replaced by the field name. | '{field}' |
filename | string | Filename of the generated XML file; boolean false means that no filename will be sent | false |
fillWithEmptyRows | bool | Ensures that all pages have the same number of rows. | false |
hideColumnLinks | array | By default sorting links are enabled on all columns. With this option it is possible to disable sorting links on specific columns. This is an array of the form: array(fieldName, ...). This option only affects drivers that support sorting. | array() |
labelAttribute | string | The name of the attribute for the column label. null stands for no attribute | null |
numberAlign | bool | Whether to right-align numeric values. | true |
outerTag | string | The name of the tag for the datagrid, without brackets | 'DataGrid' |
rowTag | string | The name of the tag for each row, without brackets | 'Row' |
saveToFile | boolean | Whether the output should be saved on the local filesystem. Please note that the 'filename' option must be given if this option is set to true. | false |
useXMLDecl | bool | Whether the XML declaration string should be added to the output. The encoding attribute value will get set from the common "encoding" option. If you need to further customize the XML declaration (version, etc..), then please set "useXMLDecl" to false, and add your own declaration string. | true |
This driver supports the following operation modes:
Таблица 57-1. Supported operations modes of this driver
Mode | Supported? |
---|---|
Container Support | no |
Output Buffering | yes |
Direct Rendering | no |
Streaming | no |
This driver accepts the following options:
Таблица 57-2. Options for this driver
Option | Type | Description | Default Value |
---|---|---|---|
buildFooter | bool | Whether to build the footer. | true |
buildHeader | bool | Whether to build the header. | true |
defaultCellValue | string | What value to put by default into empty cells. | null |
defaultColumnValues | array | Per-column default cell value. This is an array of the form: array(fieldName => value, ...). | array() |
encoding | string | The content encoding. If the mbstring extension is present the default value is set from mb_internal_encoding(), otherwise it is ISO-8859-1. | 'ISO-8859-1' |
excludeVars | array | Variables to be removed from the generated HTTP queries. | array() |
extraVars | array | Variables to be added to the generated HTTP queries. | array() |
fillWithEmptyRows | bool | Ensures that all pages have the same number of rows. | false |
hideColumnLinks | array | By default sorting links are enabled on all columns. With this option it is possible to disable sorting links on specific columns. This is an array of the form: array(fieldName, ...). This option only affects drivers that support sorting. | array() |
numberAlign | bool | Whether to right-align numeric values. | true |
selfPath | string | The complete path for sorting links | $_SERVER['PHP_SELF'] |
This renderer class will render a XUL listbox. For additional information on the XUL Listbox, refer to this url: http://www.xulplanet.com/references/elemref/ref_listbox.html
You have to setup your XUL document, just as you would with an HTML document. This driver will only generated the <listbox> element and content.
Basic example:
<?php header('Content-type: application/vnd.mozilla.xul+xml'); echo "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n"; echo "<?xml-stylesheet href=\"myStyle.css\" type=\"text/css\"?>\n"; echo "<window title=\"MyDataGrid\" xmlns=\"http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul\">\n"; // Instantiate your datagrid and setup its datasource, then call: $datagrid->setRenderer('XUL'); $datagrid->render(); echo "</window>\n"; ?> |
Games_Chess is like a brilliant helper who can tell you anything you need to know about an abstract chess game. The only thing Games_Chess cannot do is play against you - it is not a chess engine. Games_Chess handles the logic a chessboard and parsing standard FEN (Forsyth-Edwards Notation) for describing a position as well as SAN (Standard Algebraic Notation) for describing individual moves. This package can be used as a backend driver for playing chess, or for validating and/or creating PGN files using the File_ChessPGN package (when it is completed)
Games_Chess provides a basic interface for validating and playing chess. Games_Chess has facilities for calculating all of the important chess rules including check, checkmate, stalemate, basic draws such as bishop+king versus king, 50 move draw, en passant pawn captures, castling, double space first pawn move and basic piece movement. In addition, Games_Chess can set up a board to a position using the Forsyth-Edwards Notation (FEN) and can output a list of moves in Standard Algebraic Notation (SAN) as well as parse any valid SAN move, no matter how obscure (Qa3xf3, for instance), as well as simple "move the piece on a3 to h3" commands.
The Games_Chess package comes with a demonstration file, which has highlighted source at This location.
The Games_Chess package provides three different drivers, one for playing a standard chess game, and two for playing interesting variant games that are popular on the Internet Chess Club (ICC).
Crazyhouse. basic rules in Crazyhouse chess allow you to place pieces you have captured from your opponent on the board as new pieces for your own army. This is a wild and highly tactical game.
Loser's Chess. Loser's chess is similar to checkers in that if a capture is possible, it must be executed. For this reason, most of the moves are forcing moves in this game, and it results in very fast games.
To use Games_Chess on the most basic level is simple. Here is a sample script showing the initialization of the three drivers:
<?php require_once 'Games/Chess/Standard.php'; require_once 'Games/Chess/Crazyhouse.php'; require_once 'Games/Chess/Losers.php'; $standard = new Games_Chess_Standard; $crazyhouse = new Games_Chess_Crazyhouse; $losers = new Games_Chess_Losers; ?> |
<?php require_once 'Games/Chess/Standard.php'; $standard = new Games_Chess_Standard; $standard->resetGame(); ?> |
<?php require_once 'Games/Chess/Standard.php'; $standard = new Games_Chess_Standard; $standard->resetGame('rnbqkbnr/pp1ppppp/8/2p5/4P3/8/PPPP1PPP/RNBQKBNR w KQkq c6 0 2'); ?> |
There are two basic methods for performing moves with Games_Chess, moveSAN and moveSquare. Both of these methods either return TRUE or a PEAR_Error class upon error, so the proper way to handle for a return value is:
<?php require_once 'Games/Chess/Standard.php'; $standard = new Games_Chess_Standard; $err = $standard->moveSAN('Nf9'); if ($standard->isError($err)) { echo $err->getMessage(); die; } ?> |
The example below demonstrates the two ways that Games_Chess should be called to make moves on the chess board, including the way to represent a placement move in the Crazyhouse variant:
<?php require_once 'PEAR.php'; // for the PEAR_Error class function showerror($err) { echo $err->getMessage(); exit; } require_once 'Games/Chess/Standard.php'; require_once 'Games/Chess/Crazyhouse.php'; PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, 'showerror'); $standard = new Games_Chess_Standard; $crazyhouse = new Games_Chess_Crazyhouse; $standard->resetGame(); $crazyhouse->resetGame(); $standard->moveSAN('e4'); // 'e2' to 'e4' if using moveSquare $standard->moveSquare('d7', 'd5'); // 'd5' if using moveSAN $standard->moveSAN('exd5'); $crazyhouse->moveSquare('e2', 'e4'); // same as moveSAN() above $crazyhouse->moveSAN('d5'); // save as moveSquare above $crazyhouse->moveSAN('exd5'); $crazyhouse->moveSAN('Qxd5'); $crazyhouse->moveSAN('P@d7'); // dumb move, but demonstrates piece placement ?> |
<?php require_once 'PEAR.php'; // for the PEAR_Error class function showerror($err) { echo $err->getMessage(); exit; } require_once 'Games/Chess/Crazyhouse.php'; PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, 'showerror'); $crazyhouse = new Games_Chess_Crazyhouse; $crazyhouse->resetGame(); $crazyhouse->moveSAN('e4'); $crazyhouse->moveSAN('d5'); $crazyhouse->moveSAN('exd5'); $crazyhouse->moveSAN('Qxd5'); $crazyhouse->moveSAN('d3'); $crazyhouse->moveSAN('Kd7'); $crazyhouse->moveSAN('d4'); $crazyhouse->moveSAN('Ke6'); $crazyhouse->moveSAN('P@d7'); $crazyhouse->moveSAN('Qd6'); // $crazyhouse->moveSAN('d8=Q'); // normal way to do this $crazyhouse->moveSquare('d7', 'd8', 'Q'); // using moveSquare to do this // dumb moves, but demonstrates pawn promotion to queen ?> |
To retrieve necessary information such as the current move list, current FEN, list of captured pieces (Crazyhouse only), determine whether the game is over and so on, you'll want to use one of the following methods:
gameOver(). This method can be used to determine if the game has concluded, and simply returns an abbreviation of W if the white pieces have won (checkmate), B if the black pieces have won (checkmate), D if there is a draw, or false if the game is still in progress.
This method returns a Forsyth-Edwards Notation (FEN) representation of the current game state. Note that the FEN standard does not contain a way to represent captured pieces, and so cannot be used to exactly replicate a Crazyhouse game in progress, although it can be close.
For the Standard and Loser's chess drivers, this returns an associative array of algebraic square name (a1 to h8) mapped to its contents. If the square is unoccupied, it will contain its algebraic square name (a1 will map to a1), otherwise it will contain the piece name, one of P, R, N, B, Q or K. If the piece is a white piece, it will be in upper case, like P, and if the piece is a black piece, it will be in lower case like p.
For the Crazyhouse driver, this returns an associative array with two indices, board and captured. The board element is identical to the return for Standard/Loser's chess drivers described in the previous paragraph. The captured sub-array contains an array of this format:
<?php $captured = array( 'W' => array( 'P' => 6, // 6 black pawns captured by white 'R' => 0, 'N' => 0, 'B' => 0, 'Q' => 0, ), 'B' => array( 'P' => 4, // 4 white pawns captured by black 'R' => 0, 'N' => 0, 'B' => 0, 'Q' => 0, ), ); ?> |
This methods simply returns the color of the pieces that have the next move. W is returned for white, B is returned for black.
Graph datastructure manipulation library
Structures_Graph is a package for creating and manipulating graph datastructures. It allows building of directed and undirected graphs, with data and metadata stored in nodes. The library provides functions for graph traversing as well as for characteristic extraction from the graph topology.
This package implements linked list structures. It supports both singly-linked lists (Structures_LinkedList_Single) and doubly-linked lists (Structures_LinkedList_Double).
Generic tree management, currently supports DB and XML as data sources
Provides methods to read and manipulate trees, which are stored in the DB or an XML file. The trees can be stored in the DB either as nested trees. Or as simple trees ('brain dead method'), which use parentId-like structure. Currently XML data can only be read from a file and accessed. The package offers a big number of methods to access and manipulate trees. For example methods like: getRoot, getChild[ren[Ids]], getParent[s[Ids]], getPath[ById] and many more.
Unfortunately, complete documentation is not available at the moment.
System Utilities
Returns locations of system folders like home, desktop, documents and others.
System_Folders provides methods to get the locations of various system folders like home directory, desktop folder and "My documents". You can use it on nearly every operating system: It works on Linux, Windows and Mac OS; allowing you to write OS independent programs.
The methods return a string of the directory (with trailing slash) if the directory can be determined, and NULL if it fails or isn't available on the system. For example, the "Shared Documents" folder exists on Windows only. If you run getSharedDocuments() on a Mac or Linux, the method will return NULL.
The class does heavy use of environment variables. That means it is very likely that the methods fail when running in a php server module (e.g. apache) because there is user information available. Using them on command line (cli) scripts gives best results, as the class is meant to be used for such ones.
Таблица 58-1. Available folders and their methods
Folder | Method to use | Notes |
---|---|---|
All users directory | getAllUsers() | Windows only |
Application data | getAppData() | |
Desktop | getDesktop() | |
Documents / My Documents | getDocuments() | |
Home directory | getHome() | |
Programs folder (installed ones) | getPrograms() | |
Temporary files | getTemp() | |
Shared documents | getSharedDocuments() | Windows only |
Windows directory | getWindows() | Windows only |
On every getXXX() call, the whole procedure of looping through environment variables, checking the existence of the folders and trying some common locations is executed. So if you call the same method again and again, it will cost you the same amount of cpu cycles every time and perhaps be a slowdown in your application.
Another problem might be that some methods fail or don't return the correct path, e.g. because the user has an unusual installation or unusual preferences.
Both issues are addressed with System_Folders_Cached. It provides a cached version of the getXXX() methods, meaning that the result of the first method calls are stored locally and returned on every further call, which speeds up consecutive calls to the same method a lot.
Further, the class provides methods to set the folder locations and save this settings into an ini file. Saving them can be done with saveToFile() and they can be loaded with loadFromFile(). This allows customization of the folder locations, and persistency across sessions.
Пример 58-1. General usage
|
At first, you need to instantitiate a new System_Folders object. The operating system is determined there, which is needed for all the other methods.
Then just use the getXXX() methods to retrieve the folder locations. Remember that they return NULL if the location can't be determined.
Пример 58-2. General usage
|
This example displays the location of the config file (in which the folder settings are stored), shows some folder locations and sets the documents directory to a (probably non-existing) directory and saves the folder locations.
In the next program call, the documents directory is reset to the normal one and saved again.
The package provides methods to monitor system process on Unix-like systems.
System::ProcWatch is a small collection of classes to ease monitoring of system processes based on the Unix program procps (ps).
To use System::ProcWatch you simply have to define a ruleset on which based System::ProcWatch operates. A rule (or job, watch) defines what actions should happen if a condition evaluates to true.
To be continued...
You can use System::ProcWatch out of the box, by utilizing the shipped shell scripts procwatch and procwatch-lint.
The procwatch command is meant to be used for system diagnosis - run as daemon or by cron.
The usage is best described by the output of procwatch -h:
USAGE: $ procwatch (-x|-i) <file> [-d [-s <sec>]] [-a <args>] [-p <file>] OPTIONS: -x | --xml= path to XML configuration file -i | --ini= path to INI configuration file -d | --daemon run procwatch in daemon mode -s | --sleep= seconds to sleep in daemon mode (default=1800) -a | --args= arguments that should be passed to ps (default=aux) -p | --php= php file that should be included -h | --help this help message EXAMPLE: $ procwatch -x /etc/procwatch.xml -d -s 3600 This command will run procwatch in daemon mode with an interval of an hour using the configuration file '/etc/procwatch.xml' |
The procwatch-lint is meant to validate procwatchs configurtation files written in XML by utilizing XML::DTD::XmlValidator.
Once again synopsis is best described by the output of procwatch-lint -h:
USAGE: $ procwatch-lint -c <file> [-d <dtd>] [-v] OPTIONS: -c | --conf= path to XML configuration file -d | --dtd= path to DTD -v | --verbose verbose output on errors -h | --help this help message EXAMPLE: procwatch-lint -c /etc/procwatch.xml This command will validate the configuration file '/etc/procwatch.xml' using the DTD at '/usr/share/pear/data/System_ProcWatch/procwatch-1.0.dtd' |
There are three methods to configure your System::ProcWatch application:
XML string/file
INI file
PHP array
Configuring System::ProcWatch by XML is the preferred way. It is as simple as powerful.
The root element of an XML configuration file/string is the procwatch element. It has one implicit attribute, the version attribute, set to "1.0".
The procwatch element symbolizes our ruleset, and the childs of the root are our rules.
The direct descendants of the root element procwatch, are the watch elements, which can occur 1 time or more often.
The watch element has one required attribute, the name attribute, which gives the watch (or job, rule) a descriptive name like "httpd-count".
Each watch element symbolizes a single rule, containing a regular expression to search for, one or more conditions to evaluate and one or more actions to be taken.
The pattern element describes the perl compatible regular expression which should be evaluated against a column of the output of ps.
There is one required attribute, the match attribute, defining the column name of the output of ps in lowercase like "command" or "vsz".
This makes System::ProcWatch highliy versatile and should make it usable with any platforms procps program.
The pattern elements content solely consists of the perl compatible regular expression to match against the column defined in the match attribute. The PCRE MUST contain the start and end delimiter and MAY contain any PCRE modifiers.
Example: <pattern match="command">/sbin\/httpd/</pattern>
The condition element defines conditions that MUST evaluate to TRUE at all so that later defined actions will be executed.
The condition element has one required and one optional attribute, the required one being type, which MUST be one of "presence" or "attr", and the optional one being attr. However, if the type attribute equals to "attr" the attr attribute MUST be present.
The attr attribute represents a column of procps' output like "user" or "%mem".
Dependent on the content of the type attribute, syntax and behavior of the condition element differ.
A condition with type "presence" MAY be empty, thus always evaluating to true.
Child Elements of condition may be:
min
Found value MUST exceed defined value.
max
Found value MUST NOT exceed defined value.
is
Found value MUST be equal to defined value.
isnot
Found value MUST NOT be equal to defined value.
sum
The sum of found values MUST NOT exceed defined sum.
You may combine them to define for instance a range from min to max.
The execute element defines actions that should be taken if the condition applies.
It has one required attribute, the type attribute, which MUST equal to one of "shell" or "php".
Obviously the content of the execute element is executed either on the shell through shell_exec() or directly in PHP through eval().
The execute element MAY occur any times.
There are some special variables that will automagically be available in execute statements:
$msg
This contains a general message, what has happened. It is quoted in single quotes for save usage and is available in shell and php executes.
$pids
This contains all PIDs of the processes that have been found. They are enclosed by single quotes and parenthesis.
Example: '(433, 444, 455, 466)'
$procs
This is a serialized php array in string format containing all information gained from ps and looks like: array(array('pid' => 344, 'command' => '/usr/sbin/httpd' ...))
It is only available in php executes and can easily be used in function callbacks:
<execute type="php">get_procs($procs);</execute>
Пример 58-1. XML configuration file
|
Configuring by INI file is effectively the same except that only executes of type "shell" can be defined.
Пример 58-2. INI configuration file
|
Пример 58-3. PHP configuration array
|
This constants are mostly used internally by System_ProcWatch
Таблица 58-1. Constants defined in ProcWatch.php
Name |
---|
SYSTEM_PROCWATCH_IS |
SYSTEM_PROCWATCH_ISNOT |
SYSTEM_PROCWATCH_MAX |
SYSTEM_PROCWATCH_MIN |
SYSTEM_PROCWATCH_PRESENCE |
SYSTEM_PROCWATCH_PRESENCE_MAX |
SYSTEM_PROCWATCH_PRESENCE_MIN |
SYSTEM_PROCWATCH_SUM |
Monitor processes
Usage:
1 require_once 'System/ProcWatch.php'; 2 require_once 'System/ProcWatch/Config.php'; 3 4 $cf = System_ProcWatch_Config::fromXmlFile('/etc/procwatch.xml'); 5 $pw = &new System_ProcWatch($cf); 6 $pw->run(); |
Build a configuration array for System_ProcWatch
Usage:
1 $cf = System_ProcWatch_Config::fromXmlFile('/etc/procwatch.xml'); 2 $pw = &new System_ProcWatch($cf); |
Throws PEAR_Error if XML file does not exist or problems parsing the XML string have occured.
This method in fact does a sanity check on the supplied config array and should only be used for testing purposes.
Fetches output from `ps` and parses it into an associative array
Usage:
1 $ps = &new System_ProcWatch_Parser(); 2 $pd = &$ps->getParsedData(); |
Instantiates a new System_ProcWatch parser object with the supplied arguments to pass to ps.
This is the main method of this class. It fetches to output of ps, executed on the shell, and returns the parsed data as an 2 dimensional indexed and associatve array.
Provides functions to enumerate root directories ("Drives") on Windows systems by using win32 api calls.
System_WinDrives uses win32 api calls to get a list of all installed roots ("Drives") on the current Windows operating system (The folders "A:\" until "Z:\").
Additional to the list of drives, detail information like the name and the drive type (network, harddisk, removable etc) is given.
The win32 api functions are used to access the Windows application programming interface. This means that the extension php_w32api.dll on PHP4 and php_ffi.dll on PHP5 have to be installed to use all functions. If no dll is available, the drives are guessed, but drive types and drive names can't be determined.
Пример 58-1. General usage
At first, you need to instantitiate a new System_WinDrives object. You can pass "true" as parameter to enable hard disk names, but that can crash PHP and is disabled by default. The next thing to do is checking if the class can be used. That depends on the available extensions (win32api on PHP4, and php_ffi on PHP5). If the isApiAvailable method returns true, everything is ok. Now that everything is ok, you can read the driver information via getDrivesInformation and display the output. In case the API is not available, the method tries to guess the drive list by checking if the root directories exist. |
Таблица 58-1. Constants defined in System/WinDrives.php
Name | Value | Description |
---|---|---|
SYSTEM_WINDRIVE_ERROR | 1 | Drive type couldn't be determined |
SYSTEM_WINDRIVE_REMOVABLE | 2 | Removable (Floppy, ZIP) |
SYSTEM_WINDRIVE_FIXED | 3 | Harddisk |
SYSTEM_WINDRIVE_REMOTE | 4 | Network drive |
SYSTEM_WINDRIVE_CDROM | 5 | CD/DVD drive |
SYSTEM_WINDRIVE_RAMDISK | 6 | Virtual disk in the RAM |
If the titles/names of drives shall be read. It is disabled by default, because it might cause PHP to crash.
Returns an array with all drive paths (e.g. A:\, C:\).
If no API is available, the drive list is guessed. To get more data (like drive type and name), you should use getDrivesInformation().
Пример 58-1. Using myFunction()
Output:
|
Returns the user-given name for the given drive. The function does not work on PHP5 and returns an empty string ''.
Пример 58-1. Using myFunction()
Output:
|
array - Array of little objects. Key is the drive path, the value is an object with the following values: type, name and typetitle.
Пример 58-1. Using myFunction()
Output:
|
Returns the type of a drive.
Таблица 58-1. Return values
Value | Constant | Meaning |
---|---|---|
1 | SYSTEM_WINDRIVE_ERROR | Non-existent drive or other error |
2 | SYSTEM_WINDRIVE_REMOVABLE | Removable drive (e.g. floppy) |
3 | SYSTEM_WINDRIVE_FIXED | Harddisk |
4 | SYSTEM_WINDRIVE_REMOTE | Network share |
5 | SYSTEM_WINDRIVE_CDROM | CD-Rom or DVD |
6 | SYSTEM_WINDRIVE_RAMDISK | RAM disk |
Gets the readable name to a drive type, e.g. "Harddisk" for the type 3 (SYSTEM_WINDRIVE_FIXED).
Checks if the API methods to read the drive list are available, and returns that.
They may not be available if the necessary extensions (win32api on PHP4, php_ffi on PHP5) are not installed on the system.
If the API is not available, the drive list is brute-force guessed. Drive types are not available in that case.
Пакеты для анализа и манипуляций с текстом.
Создание паролей при помощи PHP.
Работа с паролями - очень частое задание при написании веб-приложений. Этот пакет предоставляет легкоиспользуемый и интуитивный API для создания:
Один из плюсов данного пакета - способность создать пароли, которые являются удобопроизносимыми.
Пример 59-1. Создание легкопроизносимого пароля:
|
В дополнение в легкопроизносимым паролям Text_Password также может создавать пароли которые произносятся с трудом.
Пример 59-2. Создание труднопроизносимых паролей:
|
Text_Password предлагает возможность создавать пароли, основанные на заданных строках. В большинстве случаев эта строка является существующим именем пользователя для аутентификации в системе.
Пример 59-3. Создание пароля, основанного на заданной строке:
|
На данный момент поддерживаются следующие алгоритмы запутывания:
xor
rotx
rotx++
rotx--
ascii_rotx
ascii_rotx++
ascii_rotx--
shuffle
reverse
VersionControl_SVN is a simple Object-Oriented interface for the svn command-line application that makes up the core of Subversion, a free/open-source version control system.
Subversion can be used to manage trees of source code, text files, image files -- just about any collection of files.
VersionControl_SVN's features include:
Full support of svn subcommands.
Flexible error reporting provided by PEAR_ErrorStack.
Multi-object factory design.
Fully documented source code
For example, what content management system (CMS) couldn't benefit from version control functionality? For many non-programmers, version control is a confusing subject to get a firm grasp on. With VersionControl_SVN, developers are now able to customize the interface to Subversion with the ease-of-use goals of their particular audience in mind. VersionControl_SVN lets you leverage the strengths of version control without burdening end-users with the learning curve of change control fundamentals.
So you've got Subversion repository set up somewhere, and you want to take a look at what's inside with a PHP script. With the VersionControl_SVN::VersionControl_SVN_List() command, you're just a few steps away.
Пример 60-1. Reading the content of a Subversion repository
|
If your example repository above happened to have the VersionControl_SVN source in it, your output would be something like this:
Array ( [0] => Array ( [name] => docs [type] => D ) [1] => Array ( [name] => package.xml [type] => F ) [2] => Array ( [name] => SVN.php [type] => F ) [3] => Array ( [name] => SVN [type] => D ) [4] => Array ( [name] => tests [type] => D ) ) |
Note that in the above output, directories are flagged as type D, and files are flagged as type F.
Замечание: For additional information in the output, try setting verbose to TRUE in your $options array.
Have a script that needs to utilize several VersionControl_SVN subclasses? At the expense of a little overhead, you can be sure your $svn objects are fully-loaded by using the VersionControl_SVN::factory() command keyword __ALL__.
For example, in a basic script to get the list of current files in a repository, you just need the VersionControl_SVN::VersionControl_SVN_List() subclass.
Пример 60-2. Getting the list of current files in a repository
|
However, if you need to get a recursive list of files in a repository, look up the recent log activity for those files, and view the annotated source for those files, you've got two options.
Пример 60-3. Recursively getting the list of current files in a repository
|
If you are interested in learning more about Subversion, see the following:
Version Control with Subversion - The primary reference manual for all things related to Subversion, from general use to repository administration.
Subversion Website - The official Subversion website offers a FAQ, mailing list, and of course, the Subversion source code. Also included are links to GUI Subversion applications.
Validate offers a set of packages to validate common or specific data. The main package validates the common data. Specific data are localised or thematic.
Localized validation class
Argentina: Validate_AR
Austria: Validate_AT
Australia : Validate_AU
Belgium: Validate_BE
Brasil: Validate_PTBR
Canada: Validate_CA
Denmark: Validate_DK
France: Validate_FR
Germany: Validate_DE
Iceland: Validate_IS
Netherlands: Validate_NL
New Zealand: Validate_NZ
Polands: Validate_PL
Republic of India: Validate_IN
South Africa: Validate_ZA
Spain: Validate_ES
Switzerland: Validate_CH
United Kingdom: Validate_UK
United States: Validate_US
Thematic validation class
Financial: Validate_Finance
Credit Cards: Validate_Finance_CreditCard
International Standard Product Numbers : Validate_ISPN
The main package provides methods to validate various data. It includes :
numbers (min/max, decimal or not)
email (syntax, domain check)
string (predifined type alpha upper and/or lowercase, numeric,...)
date (min, max)
uri (RFC2396)
possibility valid multiple data with a single method call (::multiple)
See also :
Таблица 61-1. control per country
Country |
Package |
PostCode |
SIN |
Car registration |
SSN |
Phone |
Region |
bankCode |
Others |
---|---|---|---|---|---|---|---|---|---|
Argentina |
AR |
Yes |
Yes | ||||||
Austria |
AT |
Yes |
Yes | ||||||
Australia |
AU |
Yes |
Yes |
| |||||
Belgium |
BE |
Yes |
Yes |
Yes |
Yes |
| |||
Brasil |
PTBR |
Yes |
Yes |
Yes |
Yes |
Yes |
| ||
Canada |
CA |
Yes |
Yes |
n |
y |
y |
n | ||
Denmark |
DK |
Yes |
Yes |
Yes |
Yes | ||||
France |
FR |
Yes |
Yes |
Departements |
RIB |
| |||
Germany |
DE |
Yes |
Yes | ||||||
Iceland |
IS |
Yes |
Yes |
Yes |
address | ||||
Mexico |
esMX |
Yes |
Yes (DNI) |
Yes |
Yes | ||||
Netherlands |
NL |
Yes |
Yes |
Yes |
Account Number | ||||
New Zealand |
NZ |
Yes |
Yes |
Region number |
Account Number |
IRD Number | |||
Polands |
PL |
Account number |
| ||||||
Republic of India |
IN |
Yes |
Yes |
Yes |
State and union territory |
Pan and TAN | |||
South Africa |
ZA |
Yes |
Yes |
Yes | |||||
Spain |
ES |
Yes (DNI) | |||||||
Switzerland |
CH |
Yes |
Yes |
| |||||
United Kingdom |
UK |
Yes |
Yes |
Yes |
Yes |
Account Number |
| ||
United States |
US |
Yes |
Yes |
Yes |
Yes |
Предостережение |
This package is in alpha state |
Postal code CPA (CСdigo Postal Argentino)
Regions - provinces of Argentina
See also :
Предостережение |
This package is in alpha state |
SSN
Postal Code
See also :
Предостережение |
This package is in alpha state |
Tax File Number
Postal Code
Phone Number
Australian Business Number
Australian Company Number
Regions (States)
See also :
Most Australian's will have a TFN (Tax File Number) however not all, it is the closet equivalent we have to a Social Security Number. Note that this validation routine can be accessed through both Validate_AU::tfn() and Valdiate::ssn() methods.
<?php // Include the package require_once('Validate/AU.php'); $badTFN = '23 456 782'; $result = Validate_AU::tfn($badTFN); echo 'Test ' . $badTFN .' : <br />'; var_export($result); echo '<br /><br />'; $goodTFN = '123 456 782'; $result = Validate_AU::tfn($goodTFN); echo 'Test ' . $goodNationalId .' : <br />'; var_export($result); ?> |
Output :
Test 23 456 782 : false Test 123 456 782 : true |
Australian post code are 4 digit formed.
First parameter is the post code to validate.
An optional parameter for activate strong checks using a list of postcodes.
<?php // Include the package require_once('Validate/AU.php'); $badPostCode = 'ABCD'; $result = Validate_AU::postalCode($badPostCode); echo 'Test ' . $badPostCode .' : <br />'; var_export($result); echo '<br /><br />'; $goodPostCode = '3000'; $result = Validate_AU::postalCode($goodPostCode); echo 'Test ' . $goodPostCode .' : <br />'; var_export($result); ?> |
Output :
Test ABCD : false Test 3000 : true |
1234 appears to be a valid 4 digit postcode, however it does not appear in the official list.
<?php // Include the package require_once('Validate/AU.php'); $badPostCode = '1234'; $goodPostCode = '7930'; $result = Validate_AU::postalCode($badPostCode); echo 'Test ' . $badPostCode .' : <br />'; var_export($result); $result = Validate_AU::postalCode($badPostCode, false); echo '<br /><br />Test ' . $badPostCode .' : <br />'; var_export($result); $result = Validate_AU::postalCode($badPostCode, true); echo '<br /><br />Test ' . $badPostCode .' : <br />'; var_export($result); $result = Validate_AU::postalCode($goodPostCode, true); echo '<br /><br />Test ' . $goodPostCode .' : <br />'; var_export($result); ?> |
Output :
Test 1234 : true Test 1234 : true Test 1234 : false Test 7930 : true |
Validate an Australian Business Number.
<?php // Include the package require_once('Validate/AU.php'); $badABN = '00 043 145 470'; $result = Validate_AU::abn($badABN); echo 'Test ' . $badRegion .' : <br />'; var_export($result); echo '<br /><br />'; $goodABN = '28 043 145 470'; $result = Validate_AU::abn($goodABN); echo 'Test ' . $goodRegion .' : <br />'; var_export($result); ?> |
Output :
Test 00 043 145 470 : false Test 28 043 145 470 : true |
Validates a 2/3 region (state) code.
<?php // Include the package require_once('Validate/AU.php'); $badRegion = 'asdf'; $result = Validate_AU::region($badVAT); echo 'Test ' . $badRegion .' : <br />'; var_export($result); echo '<br /><br />'; $goodRegion = 'VIC'; $result = Validate_AU::region($goodRegion); echo 'Test ' . $goodRegion .' : <br />'; var_export($result); ?> |
Output :
Test asdf : false Test VIC : true |
Validate an Australian phone number passed as first param. Second parameter can be used to specify flags that signify the type of number to be validated.
Flags can be any combination of the bitwise constants VALIDATE_AU_PHONENUMBER_* as follows:
Таблица 61-1. Validate_AU Phone Number Flags
Flag | Description |
---|---|
"VALIDATE_AU_PHONENUMBER_STRICT" | If supplied then no spaces, parenthesis or dashes (-) will be removed. |
"VALIDATE_AU_PHONENUMBER_NATIONAL" | If supplied, then valid national numbers, both landline and mobile will pass validation. |
"VALIDATE_AU_PHONENUMBER_INDIAL" | If supplied, then valid indial (13/1300/1800/1900) numbers will pass validation. |
"VALIDATE_AU_PHONENUMBER_INTERNATIONAL" | If supplied, then valid international syntax will pass validation. EG. +61.3 9999 9999 |
<?php // Include the package require_once('Validate/AU.php'); $nationalPhone = '03 9999 9999'; $nationalStrictPhone = '0399999999'; $indialPhone = '1300 131 121'; $internationalSyntax = '+61.3 8779 7212'; echo 'Test ' . $goodPhone .' : <br />'; $result = Validate_AU::phoneNumber($nationalPhone); // the flag VALIDATE_AU_PHONENUMBER_NATIONAL is default var_export($result) . '-'; $result = Validate_AU::phoneNumber($nationalPhone, VALIDATE_AU_PHONENUMBER_NATIONAL | VALIDATE_AU_PHONENUMBER_STRICT); var_export($result) . '-'; $result = Validate_AU::phoneNumber($nationalPhone, VALIDATE_AU_PHONENUMBER_INDIAL); var_export($result) . '-'; $result = Validate_AU::phoneNumber($nationalPhone, VALIDATE_AU_PHONENUMBER_INTERNATIONAL); var_export($result) . '-'; $result = Validate_AU::phoneNumber($nationalPhone, VALIDATE_AU_PHONENUMBER_NATIONAL | VALIDATE_AU_PHONENUMBER_INDIAL | VALIDATE_AU_PHONENUMBER_INTERNATIONAL); var_export($result); echo '<br /><br />'; echo 'Test ' . $nationalStrictPhone .' : <br />'; $result = Validate_AU::phoneNumber($nationalStrictPhone); var_export($result) . '-'; $result = Validate_AU::phoneNumber($nationalStrictPhone, VALIDATE_AU_PHONENUMBER_NATIONAL | VALIDATE_AU_PHONENUMBER_STRICT); var_export($result) . '-'; $result = Validate_AU::phoneNumber($nationalStrictPhone, VALIDATE_AU_PHONENUMBER_INDIAL); var_export($result) . '-'; $result = Validate_AU::phoneNumber($nationalStrictPhone, VALIDATE_AU_PHONENUMBER_INTERNATIONAL); var_export($result) . '-'; $result = Validate_AU::phoneNumber($nationalStrictPhone, VALIDATE_AU_PHONENUMBER_NATIONAL | VALIDATE_AU_PHONENUMBER_INDIAL | VALIDATE_AU_PHONENUMBER_INTERNATIONAL); var_export($result) . '-'; echo '<br /><br />'; echo 'Test ' . $indialPhone .' : <br />'; $result = Validate_AU::phoneNumber($indialPhone); var_export($result) . '-'; $result = Validate_AU::phoneNumber($indialPhone, VALIDATE_AU_PHONENUMBER_INDIAL | VALIDATE_AU_PHONENUMBER_STRICT); var_export($result) . '-'; $result = Validate_AU::phoneNumber($indialPhone, VALIDATE_AU_PHONENUMBER_INDIAL); var_export($result) . '-'; $result = Validate_AU::phoneNumber($indialPhone, VALIDATE_AU_PHONENUMBER_INTERNATIONAL); var_export($result) . '-'; $result = Validate_AU::phoneNumber($indialPhone, VALIDATE_AU_PHONENUMBER_NATIONAL | VALIDATE_AU_PHONENUMBER_INDIAL | VALIDATE_AU_PHONENUMBER_INTERNATIONAL); var_export($result) . '-'; echo '<br /><br />'; echo 'Test ' . $internationalSyntax .' : <br />'; $result = Validate_AU::phoneNumber($internationalSyntax); var_export($result) . '-'; $result = Validate_AU::phoneNumber($internationalSyntax, VALIDATE_AU_PHONENUMBER_INTERNATIONAL | VALIDATE_AU_PHONENUMBER_STRICT); var_export($result) . '-'; $result = Validate_AU::phoneNumber($internationalSyntax, VALIDATE_AU_PHONENUMBER_INDIAL); var_export($result) . '-'; $result = Validate_AU::phoneNumber($internationalSyntax, VALIDATE_AU_PHONENUMBER_INTERNATIONAL); var_export($result) . '-'; $result = Validate_AU::phoneNumber($internationalSyntax, VALIDATE_AU_PHONENUMBER_NATIONAL | VALIDATE_AU_PHONENUMBER_INDIAL | VALIDATE_AU_PHONENUMBER_INTERNATIONAL); var_export($result) . '-'; ?> |
Output :
Test 03 9999 9999 : true - false - false - false - true Test 0399999999 : true - true - false - false - true Test 1300 131 121 : false - false - true - false - true Test +61.3 8779 7212 : false - false - true - true - true |
Таблица 61-1. Constants defined in Validate_AU.php
Name | Value | Line Number |
---|---|---|
VALIDATE_AU_PHONENUMBER_INDIAL | 4 | 37 |
VALIDATE_AU_PHONENUMBER_INTERNATIONAL | 8 | 38 |
VALIDATE_AU_PHONENUMBER_NATIONAL | 2 | 36 |
VALIDATE_AU_PHONENUMBER_STRICT | 1 | 35 |
The ACN is a nine digit number with the last digit being a check digit calculated using a modified modulus 10 calculation.
author Byron Adams <byron.adams54@gmail.com>
author Daniel O'Connor <daniel.oconnor@gmail.com>
see http://www.asic.gov.au/asic/asic_infoco.nsf/byheadline/Australian+Company+Number+(ACN)+Check+Digit
Note that this function supports the following notations:
Landline: 03 9999 9999
Mobile: 0400 000 000 (as above, but usually notated differently)
Indial: 131 812 / 1300 000 000 / 1800 000 000 / 1900 000 000
International: +61.3 9999 9999
Note: If the VALIDATE_AU_PHONENUMBER_STRICT flag is not supplied, then all spaces, dashes and parenthesis are removed before validation. You will have to strip these yourself if your data storage does not allow these characters.
The telephone number
Can be a combination of the following flags:
VALIDATE_AU_PHONENUMBER_STRICT: if supplied then no spaces, parenthesis or dashes (-) will be removed.
VALIDATE_AU_PHONENUMBER_NATIONAL: when supplied valid national numbers (eg. 03 9999 9999) will return TRUE.
VALIDATE_AU_PHONENUMBER_INDIAL: when supplied valid indial numbers (eg. 13/1300/1800/1900) will return TRUE.
VALIDATE_AU_PHONENUMBER_INTERNATIONAL: when supplied valid international notation of Australian numbers (eg. +61.3 9999 9999) will return TRUE.
postcode to validate
strong checks against a list of postcodes
Australia does not have a social security number system, the closest equivalent is a Tax File Number
Предостережение |
This package is in beta state |
This package offers methods to validate specific values from Belgium
See also :
The belgian nationalId on the identity card of all belgian.
A check digit is the last one, computed the standard _get_control_number function.
<?php // Include the package require_once('Validate/BE.php'); $badNationalId = '730111-361-99'; $result = Validate_BE::nationalId($badNationalId); echo 'Test ' . $badNationalId .' : <br />'; var_export($result); echo '<br /><br />'; $goodNationalId = '730111 361 73'; $result = Validate_BE::nationalId($goodNationalId); echo 'Test ' . $goodNationalId .' : <br />'; var_export($result); ?> |
Output :
Test 730111-361-99 : false Test 730111 361 73 : true |
The belgian social security number is on the SIS card of all belgian.
A check digit is the last one, computed the standard _get_control_number function.
<?php // Include the package require_once('Validate/BE.php'); $badSsn = '72011136173'; $result = Validate_BE::ssn($badSsn); echo 'Test ' . $badSsn .' : <br />'; var_export($result); echo '<br /><br />'; $goodSsn = '73011136173'; $result = Validate_BE::ssn($goodSsn); echo 'Test ' . $goodSsn .' : <br />'; var_export($result); ?> |
Output :
Test 72011136173 : false Test 73011136173 : true |
Belgian post code are 4 digit formed.
First parameter is the post code to validate.
An optional parameter for activate strong checks using a list of postcodes.
<?php // Include the package require_once('Validate/BE.php'); $badPostCode = 'ABCD'; $result = Validate_BE::postalCode($badPostCode); echo 'Test ' . $badPostCode .' : <br />'; var_export($result); echo '<br /><br />'; $goodPostCode = '7930'; $result = Validate_BE::postalCode($goodPostCode); echo 'Test ' . $goodPostCode .' : <br />'; var_export($result); ?> |
Output :
Test ABCD : false Test 7930 : true |
1234 like a good post code, but dont exit in the official list.
<?php // Include the package require_once('Validate/BE.php'); $badPostCode = '1234'; $goodPostCode = '7930'; $result = Validate_BE::postalCode($badPostCode); echo 'Test ' . $badPostCode .' : <br />'; var_export($result); $result = Validate_BE::postalCode($badPostCode,false); echo '<br /><br />Test ' . $badPostCode .' : <br />'; var_export($result); $result = Validate_BE::postalCode($badPostCode,true); echo '<br /><br />Test ' . $badPostCode .' : <br />'; var_export($result); $result = Validate_BE::postalCode($goodPostCode); echo '<br /><br />Test ' . $goodPostCode .' : <br />'; var_export($result); ?> |
Output :
Test 1234 : true Test 1234 : true Test 1234 : false Test 7930 : true |
Belgian bankcodes consist of
3 figure number for the bank society
7-figure number for the account number
2-figure number for mod 97
<?php // Include the package require_once('Validate/BE.php'); $badBankCode = '310164533227'; $result = Validate_BE::bankCode($badBankCode); echo 'Test ' . $badBankCode .' : <br />'; var_export($result); echo '<br /><br />'; $goodBankCode = '310164533207'; $result = Validate_BE::bankCode($goodBankCode); echo 'Test ' . $goodBankCode .' : <br />'; var_export($result); ?> |
Output :
Test 310164533227 : false Test 310164533207 : true |
Belgian transfert (virement) can be done with a structured message 12 figures
10-figure number for the message
2-figure number for mod 97
<?php // Include the package require_once('Validate/BE.php'); $badBankTransferMessage = '053/3140/16211'; $result = Validate_BE::bankTransferMessage($badBankTransferMessage); echo 'Test ' . $badBankTransferMessage .' : <br />'; var_export($result); echo '<br /><br />'; $goodBankTransferMessage = '054/3140/16211'; $result = Validate_BE::bankTransferMessage($goodBankTransferMessage); echo 'Test ' . $goodBankTransferMessage .' : <br />'; var_export($result); ?> |
Output :
Test 053/3140/16211 : false Test 054/3140/16211 : true |
Belgian VAT consist of 3-figure number.
Actually no doc was found about a checksum.
<?php // Include the package require_once('Validate/BE.php'); $badVAT = '102.239.951'; $result = Validate_BE::vat($badVAT); echo 'Test ' . $badVAT .' : <br />'; var_export($result); echo '<br /><br />'; $goodVAT = '202-239-951'; $result = Validate_BE::vat($goodVAT); echo 'Test ' . $goodVAT .' : <br />'; var_export($result); ?> |
Output :
Test 102.239.951 : false Test 202-239-951 : true |
Validate a belgian phone number passed as first param second specify if it's would be a mobile or a traditional line or both. "/" (slash), "-" (dash), "." (dot), and white spaces are ignored. "+" are use a exit code : 0 in Belgium.
NOTE : this validate want a BELGIAN phonenumber to return true, not a valid number to call FROM belgium
<?php // Include the package require_once('Validate/BE.php'); $badPhone = '00 32 12 123 45 67'; $result = Validate_BE::phoneNumber($badPhone); echo 'Test ' . $badPhone .' : <br />'; var_export($result); echo '<br /><br />'; $goodPhone = '00 32 45 12 34 56'; $result = Validate_BE::phoneNumber($goodPhone); echo 'Test ' . $goodPhone .' : <br />'; var_export($result); ?> |
Output :
Test '00 32 12 123 45 67' : false Test '00 32 45 12 34 56' : true |
See now with the parameter
<?php // Include the package require_once('Validate/BE.php'); $goodPhone = '00 32 45 12 34 56'; $mobilePhone = '00 32 485 34 56'; echo 'Test ' . $goodPhone .' : <br />'; $result = Validate_BE::phoneNumber($goodPhone); var_export($result) . '-'; $result = Validate_BE::phoneNumber($goodPhone,VALIDATE_BE_PHONENUMBER_TYPE_ANY); var_export($result) . '-'; $result = Validate_BE::phoneNumber($goodPhone,VALIDATE_BE_PHONENUMBER_TYPE_NORMAL); var_export($result) . '-'; $result = Validate_BE::phoneNumber($goodPhone,VALIDATE_BE_PHONENUMBER_TYPE_MOBILE); var_export($result) . '-'; echo '<br /><br />'; $result = Validate_BE::phoneNumber($mobilePhone); var_export($result) . '-'; $result = Validate_BE::phoneNumber($mobilePhone,VALIDATE_BE_PHONENUMBER_TYPE_ANY); var_export($result) . '-'; $result = Validate_BE::phoneNumber($mobilePhone,VALIDATE_BE_PHONENUMBER_TYPE_NORMAL); var_export($result) . '-'; $result = Validate_BE::phoneNumber($mobilePhone,VALIDATE_BE_PHONENUMBER_TYPE_MOBILE); var_export($result); ?> |
Output :
Test 00 32 45 12 34 56 : true - true - true - false Test 00 32 485 34 56 : false - false - false - false |
Предостережение |
This package is in alpha state |
Social Inurance Numbers (SIN)
Regions (Provinces)
Postal Codes
Phone Numbers
See also :
The canadian social security number is on the SIS card of all canadian.
A check digit is the last one, computed the standard _get_control_number function.
<?php // Include the package require_once('Validate/CA.php'); $badSsn = '012345674'; $result = Validate_CA::ssn($badSsn); echo 'Test ' . $badSsn .' : <br />'; var_export($result); echo '<br /><br />'; $goodSsn = '123456782'; $result = Validate_CA::ssn($goodSsn); echo 'Test ' . $goodSsn .' : <br />'; var_export($result); ?> |
Output :
Test 012345674 : false Test 123456782 : true |
The postal code is a six-character, uniformly structured alphanumeric code in the form of ANA NAN where "A" represents an alphabetic character and "N" represents a numeric character.
The postal code is made up of two segments:
The first, the Forward Sortation Area (FSA), is a combination of three characters (alpha - numeric - alpha).
It identifies a major geographic area in an urban or a rural location.
The third character of the FSA segment (M4B), in conjunction with the first two characters, describes an exact area of a city or town or other geographic area.
The second segment, Local Delivery Unit (LDU), is a combination of three characters (numeric - alpha - numeric).
It identifies the smallest delivery unit within a forward sortation area.
The LDU, identified by the last three characters of the postal code, allows for a final sort within an FSA.
In Urban Areas, the last three digits may indicate a specific city block (one side of a street between two intersecting streets), a single building or, in some cases, a large volume mail receiver.
In Rural Areas, the last three digits (LDU), together with the FSA, identify a specific Rural community.
First parameter of the method is the post code to validate.
An optional parameter for limite the request to a province.
<?php // Include the package require_once('Validate/CA.php'); $badPostCode = '48103'; $result = Validate_CA::postalCode($badPostCode); echo 'Test ' . $badPostCode .' : <br />'; var_export($result); echo '<br /><br />'; $goodPostCode = 'H2M 2J1'; $result = Validate_CA::postalCode($goodPostCode); echo 'Test ' . $goodPostCode .' : <br />'; var_export($result); ?> |
Output :
Test 48103 : false Test H2M 2J1 : true |
H2M 2J1 like a good post code, but province don't exit.
<?php // Include the package require_once('Validate/CA.php'); $postalCode = 'H2M 2J1'; // in Montreal area $result = Validate_CA::postalCode($postalCode); echo 'Test ' . $postalCode .' : <br />'; var_export($result); echo '<br /><br />'; $result = Validate_CA::postalCode($postalCode,'QC'); // QC for Montreal echo 'Test ' . $postalCode .' in QC: <br />'; var_export($result); echo '<br /><br />'; $result = Validate_CA::postalCode($postalCode,'AB'); // AB for Toronto echo 'Test ' . $postalCode .' in AB: <br />'; var_export($result); ?> |
Output :
Test H2M 2J1 : true Test H2M 2J1 in QC: true Test H2M 2J1 in AB: false |
Canada and the United States share the same numbering plan, hence you can also call Validate_US::phoneNumber()
Can allow only seven digit numbers.
Also allows the formats, (xxx) xxx-xxxx, xxx xxx-xxxx, and now x (xxx) xxx-xxxx or various combination without spaces or dashes.
<?php // Include the package require_once('Validate/CA.php'); $phoneNumber = '467875098x'; $result = Validate_CA::phoneNumber($phoneNumber); echo 'Test ' . $phoneNumber .' : <br />'; var_export($result); echo '<br />'; $phoneNumber = '4678750987'; $result = Validate_CA::phoneNumber($phoneNumber); echo 'Test ' . $phoneNumber .' : <br />'; var_export($result); ?> |
Output :
Test 467875098x : false Test 4678750987 : true |
See now with the parameter
<?php // Include the package require_once('Validate/CA.php'); $phoneNumber = '8750987'; $result = Validate_CA::phoneNumber($phoneNumber,false); echo 'Test ' . $phoneNumber .' : <br />'; var_export($result); echo '<br /><br />'; $phoneNumber = '8750987'; echo 'Test ' . $phoneNumber .' : <br />'; echo 'With $requireAreaCode false <br />'; $result = Validate_CA::phoneNumber($phoneNumber,false); var_export($result); echo '<br />'; echo 'With $requireAreaCode true<br />'; $result = Validate_CA::phoneNumber($phoneNumber,true); var_export($result); echo '<br /><br />'; $phoneNumber = '(467)8750987'; echo 'Test ' . $phoneNumber .' : <br />'; echo 'With $requireAreaCode false <br />'; $result = Validate_CA::phoneNumber($phoneNumber,false); var_export($result); echo '<br />'; echo 'With $requireAreaCode true<br />'; $result = Validate_CA::phoneNumber($phoneNumber,true); var_export($result); ?> |
Output :
Test 8750987 : true Test 8750987 : With $requireAreaCode false true With $requireAreaCode true false Test (467)8750987 : With $requireAreaCode false false With $requireAreaCode true true |
Предостережение |
This package is in alpha state |
Social insurance number (aka SSN)
Postal Codes
Swiss university's immatriculation number
See also :
Предостережение |
This package is in alpha state |
Postal Code
Bank Code
See also :
Предостережение |
This package is in alpha state |
Social Security Number (CPR Nummer)
Car Registration number
Postal Codes
Phone Numbers
See also :
Предостережение |
This package is in alpha state |
DNI (El Documento Nacional de Indentidad a chequear)
See also :
Предостережение |
This package never released |
DNI (El Documento Nacional de Indentidad a chequear)
Postal code
Region (states)
Phone numbers
See also :
Package contains locale validation for France such as:
SSN
Postal Code
RIB
SIREN
SIRET
Region (Departements)
See also :
Предостережение |
This package is in alpha state |
Permanent Account Number (PAN and TAN)
State and Union Territory codes
Telephone Numbers
Postal (Zip) Codes
Vehicle License Plate Numbers
See also :
Предостережение |
This package is in alpha state |
SSN (Social Security Number (Icelandic: kennitala))
Postal code (Icelandic: post numer)
Address (Icelandic: heimilisfang)
Telephone number (Icelandic: simanumer)
See also :
Предостережение |
This package is in alpha state |
Social insurance number (aka SIN)
Postal Code
Phone Number
Bank Account Number (based on 11proef)
See also :
Предостережение |
This package is in alpha state |
Postal Codes
IRD numbers
Regional codes
Telephone number
Bank AC
See also :
Предостережение |
This package is in alpha state |
NIP (Polish tax identification number)
Bank account numbers
PESEL (Polish human identification number)
REGON (Polish statistical national economy register)
See also :
Предостережение |
This package is in alpha state |
Social Inurance Numbers (SIN)
Region (brazilian states)
Postal Codes
Phone Numbers
CNPJ
CPF
Vehicle's plate
See also :
Предостережение |
This package is in alpha state |
SSN (National Insurance/IN)
Postal Code
Phone Number
Bank Account Number
Sort Code
Car registration numbers
Passports
Driver license
See also :
Предостережение |
This package is in beta state |
Social insurance number (aka SSN)
Region (state code)
Postal Codes
Phone Numbers
See also :
Предостережение |
This package is in alpha state. |
South African Identity Number
Regions (Provinces)
Postal Codes
See also :
Validation class for Credit Card
Package to validate Credit card.
Credit card number
Card security code
Card type (i.e. Visa, Mastercard...)
Theses methods only check the format of the data. For instance the package does NOT check if a card is a legitimate card registered with a card issuer, or if the card is reported stolen, etc...
See also :
Validation class for ISPN (International Standard Product Numbers)
Package contains ISPN (International Standard Product Numbers) validations such as:
ISSN (International Standard Book Number)
ISBN (International Standard Serial Number)
ISMN (International Standard Music Number)
EAN/UCC-8 number
EAN/UCC-13 number
EAN/UCC-14 number
UCC-12 (U.P.C.) ID number
SSCC (Serial Shipping Container Code)
See also :
Object-oriented abstraction for del.icio.us XML API.
Services_Delicious is an abstraction for the webservice of the social bookmarking site del.icio.us. del.icio.us allows you to easily add sites you like to your personal collection of links, to categorize those sites with keywords, and to share your collection not only between your own browsers and machines, but also with others.
del.icio.us is using "tags" to categorize your bookmarks and allows other users to browse bookmarks by topic.
Services_Delicious enables you to access, add and even delete your social bookmarks by using a Services_Delicious class that provides functions like getAllPosts(), addPost() or deletePost().
The following examples show how to use some basic features of Services_Delicious:
Пример 62-1. Fetching your recent posts
|
Пример 62-2. Getting all tags that you used in your bookmarks
|
Пример 62-3. Adding a new bookmark
|
Object-oriented abstraction for eBay's XML API.
Services_Ebay is an object-oriented abstraction layer for eBay's XML API. In addition to a SOAP-service, eBay provides an API, that does not follow any standards except wrapping all webservice calls and parameters in XML. This webservice still is more powerful than eBay's SOAP server and in addition has been heavily tested by real-life applications.
eBay's webservice enables you to use all of eBay's features (except bidding on items) in your own PHP applications. The features range from adding new items to managing the transaction, payment and shipping. Currently there are about 70 method calls available, all accept a range of parameters.
Services_Ebay (as of version 0.7.0) already provides wrappers for 50 methods as well as some model classes which help you working with the results from the calls.
To use this package you will need PHP5 with cURL support enabled and should be familiar with PHP5's exception handling.
The eBay webservice is of course not free to use by the public. To develop and test your applications, you will have to register as an eBay developer (which is free of charge). Furthermore, you will not be able to test and develop on the eBay site, before your application has been certified.
The eBay Developers Program Sandbox is a test environment that represents a "mini" eBay site. The Sandbox provides the most important features of the eBay site, allowing you to build and test your application in a non-production environment. The eBay Sandbox supports both API testing as well as site testing via the GUI interface.
While developing your application, you will always be using the eBay sandbox, which can be accessed via web at http://sandbox.ebay.com/. This site looks and behaves like any eBay website you are being used to.
To develop applications in the sandbox you will have to register at the eBay developers program. To do this, follow these steps:
Register as an eBay user:
In order to register as an eBay developer, you'll have to be an eBay user. As eBay users are valid on all international sites, it is sufficient if you have an eBay user id for your local eBay site, like ebay.com or ebay.de.
Register as an eBay developer:
Next, you will have to register as an eBay developer at the eBay developer program. This procedure can take some time, as they require you to enter a lot of information, so you should do this carefully. If you are developing an open source application using Services_Ebay, you should apply for an Individual license.
After the registration has been finisehd, you will recieve three keys that you will need to authenticate your eBay application: DevID, AppID and CertID. You will need these keys later so you should save them somewhere.
Create one or more test users:
As the sandbox does not share any data with the eBay sites, you will have to create new users that you can use to add items, make transactions and give feedback. You can create as many users as you need for testing purposes, just use the registration form in the sandbox.
You will need a valid email address for each of your users, as well as a valid US address and telephone number, you can easily get on by using YellowPages. A credit card is not required, your test users will receive money from eBay they can spend in the sandbox. Of course, this is no real money, which has not use outside of the sandbox.
Validate your test users:
If you want your test users to sell items on eBay, you will need to validate them. This can be done using the ValidateTestUserRegistration() API call, which is already supported by Services_Ebay.
eBay's Auth&Auth process is quite complex and can be the biggest hurdle for getting started with the webservice. To make an API call the following information is required:
DevID (received after registration, unique per developer)
AppID (received after registration, unique per application)
CertID (received after registration, unique per application)
Authentication Token, unique for each user of your application
While you already are in possession of the first three tokens, you still need the last one to make an API call. If your application is used by more than one user (which is the case for web applications), eBay does not want your application to receive the usernames and passwords of your users. If a user authenticates, your application is supposed to redirect him to the eBay login page and pass an additional parameter (a so called RuName). The user will then enter his login information as he is used to on the eBay website and then authorize your application to make API calls on his behalf.
After that, eBay will redirect the user back to your application and pass a unique token, which can be used to identify this user when your application is making API calls. This technique has several advantages:
Single sign-on system for eBay applications
When your application is hacked, no passwords are revealed
The user only sees the login screen he is used to.
As this authentication procedure is quite complex and requires various API calls to function there is an easier way, which can be used for testing. eBay provides the so called Single-User-Tool, an HTML-based tool, which creates tokens that you can use to authenticate a user. All you need to do is submit your DevID, AppID and CertID and select whether the token will be used in the sandbox or production environment.
Services_Ebay provides a lot of examples, which demonstrate how the API calls have to be used. After installing Services_Ebay, they will be located in the docs/ directory of your PEAR installation. In order to run the examples, you will have to supply the authentication credentials you received from eBay. The easiest way to do this, is to modify the config.php file, which is located in the examples folder.
Пример 62-1. The configuration file
|
Since mid-2005, the eBay API will only accept UTF-8 encoded XML-documents. As encoding all data to UTF-8 is tedious, Services_Ebay will take care of this for you. All you need to do is specify the encoding you want to use in your script when creating a session object.
Пример 62-1. Using ISO-8859-1 in your script
|
The umlaut characters contained in the description of the item will be automatically converted to UTF-8 when the XML-document is created. Furthermore the result document which is returned by the eBay API will be decoded again to ISO-8859-1 so you do not have to worry about UTF-8 at all.
Of course, it is also possible to supply UTF-8 encoded data to Services_Ebay. All you have to do is change the encoding type, when creating the session object.
Пример 62-2. Using UTF-8 in your script
|
In this example you are using utf8_encode() to encode the data prior to passing it to Services_Ebay. To avoid duplicated encoding, you need to set the encoding to UTF-8.
As Services_Ebay is a PHP 5 only package, it uses exception handling and the PEAR_Exception class as base class for all exceptions. Exceptions can be thrown, whenever you try to call any of the API calls provided by Services_Ebay, which means you should always nest those in a try/catch-block:
Пример 62-1. Exception handling
|
When calling a non-existent API call or passing the wrong parameters to the API, eBay will abort the API call and return an XML-document that contains error information. Services_Ebay will automatically convert this into an exception that can be easily handled by your PHP application.
In some cases, the eBay API will still process your request, even if you passed invalid parameters and include error information in the resulting XML-document alongside the actual response of your request.
In this case, the errors will be tagged as warnings, as they were not serious errors. Services_Ebay will not convert these errors to exceptions, but only to instances of Services_Ebay_Error. These objects will be stored in the Services_Ebay_Session and can be retrieved by your application at a later point.
Пример 62-2. Handling warnings
|
Services_Ebay consists of a lot of small classes, which keeps the used codebase small, as only the functionality that you use in your applications are loaded and parsed.
This will give you a short overview of the different types of objects that are provided and for which tasks they are used.
The Services_Ebay class is used for the following tasks:
Provides factory methods.
The Services_Ebay provides methods to load and instantiate all of the other classes, that are included in the Services_Ebay distribution. That means that this is the only class you should include and instantiate yourself. Factory methods include loadApiCall(), getSession() and loadModel().
Provides constants.
This class also defines some constants like the eBay site ids that you will need in your applications, constants include Services_Ebay::SITEID_ID, Services_Ebay::AUTH_TYPE_TOKEN or Services_Ebay::FEEDBACK_BRIEF. Whenever the eBay webservice expects an integer value in an XML tag, Services_Ebay tries to provide a matching constant.
Provides static helper methods.
The class also provides some helper methods, which can be called statically like getAvailableApiCalls().
Acts as a proxy class.
The most important usage is that Services_Ebay acts as a proxy class for the API calls, that means you can call methods on the class which will then be redirected to the appropriate call object.
The Services_Ebay_Session class is used to handle the serialization and unserialization of the incoming and outgoing XML streams. Furthermore it builds the HTTP headers that are needed and manages all user authentication.
You will probably always use the session indirectly by at first passing it to the Services_Ebay object which will then use the session for making API calls.
Пример 62-1. Using the session class
|
The Services_Ebay_Transport classes are used to build up network connections to the eBay webservices and send and recieve the raw data which has been created by Services_Ebay_Session.
Theoretically there may be different transport classes, but due to bugs in PHP's stream functions and some SSL libraries, the only working transport class is Services_Ebay_Transport_Curl, which uses PHP's curl extension.
The Services_Ebay_Call classes contain information about the API calls that the eBay webservice offers. Each API call is encapsulated in an object that contains information about the API call, which XML tags have to be used and what the call is expected to return.
There are two ways in which the call objects can be used:
Instantiate them directly (best via the factory method of Services_Ebay), pass all parameters and invoke Services_Ebay_Call::call() while passing the session object to this method.
Use Services_Ebay as a proxy object which is able to do all the work by using PHP5's new object overloading features.
It is recommended to use Services_Ebay as a proxy instead of working directly on the Call objects. Services_Ebay will instantiate the class, pass the parameters and invoke the call method on the Call object.
The Services_Ebay_Model classes act as local containers for the remote data stored on the eBay server. For example, when calling Services_Ebay::getItem(), the method will return an instance of Services_Ebay_Model_Item, which contains information about the item as well as some helper methods like Services_Ebay_Model_Item::addToDescription() which encapsulates a new API call.
Currently Services_Ebay provides models for accounts, disputes (single dispute and a list of disputes), user feedback (summary and a single feedback entry), items and list of items, MyeBay, orders, preferences, search results, shipments, eBay stores, transactions and users.
The Services_Ebay_Cache classes allow you to locally cache information that you retrieved from the eBay webservice without changing anything in your scripts. After registering a cache instance for any model type, Services_Ebay will query the cache before making a time-consuming API call.
The cache classes use a very high abstraction and allow you to create new cache containers, so you could store the data in a database, shared memory or wherever you like. Currently there is only one container available, which stores the data in the local filesystem.
To determine, whether a cache is still valid an instance of Services_Ebay_Cache_ExpiryCheck is used, which allows you to build "intelligent" caches that have a shorter expiry time the nearer the end of an auction is.
The following examples show how to use some basic features of Services_Ebay:
Пример 62-1. Using a proxy object
|
Пример 62-2. Working directly with a Call object
|
Пример 62-3. Using the model classes
|
A class for interacting with the Technorati API
Technorati is a blog search engine. By indexing blogs and exploring links between them, they provide tools for monitoring online conversations taking place on and between blogs. By far the richest source of this information is through their REST-based API, to which this module provides an OO PHP interface. Full documentation for Technorati's API is available on their developers' wiki. To use the API you will need an API key.
To protect against future changes to the underlying API it is accessed using a factory method:
$tapi =& Services_Technorati::factory($api_key); |
The Technorati API limits you to 500 queries per day so those wishing to use it in a high-demand environment will want to employ some caching. Services_Technorati provides support for any caching system with a Cache_Lite-like API. To use a cache, you will need to create it and then pass it to the class in the factory:
$tapi =& Services_Technorati::factory($api_key, $cache_object); |
Once you have instantiated the object you can start passing in queries. Each call takes the form of methodName(keyParameter, options) where options is an array.
Таблица 62-1. Query types and their options
Query Name | Key Parameter | Permitted Options |
---|---|---|
cosmos | url | type, limit, start, current, claim, highlight |
search | query keywords | start, limit, claim |
outbound | url | start |
tag | tag | limit, start, format, excerptsize, topexcerptsize |
topTags | - | limit, start |
blogPostTags | url | limit |
getInfo | username | - |
blogInfo | url | - |
The value returned from each query will be either an array representing the unserialized XML or a PEAR Error.
Пример 62-1. An example return from the blogInfo query (for 'jystewart') is:
|
Full details of the XML returned by Technorati is included on the developers' wiki
This package provides a programmable interface to the W3's HTML Validation service at http://validator.w3.org/.
With this package you can use PHP to obtain usable validation results for HTML. The package utilizes the SOAP 1.2 output format of validator to populate validation result objects with true | false as well as any errors and warning messages.
See the examples included with the package for usage.
This class acts as an interface to various online weather-services.
Services_Weather searches for given locations and retrieves current weather data and, dependant on the used service, also forecasts. Up to now, SOAP services from CapeScience and EJSE, XML from weather.com and METAR from noaa.gov are supported, further services will get included, if they become available and are properly documented.
Usable keys for the options array are:
debug enables debugging output
cacheType defines what type of cache to use
cacheOptions passes cache options
unitsFormat use (US)-standard, metric or custom units
customUnitsFormat defines the customized units format
httpTimeout sets timeout for HTTP requests
dateFormat string to use for date output
timeFormat string to use for time output
none
none
dsn String for defining the DB connection
dbOptions passes DB options
source http, ftp or file - type of data-source
sourcePath where to look for the source, URI or filepath
partnerID You'll receive these keys after registering
licenseKey with the weather.com XML-service
Parent class for weather-services. Defines common functions for unit conversions, checks for cache enabling and does other miscellaneous things.
Services_Weather_Common
Таблица 62-1. Classes that extend Services_Weather_Common
Class | Summary |
---|---|
Services_Weather_Ejse | PEAR::Services_Weather_Ejse |
Services_Weather_Globalweather | PEAR::Services_Weather_Globalweather |
Services_Weather_Metar | PEAR::Services_Weather_Metar |
Services_Weather_Weatherdotcom | PEAR::Services_Weather_Weatherdotcom |
This class acts as an interface to the soap service of EJSE. It retrieves current weather data and forecasts based on postal codes (ZIP).
Currently this service is only available for US territory.
For a working example, please take a look at docs/Services_Weather/examples/ejse-basic.php
Services_Weather_Ejse
Services_Weather_Ejse Inherited Methods
Таблица 62-1. Inherited from Services_Weather_Common
Method Name | Summary |
---|---|
Services_Weather_Common::calculateDewPoint() | Calculate dewpoint from temperature and humidity This is only an approximation, there is no exact formula, this one here is called Magnus-Formula |
Services_Weather_Common::calculateHumidity() | Calculate humidity from temperature and dewpoint This is only an approximation, there is no exact formula, this one here is called Magnus-Formula |
Services_Weather_Common::calculateWindChill() | Calculate windchill from temperature and windspeed (enhanced formula) |
Services_Weather_Common::convertDistance() | Convert distance between km, ft and sm |
Services_Weather_Common::convertPressure() | Convert pressure between in, hpa, mb, mm and atm |
Services_Weather_Common::convertSpeed() | Convert speed between mph, kmh, kt, mps and fps |
Services_Weather_Common::convertTemperature() | Convert temperature between f and c |
Services_Weather_Common::getUnitsFormat() | Returns the selected units format |
Services_Weather_Common::polar2cartesian() | Convert polar coordinates to cartesian coordinates |
Services_Weather_Common::setCache() | Enables caching the data, usage strongly recommended |
Services_Weather_Common::setDateTimeFormat() | Changes the representation of time and dates (see http://www.php.net/date) |
Services_Weather_Common::setHttpTimeout() | Sets the timeout in seconds for HTTP requests |
Services_Weather_Common::setUnitsFormat() | Changes the representation of the units (standard/metric) |
This class acts as an interface to the soap service of capescience.com. It searches for given locations and retrieves current weather data.
GlobalWeather is a SOAP frontend for METAR data, provided by CapeScience. If you want to use METAR, you should try this class first, as it is much more comfortable (and also a bit faster) than the native METAR-class provided by this package.
For a working example, please take a look at docs/Services_Weather/examples/globalweather-basic.php
Services_Weather_Globalweather
Services_Weather_Globalweather Inherited Methods
Таблица 62-1. Inherited from Services_Weather_Common
Method Name | Summary |
---|---|
Services_Weather_Common::calculateDewPoint() | Calculate dewpoint from temperature and humidity This is only an approximation, there is no exact formula, this one here is called Magnus-Formula |
Services_Weather_Common::calculateHumidity() | Calculate humidity from temperature and dewpoint This is only an approximation, there is no exact formula, this one here is called Magnus-Formula |
Services_Weather_Common::calculateWindChill() | Calculate windchill from temperature and windspeed (enhanced formula) |
Services_Weather_Common::convertDistance() | Convert distance between km, ft and sm |
Services_Weather_Common::convertPressure() | Convert pressure between in, hpa, mb, mm and atm |
Services_Weather_Common::convertSpeed() | Convert speed between mph, kmh, kt, mps and fps |
Services_Weather_Common::convertTemperature() | Convert temperature between f and c |
Services_Weather_Common::getUnitsFormat() | Returns the selected units format |
Services_Weather_Common::polar2cartesian() | Convert polar coordinates to cartesian coordinates |
Services_Weather_Common::setCache() | Enables caching the data, usage strongly recommended |
Services_Weather_Common::setDateTimeFormat() | Changes the representation of time and dates (see http://www.php.net/date) |
Services_Weather_Common::setHttpTimeout() | Sets the timeout in seconds for HTTP requests |
Services_Weather_Common::setUnitsFormat() | Changes the representation of the units (standard/metric) |
throws PEAR_Error::SERVICES_WEATHER_ERROR_WRONG_SERVER_DATA
throws PEAR_Error::SERVICES_WEATHER_ERROR_UNKNOWN_LOCATION
throws PEAR_Error::SERVICES_WEATHER_ERROR_WRONG_SERVER_DATA
throws PEAR_Error::SERVICES_WEATHER_ERROR_UNKNOWN_LOCATION
This class acts as an interface to the metar service of weather.noaa.gov. It searches for locations given in ICAO notation and retrieves the current weather data.
Of course the parsing of the METAR-data has its limitations, as it follows the Federal Meteorological Handbook No.1 with modifications to accomodate for non-US reports, so if the report deviates from these standards, you won't get it parsed correctly. Anything that is not parsed, is saved in the "noparse" array-entry, returned by getWeather(), so you can do your own parsing afterwards. This limitation is specifically given for remarks, as the class is not processing everything mentioned there, but you will get the most common fields like precipitation and temperature-changes. Again, everything not parsed, goes into "noparse".
If you think, some important field is missing or not correctly parsed, please file a feature- request/bugreport at http://pear.php.net/ and be sure to provide the METAR report with a _detailed_ explanation!
For a working example, please take a look at docs/Services_Weather/examples/metar-basic.php
Services_Weather_Metar
Services_Weather_Metar Inherited Methods
Таблица 62-1. Inherited from Services_Weather_Common
Method Name | Summary |
---|---|
Services_Weather_Common::calculateDewPoint() | Calculate dewpoint from temperature and humidity This is only an approximation, there is no exact formula, this one here is called Magnus-Formula |
Services_Weather_Common::calculateHumidity() | Calculate humidity from temperature and dewpoint This is only an approximation, there is no exact formula, this one here is called Magnus-Formula |
Services_Weather_Common::calculateWindChill() | Calculate windchill from temperature and windspeed (enhanced formula) |
Services_Weather_Common::convertDistance() | Convert distance between km, ft and sm |
Services_Weather_Common::convertPressure() | Convert pressure between in, hpa, mb, mm and atm |
Services_Weather_Common::convertSpeed() | Convert speed between mph, kmh, kt, mps and fps |
Services_Weather_Common::convertTemperature() | Convert temperature between f and c |
Services_Weather_Common::getUnitsFormat() | Returns the selected units format |
Services_Weather_Common::polar2cartesian() | Convert polar coordinates to cartesian coordinates |
Services_Weather_Common::setCache() | Enables caching the data, usage strongly recommended |
Services_Weather_Common::setDateTimeFormat() | Changes the representation of time and dates (see http://www.php.net/date) |
Services_Weather_Common::setHttpTimeout() | Sets the timeout in seconds for HTTP requests |
Services_Weather_Common::setUnitsFormat() | Changes the representation of the units (standard/metric) |
throws PEAR_Error::SERVICES_WEATHER_ERROR_UNKNOWN_LOCATION
throws PEAR_Error::SERVICES_WEATHER_ERROR_DB_NOT_CONNECTED
throws PEAR_Error::SERVICES_WEATHER_ERROR_INVALID_LOCATION
throws PEAR_Error::SERVICES_WEATHER_ERROR_UNKNOWN_LOCATION
throws PEAR_Error::SERVICES_WEATHER_ERROR_DB_NOT_CONNECTED
throws PEAR_Error::SERVICES_WEATHER_ERROR_INVALID_LOCATION
throws PEAR_Error::SERVICES_WEATHER_ERROR_UNKNOWN_LOCATION
throws PEAR_Error::SERVICES_WEATHER_ERROR_DB_NOT_CONNECTED
throws PEAR_Error::SERVICES_WEATHER_ERROR_WRONG_SERVER_DATA
This class acts as an interface to the xml service of weather.com. It searches for given locations and retrieves current weather data as well as forecast for up to 10 days.
For using the weather.com xml-service please visit http://www.weather.com/services/xmloap.html and follow the link to sign up, it's free! You will receive an email where to download the SDK with the needed images and guidelines how to publish live data from weather.com. Unfortunately the guidelines are a bit harsh, that's why there's no actual data-representation in this class, just the raw data. Also weather.com demands active caching, so I'd strongly recommend enabling the caching implemented in this class. It obeys to the times as written down in the guidelines.
For a working example, please take a look at docs/Services_Weather/examples/weather.com-basic.php
Services_Weather_Weatherdotcom
Services_Weather_Weatherdotcom Inherited Methods
Таблица 62-1. Inherited from Services_Weather_Common
Method Name | Summary |
---|---|
Services_Weather_Common::calculateDewPoint() | Calculate dewpoint from temperature and humidity This is only an approximation, there is no exact formula, this one here is called Magnus-Formula |
Services_Weather_Common::calculateHumidity() | Calculate humidity from temperature and dewpoint This is only an approximation, there is no exact formula, this one here is called Magnus-Formula |
Services_Weather_Common::calculateWindChill() | Calculate windchill from temperature and windspeed (enhanced formula) |
Services_Weather_Common::convertDistance() | Convert distance between km, ft and sm |
Services_Weather_Common::convertPressure() | Convert pressure between in, hpa, mb, mm and atm |
Services_Weather_Common::convertSpeed() | Convert speed between mph, kmh, kt, mps and fps |
Services_Weather_Common::convertTemperature() | Convert temperature between f and c |
Services_Weather_Common::getUnitsFormat() | Returns the selected units format |
Services_Weather_Common::polar2cartesian() | Convert polar coordinates to cartesian coordinates |
Services_Weather_Common::setCache() | Enables caching the data, usage strongly recommended |
Services_Weather_Common::setDateTimeFormat() | Changes the representation of time and dates (see http://www.php.net/date) |
Services_Weather_Common::setHttpTimeout() | Sets the timeout in seconds for HTTP requests |
Services_Weather_Common::setUnitsFormat() | Changes the representation of the units (standard/metric) |
throws PEAR_Error::SERVICES_WEATHER_ERROR_WRONG_SERVER_DATA
throws PEAR_Error::SERVICES_WEATHER_ERROR_UNKNOWN_LOCATION
Таблица 62-1. Constants defined in Weather.php
Name | Value | Line Number |
---|---|---|
SERVICES_WEATHER_ERROR_CACHE_INIT_FAILED | 13 | 41 |
SERVICES_WEATHER_ERROR_DB_NOT_CONNECTED | 14 | 42 |
SERVICES_WEATHER_ERROR_INVALID_LICENSE_KEY | 102 | 51 |
SERVICES_WEATHER_ERROR_INVALID_LOCATION | 2 | 48 |
SERVICES_WEATHER_ERROR_INVALID_PARTNER_ID | 100 | 49 |
SERVICES_WEATHER_ERROR_INVALID_PRODUCT_CODE | 101 | 50 |
SERVICES_WEATHER_ERROR_NO_LOCATION | 1 | 47 |
SERVICES_WEATHER_ERROR_SERVICE_NOT_FOUND | 10 | 38 |
SERVICES_WEATHER_ERROR_UNKNOWN_ERROR | 46 | |
SERVICES_WEATHER_ERROR_UNKNOWN_LOCATION | 11 | 39 |
SERVICES_WEATHER_ERROR_WRONG_SERVER_DATA | 12 | 40 |
SERVICES_WEATHER_EXPIRES_FORECAST | 7200 | 33 |
SERVICES_WEATHER_EXPIRES_LINKS | 43200 | 34 |
SERVICES_WEATHER_EXPIRES_LOCATION | 900 | 31 |
SERVICES_WEATHER_EXPIRES_UNITS | 900 | 30 |
SERVICES_WEATHER_EXPIRES_WEATHER | 1800 | 32 |
Таблица 62-2. Constants defined in WeatherCommon.php
Name | Value | Line Number |
---|---|---|
SERVICES_WEATHER_RADIUS_EARTH | 6378.15 | 32 |
Interface to the Yahoo! Search API.
The package provides an object oriented model to communicate with Yahoo's services via their REST-based XML interface.
The package provides an object oriented model to communicate with Yahoo's web services via their REST-based XML interface.
Currently the package only supports the Yahoo! Search Web Services, which is natural because Yahoo! does not expose other services via their API at the moment. Due to the modular layout of the package it is easy to add support for other services at a later point though. More information about the design of the package is available in a separate section.
Services_Yahoo requires PHP 5 and a bunch of PEAR packages. For a complete list of dependencies please see the download page.
The Services_Yahoo package can be installed using the PEAR installer command pear install Services_Yahoo. If the installation fails due to missing dependencies, one either needs to install them manually or can make the installer fetch all dependencies automatically: pear install -a Services_Yahoo.
Alternative installation methods for situations where one has no access to the pear installer command can be found in the general installation chapter.
The following sections provide you with examples of using the different feature sets of Services_Yahoo. Currently this includes documentation for the interfaces to Yahoo! Search and Content Analysis.
All public methods in Services_Yahoo have in common that exceptions will be raised when something goes wrong. This is why try { ... } catch { } blocks are wrapped around all examples.
Замечание: The examples are designed to be run from a command line shell. If you would like to test them in a web browser you should replace \n with <br /> for better readability.
The following examples will communicate with Yahoo! Search.
Пример 62-1. Web search: Listing results This snippet issues a search query for the term Steve Fossett to Yahoo! Search. For each result in the returned result set the title is printed.
By default 10 results are returned per request. This number can be modified using the method setResultNumber():
|
Пример 62-2. Web search: Result details This code again queries Yahoo! Search for Steve Fossett, but this time the details of the first result in the result set are printed.
|
Замечание: In order to query the Image, News, Video or Local search, one only needs to replace the argument "web" in the call of the factory() method with one of "image", "news", "video", or "local".
The following examples will show you how to use the Content Analysis Services provided by Yahoo!.
Пример 62-4. Term Extraction Service The Term Extraction service provides a list of significant words or phrases extracted from a larger content.
It is possible to skip the call to setQuery(). The parameter set by this method is intended to help the engine with the extraction process, but it is not stricly required. |
Пример 62-5. Spelling Suggestion Service The Spelling Suggestion service provides a suggested spelling correction for a given term. The following code queries Yahoo for a spelling suggestion for the term "madnna". The service will return exactly one result, but currently there is no way to avoid looping through the $results.
|
Services_Yahoo is split up into chunks that group similar functionality. Currently there are chunks for the interfaces to Yahoo Search and to the Content Analysis functions.
Each chunk basically contains two top-level element in the source tree: A .php file and a directory that holds the implementation of the chunk. The file is a class that contains only one method which implements that factory pattern. This method dynamically loads the right file from the related directory and returns an instance of the class that implements the desired function.
Due to this modular layout Services_Yahoo can easily be extended when Yahoo adds new functions to their API.
If you would like to study the code of the package, you can do so by either downloading a release from the package homepage or by browsing the code in CVS.
Also the automatically generated API documentation should help you.
Object-oriented abstraction for YouTube API.
Services_YouTube is an abstraction for the webservice of YouTube APIs. Using YouTube APIs, you can easily integrate online videos from YouTube's rapidly growing repository of videos into your application. To use YouTube API and this package, create a YouTube account and create a YouTube developer profile.
YouTube APIs currently allow read-only access to key parts of the YouTube video respository and user community. Services_YouTube provides functions for YouTube APIs using O-O abstraction access.
The following examples show how to use some basic features of Services_YouTube:
Пример 62-1. Retrieves the public parts of a user profile.
|
Пример 62-2. Lists a user's favorite videos.
|
Пример 62-3. Lists a user's friends.
|
Пример 62-4. Lists all videos that have the specified tag.
|
Пример 62-5. Lists all videos that were uploaded by the specified user.
|
Пример 62-6. Lists the most recent 25 videos that have been featured on the front page of the YouTube site.
|
Пример 62-7. Displays the details for a video.
|
UDDI implementation for PHP
PHP implementation of the XML-RPC protocol.
This is a PEAR-ified version of Useful inc's XML-RPC for PHP. It has support for HTTP transport, proxies and authentication.
XML-RPC is a format devised by Userland Software for achieving remote procedure call via XML. XML-RPC has its own web site, www.XmlRpc.com.
The most common implementations of XML-RPC available at the moment use HTTP as the transport. A list of implementations for other languages such as Perl and Python can be found on the www.xmlrpc.com.
This collection of PHP classes provides a framework for writing XML-RPC clients and servers in PHP.
This package has been orginially written by Edd Dumbill of Useful Information Company, so he deservers most of the credits. Apart from that following people have contributed to the initial codebase that is still being maintained by Edd:
Jim Winstead <jimw at php dot net>
Peter Kocks <peter.kocks at baygate dot com>
Nicolay Mausz <mausz at flying-dog dot com>
Ben Margolin <ben at wendy.auctionwatch dot com>
Dan Libby <dan at libby dot com>
Gaetano Giunta <g.giunta at libero dot it>
Idan Sofer <i_sofer at yahoo dot com>
Giancarlo Pinerolo <ping at alt dot it>
Justin Miller <justin at voxel dot net>
the XML-RPC server class. include() this to get server functionality.
the XML-RPC client classes. include() this to get client functionality.
The package is offered "as-is" without any warranty or commitment to support. However, informal advice and help is available via the PEAR user mailing list and XML-RPC.com.
The PEAR user mailing list can be contacted for questions concerning the usage of the package. More details can be found here.
For more general XML-RPC questions, there is a Yahoo! Groups XML-RPC mailing list.
The XML-RPC.com discussion group is a useful place to get help with using XML-RPC. This group is also gatewayed into the Yahoo! Groups mailing list.
Together with Simon St.Laurent and Joe Johnston, Edd Dumbill wrote a book on XML-RPC for O'Reilly and Associates on XML-RPC. It features a rather fetching jellyfish on the cover.
Complete details of the book are available from O'Reilly's web site.
Edd is responsible for the chapter on PHP, which includes a worked example of creating a forum server, and hooking it up the O'Reilly's Meerkat service in order to allow commenting on news stories from around the Web.
If you've benefitted from the effort he has put into writing this software, then please consider buying the book!
Пример 62-1.
|
Пример 62-2. Here is the server script. It's named xmlrpc.php and located in the document root of the web server at localhost:
And here is the client script:
|
The XML_RPC_encode() function automatically converts PHP data into the format needed by the XML_RPC library.
Пример 62-3.
|
This is the basic class used to represent a client of an XML-RPC server.
The constructor has the following syntax:
the path and name of the RPC server script you want the request to go to
the URL of the remote server to connect to. If this parameter doesn't specify a protocol and $port is 443, ssl:// is assumed.
a port for connecting to the remote server. Defaults to 80 for http:// connections and 443 for https:// and ssl:// connections.
the URL of the proxy server to use, if any. If this parameter doesn't specify a protocol and $port is 443, ssl:// is assumed.
a port for connecting to the remote server. Defaults to 8080 for http:// connections and 443 for https:// and ssl:// connections.
a user name for accessing the proxy server
a password for accessing the proxy server
Замечание: In order to use SSL connections, your PHP installation must have the openssl extension enabled.
Here's an example client set up to query Userland's XML-RPC server at betty.userland.com:
$client = new XML_RPC_Client('/RPC2', 'betty.userland.com'); |
This class supports the following methods.
This method takes the form:
Where $xmlrpc_message is an instance of XML_RPC_Message and $response is an instance of XML_RPC_Response (see XML_RPC_Response).
The $timeout is optional, and will be set to 0 (wait forever) if omitted. This timeout value is passed to fsockopen().
If the value of $response is 0 rather than an XML_RPC_Response object, then this signifies an I/O error has occured. You can find out what the I/O error was from the values $client->errno and $client->errstring.
In addition to low-level errors, the XML-RPC server you were querying may return an error in the XML_RPC_Response object. See XML_RPC_Response for details of how to handle these errors.
This method sets the username and password for authorizing the client to a server. With the default (HTTP) transport, this information is used for HTTP Basic authorization.
$debugOn is either 0 or 1 depending on whether you require the client to print debugging information to the browser. The default is not to output this information.
The debugging information includes the raw data returned from the XML-RPC server it was querying, and the PHP value the client attempts to create to represent the value returned by the server. This option can be very useful when debugging servers as it allows you to see exactly what the server returns.
This class provides a representation for a request to an XML-RPC server. A client sends an XML_RPC_Message to a server, and receives back an XML_RPC_Response.
The constructor takes the following form:
Where $methodName is a string indicating the name of the method you wish to invoke, and $parameterArray is a simple Array of XML_RPC_Value objects. Here's an example message to the US state name server:
require_once "XML/RPC.php"; $msg = new XML_RPC_Message("examples.getStateName", array(new XML_RPC_Value(23, "int"))); |
This example requests the name of state number 23. For more information on XML_RPC_Value objects, see XML_RPC_Value.
Adds the XML_RPC_Value $xmlrpcVal to the parameter list for this method call.
Returns an XML_RPC_Value object. If the parameter doesn't exist, an XML_RPC_Response object is returned.
Gets the $nth parameter in the message. Use this method in server implementations. Returns the undef value if no such parameter exists.
Given an incoming XML-RPC server response contained in the string $xmlString, this method constructs an XML_RPC_Response response object and returns it, setting error codes as appropriate.
This method processes any HTTP/MIME headers it finds.
This class is used to contain responses to XML-RPC requests. A server method handler will construct an XML_RPC_Response and pass it as a return value. This same value will be returned by the result of an invocation of the send() method of the XML_RPC_Client class.
The first instance is used when execution has happened without difficulty: $xmlrpcval is an XML_RPC_Value value with the result of the method execution contained in it.
The second type of constructor is used in case of failure. $errcode and $errstring are used to provide indication of what has gone wrong. See XML_RPC_Server for more information on passing error codes.
Returns the integer fault code return from the XML-RPC response $resp. A zero value indicates success, any other value indicates a failure response.
This is where a lot of the hard work gets done. This class enables the creation and encapsulation of values for XML-RPC.
Ensure you've read the XML-RPC spec at http://www.xmlrpc.com/stories/storyReader$7 before reading on as it will make things clearer.
The XML_RPC_Value class can store arbitrarily complicated values using the following types: i4, int, boolean, string, double, dateTime.iso8601, base64, array or struct. You should refer to the spec for more information on what each of these types mean.
The type i4 is accepted as a synonym for int. The value parsing code will always convert i4 to int: int is regarded by this implementation as the canonical name for this type.
Base 64 encoding is performed transparently to the caller when using this type. Therefore you ought to consider it as a binary data type, for use when you want to pass none 7-bit clean data. Decoding is also transparent.
The values true and 1 map to true. All other values (including the empty string) are converted to false.
The characters <, >, " and & are converted to their entity equivalents <, >, " and & for transport through XML-RPC. The current XML-RPC spec recommends only encoding < and & but this implementation goes further, for reasons explained by the XML 1.0 recommendation.
TODO: ' entity is not yet supported
The constructor is the normal way to create an XML_RPC_Value. The constructor can take these forms:
The first constructor creates an empty value, which must be altered using the methods addScalar(), addArray() or addStruct() before it can be used.
The second constructor creates a simple string value.
The third constructor is used to create a scalar value. The second parameter must be a name of an XML-RPC type. Examples:
$myInt = new XML_RPC_Value(1267, "int"); $myString= new XML_RPC_Value("Hello, World!", "string"); $myBool = new XML_RPC_Value(1, "boolean"); |
The fourth constructor form can be used to compose complex XML-RPC values. The first argument is either a simple array in the case of an XML-RPC array or an associative array in the case of a struct. The elements of the array must be XML_RPC_Value objects themselves. Examples:
$myArray = new XML_RPC_Value(array( new XML_RPC_Value("Tom"), new XML_RPC_Value("Dick"), new XML_RPC_Value("Harry")), "array"); $myStruct = new XML_RPC_Value(array( "name" => new XML_RPC_Value("Tom"), "age" => new XML_RPC_Value(34, "int"), "geek" => new XML_RPC_Value(1, "boolean")), "struct"); |
If $val is an empty XML_RPC_Value this method makes it a scalar value, and sets that value. If $val is already a scalar value, then no more scalars can be added and 0 is returned. If all went OK, 1 is returned.
There is a special case if $val is an array: the scalar value passedis appended to the array.
Turns an empty XML_RPC_Value into an array with contents as specified by $arrayVal. See the fourth constructor form for more information.
Turns an empty XML_RPC_Value into a struct with contents as specified by $assocArrayVal. See the fourth constructor form for more information.
Returns a string containing struct, array or scalar describing the base type of the value. If it returns undef it means that the value hasn't been initialised.
If $val->kindOf() == 'scalar', this method returns the actual PHP-language value of the scalar (base 64 decoding is automatically handled here).
If $val->kindOf() == 'scalar', this method returns a string denoting the type of the scalar. As mentioned before, i4 is always coerced to int.
Returns the $nth element in the array represented by the value $val. The value returned is an XML_RPC_Value object.
Returns the element called $memberName from the struct represented by the value $val. The value returned is an XML_RPC_Value object.
Returns the next (key,value) pair from the struct, when $val is a struct. See also structreset().
The current implementation of this class has been kept as simple as possible. The constructor for the server basically does all the work. Here's a minimal example:
function foo ($params) { ... } $s = new XML_RPC_Server(array("examples.myFunc" => array("function" => "foo"))); |
This performs everything you need to do with a server. The single argument is an associative array from method names to function names. The request is parsed and despatched to the relevant function, which is reponsible for returning a XML_RPC_Response object, which gets serialized back to the caller.
Here is a more detailed look at what the handler function foo() may do:
function foo ($params) { global $XML_RPC_erruser; // import user errcode value // $params is the received XML_RPC_Message object. if ($err) { // this is an error condition return new XML_RPC_Response(0, $XML_RPC_erruser+1, // user error 1 "There's a problem, Captain"); } else { // this is a successful value being returned return new XML_RPC_Response(new XML_RPC_Value("All's fine!", "string")); } } |
The first argument to the XML_RPC_Server() constructor is an array, called the dispatch map. In this array is the information the server needs to service the XML-RPC methods you define.
The dispatch map takes the form of an associative array of associative arrays: the outer array has one entry for each method, the key being the method name. The corresponding value is another associative array, which can have the following members:
function - this entry is mandatory. It must be a name of a function in the global scope which services the XML-RPC method.
It is possible to use regular functions, class names with method names and objects with method names. The Examples page of this manual demonstrates the appropriate syntax for all of these approaches.
signature - this entry is an array containg the possible signatures (see Signatures) for the method. If this entry is present then the server will check that the correct number and type of parameters have been sent for this method before dispatching it.
docstring - this entry is a string containing documentation for the method. The documentation may contain HTML markup.
A signature is a description of a method's return type and its parameter types. A method may have more than one signature.
Within a server's dispatch map, each method has an array of possible signatures. Each signature is an array of types. The first entry is the return type.
Let's run through an example. Imagine you wanted to write a regular PHP function like this:
function is_8($input, $strict = false) { if ($strict) { return ($input === 8); } else { return ($input == 8); } } |
To get it to work in an XML_RPC server, you would have to write it like this:
function is_8($params) { // This parameter is required. $param = $params->getParam(0); if (!XML_RPC_Value::isValue($param)) { return $param; } $input = $param->scalarval(); // This parameter is optional. $param = $params->getParam(1); if (!XML_RPC_Value::isValue($param)) { $strict = false; } else { $strict = $param->scalarval(); } if ($strict) { $answer = ($input === 8); } else { $answer = ($input == 8); } $val = new XML_RPC_Value($answer, 'boolean'); return new XML_RPC_Response($val); } |
Here is a signature covering all of the possible permutations:
array( array('boolean', 'int'), array('boolean', 'int', 'boolean'), array('boolean', 'string'), array('boolean', 'string', 'boolean'), ) |
The server could be instatiated like this:
$server = new XML_RPC_Server( array( 'isan8' => array( 'function' => 'is_8', 'signature' => array( array('boolean', 'int'), array('boolean', 'int', 'boolean'), array('boolean', 'string'), array('boolean', 'string', 'boolean'), ), 'docstring' => 'Is the value an 8?' ), ), 1, 0 ); |
The strings representing the XML-RPC types have been encoded as global variables for your convenience:
$GLOBALS['XML_RPC_I4'] = 'i4'; $GLOBALS['XML_RPC_Int'] = 'int'; $GLOBALS['XML_RPC_Boolean'] = 'boolean'; $GLOBALS['XML_RPC_Double'] = 'double'; $GLOBALS['XML_RPC_String'] = 'string'; $GLOBALS['XML_RPC_DateTime'] = 'dateTime.iso8601'; $GLOBALS['XML_RPC_Base64'] = 'base64'; $GLOBALS['XML_RPC_Array'] = 'array'; $GLOBALS['XML_RPC_Struct'] = 'struct'; |
You may want to construct the server, but for some reason not fulfill the request immediately (security verification, for instance). If you pass the constructor a second argument of 0 this will have the desired effect. You can then use the service() method of the server class to service the request. For example:
$s = new XML_RPC_Server($myDispMap, 0); // ... some code that does other stuff here $s->service(); |
Fault codes for your servers should start at the value indicated by the global $xmlrpcerruser + 1.
Standard errors returned by the server include:
Returned if the server was asked to dispatch a method it didn't know about
This error is actually generated by the client, not server, code, but signifies that a server returned something it couldn't understand.
This error is generated when the server has signature(s) defined for a method, and the parameters passed by the client do not match any of signatures.
This error is generated by the builtin system.*() methods when any kind of introspection is attempted on a method undefined by the server.
This error is generated by the client when a remote server doesn't return HTTP/1.1 200 OK in response to a request. A more detailed error report is added onto the end of the phrase above.
Returns 100 plus the XML parser error code for the fault that occurred. The faultString returned explains where the parse error was in the incoming XML stream.
PHP5 implementation of the XML-RPC protocol.
This is a "PHP5 only" implementation of the XMLRPC protocol. This package provides the client and the server side of the protocol. An optimized cache is also available for both parts.
As a client library, XML_RPC2 is capable of creating a proxy class which exposes the methods exported by the server. As a server library, XML_RPC2 is capable of exposing methods from a class or object instance, seamlessly exporting local methods as remotely callable procedures.
XML_RPC2 is a "PHP5 only" implementation of the XMLRPC protocol. This package provides the client and the server side of the protocol. An optimized cache is also available for both parts.
As a client library, XML_RPC2 is capable of creating a proxy class which exposes the methods exported by the server. So it's very easy and natural to call XMLRPC exported methods. Like in Python language, the classic way to use XML_RPC2 client side is :
We make a XML_RCP2_Client object with server informations as arguments.
In a classic way, we call a method of this object.
Then, the method call is XMLRPC encoded, sent to the server, the response is decoded into PHP native types and we get the result of the call (all this logic is made by the library in a completely transparent way).
As a server library, XML_RPC2 is capable of exposing methods from a class or object instance, seamlessly capable of exposing methods from a class or object instance, seamlessly exporting local methods as remotely callable procedures. Method signatures are automatically determined and checked by using the reflection API and PHPDOC comments. An automatic documentation about XMLRPC exported methods is dynamically built and available at the server URL (with a simple HTTP GET).
For both sides, an optimized cache based on Cache_Lite can be set. It can be really usefull especially on public XMLRPC servers.
XML_RCP2 need PHP5 and the CURL extension. To avoid in next version, the CURL dependency, we are waiting for a PHP5 E_STRICT PEAR module for HTTP_Request.
If you want to use the integrated cache, you will also need the Cache_Lite PEAR module but it's of course an optional dependency.
XML_RPC2 can use two backends for the XMLRPC encoding/decoding :
XMLRPCEXT, which of course need this PHP extension (probably the better choice but it's an additional dependency) ;
PHP, which doesn't need the XMLRPCEXT extension at all (this is full PHP but slower).
Let's start with a XMLRPC call to the pear.php.net XMLRPC server :
<?php require_once 'XML/RPC2/Client.php'; $options = array( 'prefix' => 'package.' ); // We make the XML_RPC2_Client object (as the backend is not specified, XMLRPCEXT // will be used if available (full PHP else)) $client = XML_RPC2_Client::create('http://pear.php.net/xmlrpc.php', $options); try { // Because of the prefix specified in the $options array, indeed, we will call // the package.info() method with a single argument (the string 'XML_RPC2') $result = $client->info('XML_RPC2'); // $result is a complex PHP type (no XMLRPC decoding needed, it's already done) print_r($result); } catch (XML_RPC2_FaultException $e) { // The XMLRPC server returns a XMLRPC error die('Exception #' . $result->getFaultCode() . ' : ' . $e->getFaultString()); } catch (Exception $e) { // Other errors (HTTP or networking problems...) die('Exception : ' . $e->getMessage()); } ?> |
Let's build a XMLRPC "echo server" :
<?php require_once 'XML/RPC2/Server.php'; // Let's define a class with public static methods // PHPDOC comments are really important because they are used for automatic // signature checking class EchoServer { /** * echoes the message received * * @param string Message * @return string The echo */ public static function echoecho($string) { return $string; } } $options = array( 'prefix' => 'test.' // we define a sort of "namespace" for the server ); // Let's build the server object with the name of the Echo class $server = XML_RPC2_Server::create('EchoServer', $options); $server->handleCall(); ?> |
As the caching process is completely transparent, this is very similar to the standard client side use :
<?php require_once 'XML/RPC2/CachedClient.php'; $options = array( 'prefix' => 'package.', 'cacheDebug' => false, // with cacheDebug set to true, it's very easy // to get an indication about the cache using (or not) 'cacheOptions' => array( 'cacheDir' => '/tmp/', 'lifetime' => 3600, // during this lifetime, the local cache will be used 'cacheByDefault' => true // all methods call will be cached // (but a more precise way is possible) ) ); // We make the XML_RPC2_CachedClient object (same syntax than XML_RPC2_Client) $client = XML_RPC2_CachedClient::create('http://pear.php.net/xmlrpc.php', $options); try { // First call, the cache won't be used $result = $client->info('XML_RPC2'); print_r($result); // Second call, the cache will be used (in a transparent way) and no // additional HTTP request will be sent to the server $result = $client->info('XML_RPC2'); print_r($result); } catch (XML_RPC2_FaultException $e) { // The XMLRPC server returns a XMLRPC error die('Exception #' . $result->getFaultCode() . ' : ' . $e->getFaultString()); } catch (Exception $e) { // Other errors (HTTP or networking problems...) die('Exception : ' . $e->getMessage()); } ?> |
As the caching process is completely transparent, this is very similar to the standard server side use :
<?php require_once 'XML/RPC2/CachedServer.php'; // Let's define a class with public static methods // PHPDOC comments are really important because they are used for automatic // signature checking // IMPORTANT : note the @xmlrpc.caching PHPDOC tags to indicate // that the method has to be cached class EchoServer { /** * echoes the message received * * @param string Message * @return string The echo * @xmlrpc.caching true */ public static function echoecho($string) { return $string; } } $options = array( 'prefix' => 'test..', 'cacheDebug' => false, // with cacheDebug set to true, it's very easy // to get an indication about the cache using (or not) 'cacheOptions' => array( 'cacheDir' => '/tmp/', 'lifetime' => 3600, 'cacheByDefault' => false // we don't cache by default (only methods with @xmlrpc.caching true) ) ); $server = XML_RPC2_CachedServer::create('EchoServer', $options); $server->handleCall(); ?> |
Thanks to PHP5, it's really easy to do XMLRPC client requests with XML_RPC2. The usage is really straightforward.
First, you include 'XML/RPC2/Client.php' file (only this one).
require_once 'XML/RPC2/Client.php'; |
Second, you make an assocative arrays of options to tune XML_RPC2 (prefix, proxy, manual backend choice...).
$options = array( 'prefix' => 'package.' ); |
Third, you make a XML_RPC2_Client object with the server URL and the with the options array.
$client = XML_RPC2_Client::create('http://pear.php.net/xmlrpc.php', $options); |
Then, you send your request by calling the server method as it was a local method of the $client object.
$result = $client->info('XML_RPC2'); |
Of course, to catch server errors, you have to add a few lines around you client call like for example :
try { $result = $client->info('XML_RPC2'); print_r($result); } catch (XML_RPC2_FaultException $e) { // The XMLRPC server returns a XMLRPC error die('Exception #' . $result->getFaultCode() . ' : ' . $e->getFaultString()); } catch (Exception $e) { // Other errors (HTTP or networking problems...) die('Exception : ' . $e->getMessage()); } |
This array is completely optional but really usefull. The following keys are available :
Таблица 62-1. Options available keys
Option | Data Type | Default Value | Description |
---|---|---|---|
prefix | string | '' | Prefix added before XMLRPC called method name |
proxy | string | '' | Proxy used for the HTTP request (default : no proxy) |
debug | boolean | FALSE | Debug mode ? |
encoding | string | '' | Encoding of the request 'utf-8', 'iso-8859-1' (for now, only these two ones are officialy supported) |
uglyStructHack | boolean | TRUE | ugly hack to circumvent a XMLRPCEXT bug/feature , see this PHP bug for more details. The only (reasonable) counterpart of this hack is that you can't use structs with a key beginning with the string 'xml_rpc2_ugly_struct_hack_' as arguments of the called method. |
It's really easy to make the XML_RPC2_Client object. Use the following syntax :
// $XMLRPCServerURL is a string : 'http://pear.php.net/xmlrpc.php' (for example) // $options is an optional array : see previous section for more informations $client = XML_RPC2_Client::create($XMLRPCServerURL, $options); |
When the XML_RPC2_Client object is created, you can directly call the remote method as it was local. For example :
// We call the remote foo() method without any arguments $result1 = $client->foo(); // We call the remote bar() method with two arguments (an integer : 123, a string : 'foo') $result2 = $client->bar(123, 'foo'); // We call the remote foobar() method with complex data types (2 integer, a string, a structure) $result3 = $client->foobar(1, 2, 'foo', array('foo' => 1, 'bar' => 2)); |
Be carefull, XMLRPC spec allows some remote method names with some special characters like "." or "/"... which are not available as PHP method names. To deal with them, you have to fix a prefix in a the options array. For example :
$options = array('prefix' => 'foo.'); $client = XML_RPC2_Client::create('http://...', $options); // We call the foo.bar() method because of the prefix 'foo.' fixed in $options array $result = $client->bar(); |
In most cases, XML_RPC2 transforms automatically PHP native types into XMLRPC types (as described in the SPEC) for the request. In most cases too, XML_RPC2 transforms the XML server response into PHP native types too. Yet, there are two exceptions : 'dateTime.iso8601' and 'base64' which doesn't really exist in PHP.
To manipulate explicitely these two types, you have to use special objects. Let's see a complete example :
<?php // Classic usage require_once 'XML/RPC2/Client.php'; // To manipulate these types, we need to include this file too require_once 'XML/RPC2/Value.php'; // To get a 'dateTime.iso8601' object, you have first to set a string with an iso8601 encoded date : $tmp = "20060116T19:14:03"; // Then, you call this static method to get your 'dateTime.iso8601' object $time = XML_RPC2_Value::createFromNative($tmp, 'datetime'); // For 'base64', you call the same static method with your string to get a 'base64' object $base64 = XML_RPC2_Value::createFromNative('foobar', 'base64'); // Then, you can use XML_RPC2_Client as usual : $options = array('prefix' => 'validator1.'); $client = XML_RPC2_Client::create('http://phpxmlrpc.sourceforge.net/server.php', $options); $result = $client->manyTypesTest(1, true, 'foo', 3.14159, $time, $base64); // The remote validator1.manyTypesTest() method returns an array with the 6 given arguments $result_datetime = $result[4]; // a 'dateTime.iso8601' object $result_base64 = $result[5]; // a 'base64' object // To transform these objects into PHP native types, you have to use public properties of // these objects as follow : var_dump($result_datetime->scalar); // will return string(17) "20060116T19:14:03" var_dump($result_datetime->xmlrpc_type); // will return string(8) "datetime" var_dump($result_datetime->timestamp); // will return int(1137435243) var_dump($result_base64->scalar); // will return string(6) "foobar" var_dump($result_base64->xmlrpc_type); // will return string(6) "base64" ?> |
Thanks to PHP5 and PEAR/Cache_Lite, it's really easy to do XMLRPC "cached client" requests with XML_RPC2. The usage is really straightforward.
First, you include 'XML/RPC2/CachedClient.php' file (only this one).
require_once 'XML/RPC2/CachedClient.php'; |
Second, you make an assocative arrays of options to tune XML_RPC2 (prefix, proxy, manual backend choice...).
$options = array( 'prefix' => 'package.', 'cacheOptions' => array( 'cacheDir' => '/tmp/', 'lifetime' => 3600 ) ); |
Third, you make a XML_RPC2_CachedClient object with the server URL and the with the options array.
$client = XML_RPC2_CachedClient::create('http://pear.php.net/xmlrpc.php', $options); |
Then, you send your request by calling the server method as it was a local method of the $client object.
$result = $client->info('XML_RPC2'); |
Of course, to catch server errors, you have to add a few lines around you client call like for example :
try { $result = $client->info('XML_RPC2'); print_r($result); } catch (XML_RPC2_FaultException $e) { // The XMLRPC server returns a XMLRPC error die('Exception #' . $result->getFaultCode() . ' : ' . $e->getFaultString()); } catch (Exception $e) { // Other errors (HTTP or networking problems...) die('Exception : ' . $e->getMessage()); } |
This array is completely optional but really usefull. The following keys are available :
Таблица 62-1. Options available keys
Option | Data Type | Default Value | Description |
---|---|---|---|
[...] | [...] | [...] | See "non cached client side" for more options |
cacheOptions | array | array() | See next table for a complete description |
Таблица 62-2. CacheOptions available keys
Option | Data Type | Default Value | Description |
---|---|---|---|
[...] | [...] | [...] | See "Cache_Lite constructor" for more options |
defaultCacheGroup | string | '' | Name of the default cache group |
cachedMethods | array | array() | Array of method names to be cached (if cacheByDefault is false) |
notCachedMethods | array | array() | Array of method names not to be cached (if cacheByDefault is true) |
cacheByDefault | boolean | TRUE | if true, the cache is "on" by default ; else, only methods listed in cachedMethods will be cached |
It's really easy to make the XML_RPC2_CachedClient object. Use the following syntax :
// $XMLRPCServerURL is a string : 'http://pear.php.net/xmlrpc.php' (for example) // $options is an optional array : see previous section for more informations $client = XML_RPC2_CachedClient::create($XMLRPCServerURL, $options); |
See "non cached client side" documentation, there is no difference.
The caching process is completly embedded and automatic. If a cache is available, result will be get from cache and no HTTP request will be sent. If there is no cache available for this particular call (method name and arguments), the classical XMLRPC communication will be used (and the result will be stored into a cache file for the next use).
Предоставляет пакеты для создания и работы с XML
Package to "beautify" XML documents. This package will add line breaks, indentation and other layout elements to an XML document, so it can be easier read by humans.
XML_Beautifier is a package, that helps you making XML documents easier to read for human beings.
It is able to add line-breaks, indentation, sorts attributes, convert tag cases and wraps long comments. It recognizes tags, character data, comments, XML declarations, processing instructions and external entities and is able to format these tokens nicely.
The document is split into these tokens using the XML_Beautifier_Tokenizer class and the expat parser. Then a renderer is used to create the string representation of the document and formats it using the specified options.
Currently only one renderer is available, but as XML_Beautifier uses a driver-based architecture, other renderers (like syntax-highlighting) will follow soon.
Let's assume, you've got an XML document that is really badly formatted:
<?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE page [ <!ENTITY foo SYSTEM "foo.xml"> <!ENTITY bar SYSTEM "bar.xml"> ]> <document title="Current News"> <meta project="none" foo="bar"> <keywords/><description/> <author>Stephan Schmidt</author> <getMetaNav/> </meta> <page label="PHP Application Tools" sublabel="Current News"> <?php for($i = 0; $i < count($_GET); $i++) { echo $_GET[$i]."<br>"; } ?> &foo;&bar; <intro> <!-- This Comment has more than one line. --> <introtitle>Welcome to PHP Application Tools & PEAR!</introtitle> <para> If you're new to pat, and would like <!-- This is a comment in a single line that contains an & --> to know what we do here, take a look at <link url= "/about/project.xml"> "About Pat"</link> or check out the <link url="/about/projectsOverview.xml">"projects overview"</link>. Otherwise, you probably know your way around the site already <smiley type="smile"/> </para> </intro> </page> </document> |
All you have to do is to use XML_Beautifier, pass the filename of the original file and the filename for the new file:
require_once "XML/Beautifier.php"; $fmt = new XML_Beautifier(); $result = $fmt->formatFile('originalFile.xml', 'beautifiedFile.xml'); if (PEAR::isError($result)) { echo $result->getMessage(); exit(); } echo "File beautified, awaiting orders!<br />"; |
And voila, your document looks nice:
<?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE page [ <!ENTITY foo SYSTEM "foo.xml"> <!ENTITY bar SYSTEM "bar.xml"> ]> <document title="Current News"> <meta foo="bar" project="none"> <keywords /> <description /> <author>Stephan Schmidt</author> <getMetaNav /> </meta> <page label="PHP Application Tools" sublabel="Current News"> <?php for($i = 0; $i < count($_GET); $i++) { echo $_GET[$i]."<br>"; } ?> &foo; &bar; <intro> <!-- This Comment has more than one line. --> <introtitle>Welcome to PHP Application Tools & PEAR!</introtitle> <para> If you're new to pat, and would like <!-- This is a comment in a single line that contains an & --> to know what we do here, take a look at <link url="/about/project.xml">"About Pat"</link> or check out the <link url="/about/projectsOverview.xml">"projects overview"</link> . Otherwise, you probably know your way around the site already <smiley type="smile" /> </para> </intro> </page> </document> |
Options let you influence the beautifiying process. They are passed to the renderer and thus, you have to check, whether the renderer you are using supports the options you want to use.
As there currently is only one renderer (Plain) available, you should not worry about this too much.
Options can be passed as an associative array to the constructor of XML_Beautifier. You may also use setOption(), or setOptions() to set one or more options after the instance of XML_Beautifier has been created.
Here is a list of all options supported by XML_Beautifier.
Таблица 63-1. XML_Beautifier options
Option | Possible values | Default | Description |
---|---|---|---|
removeLineBreaks | TRUE or FALSE | TRUE | Sets, whether linebreaks should be stripped from cdata sections |
indent | any string | " " (4 spaces) | The string passed to this option will be used to indent the tags in one level. |
linebreak | any string | "\n" | The string passed to this option will be used for linebreaks You should use "\n" or "\r\n". |
caseFolding | TRUE or FALSE | FALSE | Disable or enable case folding for tags and attributes |
caseFoldingTo | "uppercase" or "lowercase" | "uppercase" | Can be used, if caseFolding is set to TRUE to define whether tags and attributes should be converted to upper- or lowercase |
normalizeComments | FALSE or TRUE | FALSE | If set to true, all adjacent whitespaces in an XML comment will be converted to one space. This will convert comments with more than one line to a comment with one line. |
maxCommentLine | integer | -1 | Maximum length of comment line. If a comment exceeds this limit, it will be wrapped automatically. If set to -1 the line length is unlimited. |
multilineTags | TRUE or FALSE | FALSE | If set to true, a linebreak will be added inside the tags after each attribute and attributes will be indeted. |
The following example shows how to set options for XML_Beautifier.
Пример 63-1. Using setOptions() and setOption()
|
The following example shows how to set options for XML_Beautifier, if the instance already has been created.
Пример 63-2. XML_Beautifier options
|
array $options - options are used to influence to beautifying process. You may set the indent string, specify whether case folding should be enabled, etc...
See XML_Beautifier options for more information.
Set an option for the beautifying process.
See XML_Beautifier options for more information.
Set several options for the beautifying process.
See XML_Beautifier options for more information.
array $options - associative array containing options and their values, like you would pass it to the constructor.
Reset all options to their default values.
See XML_Beautifier options for more information.
string $file - filename of the original file
string $newFile - filename for the beautified file. If no file is given, the method will return the resulting XML document. To overwrite the original file, pass XML_BEAUTIFIER_OVERWRITE.
string $renderer - renderer to use, currently only a "Plain" XML renderer can be used.
Beautifies an XML string. Use this method to beautify an XML document that has been generated on-the-fly.
Parses DTD files and does DTD validation of XML documents.
XML_DTD is able to parse a document type definition (DTD) file and validate XML documents according to this DTD. A DTD is the grammar of an XML application, it consist of rules that declare how tags have to be nested and which attributes may be used in the tags.
If you want to learn how to create a DTD, you should take a look at the W3C.
XML_DTD consits of two parts:
XML_DTD_Parser, which will parse a DTD file and return an XML_DTD_Tree object
XML_DTD_XmlValidator, which validates an XML document using a DTD file
If you validate an XML_Document using XML_DTD_XmlValidator, it will automatically parse the DTD file and create an XML_DTD_Tree from it.
XML_Feed_Parser is a parser for (the various) RSS and Atom format XML feeds. It provides a somewhat unified API while still allowing access to the full details of each feed type.
XML_Feed_Parser provides a generic interface to a number of the most popular XML-based syndication formats (Atom, RSS1, RSS2, etc). In order to focus on its core competencies, it does not provide any HTTP or feed creation features, but instead parses a wide range of formats quickly and simply.
Presuming the XML for a feed is stored in the variable $xml_source, the simplest way to create an instance of the parser is:
try { $feed = new XML_Feed_Parser($xml_source); } catch (XML_Feed_Parser_Exception $e) { die('Feed invalid: ' . $e->getMessage()); } |
The constructor accepts a number of parameters, as follows:
/* The file you wish to parse */ $source = 'my_source.xml'; /* Where Relax NG is available, we can force validation of the feed */ $validate = true; /* Whether or not to suppress non-fatal warnings */ $suppress_warnings = false; /* If the feed is not valid XML and the tidy extension is installed we can * attempt to use it to fix the feed */ $use_tidy = true; $feed = new XML_Feed_Parser($source, $validate, $suppress_warnings, $use_tidy); |
Once you have an instance of the parser you can extract feed-level data by querying it directly. eg.
$title = $feed->title; |
You can also access elements by iterating over the feed, or directly by offset or id.
foreach ($feed as $entry) { print $entry->title . "\n"; } $first_entry = $feed->getEntryByOffset(0); $particular_entry = $feed->getEntryById('http://jystewart.net/entry/1'); |
Using XML namespaces, the various syndication formats are very easy to extend and the number of extensions in use is enormous.
XML_Feed_Parser focuses on core functionality shared between the various syndication formats. Some of the most common extensions are handled natively—particularly when they provide one format with features to bring it into line with others, such as the content extension for RSS2—but the majority provide specialist content and providing support for them would quickly result in a bloated package.
It is possible that a proper extensions mechanism may be introduced in a future version, but as an alternative the DOM models in use within the classes are publicly accessible, allowing the package to be wrapped with special handlers.
For example, to make use of the 'pheed' extension (namespace http://www.pheed.com/pheed/) we might use:
$feed = new XML_Feed_Parser($xml_source); $entry = $feed->getEntryByOffset(0); $eModel = $entry->model; $thumbnails = $eModel->getElementsByTagNameNS( 'http://www.pheed.com/pheed/', 'thumbnail'); if ($thumbnails->length) { $thumbnail_url = $thumbnails->item(0)->nodeValue; } |
Object-oriented abstraction for PHP's xml extension.
XML_Parser provides an object-oriented abstraction to PHP's ext/xml. It helps you processing XML documents by supplying methods that are needed when working with XML documents, like automatic error handling, parsing from a file, URL or string as well as an easy way to register callbacks.
XML_Parser uses SAX-based parsing, which is a simple API to retrieve information from XML documents. While the parser reads the document, it will call methods for the different nodes that are found. These nodes range from opening and closing tags to character data and processing instructions.
You will not be able to use XML_Parser directly to parse your documents, but you have to create a new class that extends XML_Parser and implement handlers for the tags and all other elements you need to process.
Several of PEAR's XML packages use this approach and thus rely on XML_Parser. If you would like to take a look at real-life examples, just install XML_RDDL, XML_Beautifier, XML_Statistics or XML_Serializer.
A tutorial that explains nearly every feature of XML_Parser is available at http://www.schst.net/articles/XML_Parser.
This example shows you how to create a very simple parser that handles start, end elements (i.e. opening and closing tags), and character data (the "content" between the tags).
require_once 'XML/Parser.php'; class myParser extends XML_Parser { function myParser() { parent::XML_Parser(); } /** * handle start element * * @access private * @param resource xml parser resource * @param string name of the element * @param array attributes */ function startHandler($xp, $name, $attribs) { printf('handle start tag: %s<br />', $name); } /** * handle start element * * @access private * @param resource xml parser resource * @param string name of the element */ function endHandler($xp, $name) { printf('handle end tag: %s<br />', $name); } /** * handle character data * * @access private * @param resource xml parser resource * @param string character data */ function cdataHandler($xp, $cdata) { // does nothing here, but might e.g. print $cdata } } $p = &new myParser(); $result = $p->setInputFile('xml_parser_file.xml'); $result = $p->parse(); |
This parser will just output the names of the opening and closing tags that are found while parsing the document.
XML_Parser provides two modes for parsing:
func
event
In the 'event' mode, XML_Parser will always call the methods startHandler() and endHandler(), independent of the tag name. In these methods you'll have to check for the tagname, which is passed as the second parameter and decide what you need to do. In most cases, this is done with a switch/case statement.
In the 'func' mode, XML_Parser will call different methods based on the name of the tag. This allows you to dispatch different tags to different methods. The methods to handle the start tag have to be called xmltag_[tagname](), where [tagname] has to be substituted by the name of the element that you wish to process. That means if you wish to write a method to process all opening <title> tags, it has to be called xmltag_title.
Methods to handle closing tags have to be named xmltag_[tagname]_() (distinguishes from the start element handler using a traling underscore).
As XML tags may contain chars like ".", ":" and "-" and those chars are not allowed in PHP function names, XML_Parser will replace them with "_" when building the name of the callback function.
If a method does not exist, XML_Parser will skip the tag without handling the element, unless you implemented the methods xmltag() and xmltag_(), which will be used as fallback methods.
There are two ways of setting the mode:
Specifying the mode in the constructor as the second parameter.
In the subclass of XML_Parser that you implemented to process the XML documents, you will have to call XML_Parser::XML_Parser() in the constructor. This method accepts the mode as its second parameter.
Setting the mode using XML_Parser::setMode().
XML_Parser is able to parse from several inputs:
filesystem or anything that can be accessed via stream
strings
resources
You will have to set the input using setInputFile(), setInputString() or setInput() and then call parse() to start the XML processing.
To parse from a file or URL, you'll have to set the name or URI using XML_Parser::setInputFile(). You may not only use files located on the filesystem, but any location that can be opened using fopen(). You may combine this functionality with the stream functions or PEAR's Streams packages to parse documents from shared memory, databases or anything else.
You may also use any of PHP's built-in wrappers to open HTTP or FTP locations as well as STDIN.
To parse an XML string, pass the string to XML_Parser (or your subclass of XML_Parser) using XML_Parser::setInputString(). A big advantage of SAX-based parsing is that the parser does not have to read the whole XML document to process it. If you are parsing very large documents, you should aboid setInputString() and use setInput() or setInputFile() instead.
There's a third, but seldomly used way to specify XML_Parser's input. XML_Parser allows you to pass a PHP resource, like a file pointer that has been returned by fopen(). This can be useful, if you are generating the document on-the-fly and already opened it before. Instead of closing the file and passing its name to XML_Parser, you may simply use XML_Parser::setInput() to pass the resource. Make sure that the file pointer is at the correct location in your file using fseek().
Class to read RDDL (Resource Directory Description Language) documents.
XML_RDDL is a class that allows the extraction of RDDL resources from an XML document.
The Resource Directory Description Language is an extension of XHTML Basic 1.0 with an added element named resource. This element serves as an XLink to the referenced resource, and contains a human-readable description of the resource and machine readable links which describe the purpose of the link and the nature of the resource being linked to. The nature of the resource being linked to is indicated by the xlink:role attribute and the purpose of the link is indicated by the xlink:arcrole attribute.
For more information on RDDL, visit the RDDL website.
As the RDDL website contains RDDL resources embedded in the XHMTL code of the home page, it can be used in the following example.
Пример 63-1. Fetching resources from www.rddl.org
|
Creates a new instance of XML_RDDL that can be used to parse RDDL documents.
When instantiating you may specifiy RDDL and XLINK namespaces. This may change, when XML_Parser supports namespaces and XML_RDDL will be able to extract the correct namespace abbrevations.
string $rddlNamespace - abbrevation for the RDDL namespace.
string $xlinkNamespace - abbrevation for the XLink namespace.
Parses an XML or XHTML document that contains RDDL resources and stores information about them for retrieval by the other methods.
string $input - input to parse, either a string or a file. If it's a file, you have to set $isFile to true.
boolean $isFile - flag to indicate whether the $input parameter should be treated as a filename.
Returns an array containing all reources that have been found. You have to call XML_RDDL::parseRDDL() first.
array array containing all information about the specified resource or a PEAR_Error if the resource does not exist.
Gets all resources of a given nature from an RDDL document. You have to call XML_RDDL::parseRDDL() first. The nature of a resource is specified by the 'xlink:role' attribute. A nature can be a stylesheet, a DTD, a HTML document, etc. You can find a list of well known natures at http://www.rddl.org/natures/.
Пример 63-1. Getting all stylesheets from a document
|
Gets all resources of a given purpose from an RDDL document. You have to call XML_RDDL::parseRDDL() first. The purpose of a resource is specified by the 'xlink:arcrole' attribute. The purpose of a resource link determines what the link will be used for. Frequently the purpose of a link can be determined from the nature of the referenced resource. For example the purpose of an XML Schema is typically schema validation, yet a schema may be comprised of a number of included modules and even when included modules are themselves an XML Schema, the purpose is as a module. You can find a list of well known purposes at http://www.rddl.org/purposes/.
Пример 63-1. Getting all normative references
|
Gets all resources of a given language from an RDDL document. You have to call XML_RDDL::parseRDDL() first. If a resource has no xml:lang attribute, the xml:lang attribute of the root of the document is used.
Пример 63-1. Getting all english resource
|
Parser for Resource Description Framework (RDF) Site Summary (RSS) documents.
Resource Description Framework (RDF) Site Summary (RSS) documents are XML documents, that provide a lightweight multipurpose extensible metadata description and syndication format. RSS files are often used to syndicate news or headlines from portal sites (e.g. Slashdot or freshmeat.net) or weblogs.
For more information on RSS see the website of the RSS working group (http://www.purl.org/rss/).
Пример 63-1. RSS file
|
To parse the XML files that contain the RSS feeds, XML_RSS requires that the package XML_Parser is installed. However this dependency will be automatically handled by the installer during the installation phase of XML_RSS.
Since most RSS feeds are located on remote hosts, one has to ensure that the PHP configuration value "allow_url_fopen" is set to "On" before running XML_RSS.
To find out the current value of "allow_url_fopen", one can use the function ini_get(). To set a new value of "allow_url_fopen", you must modify the php.ini configuration file of PHP.
The following script fetches the latest headlines from Slashdot.org via RSS.
Пример 63-1. Fetching headlines from Slashdot
|
Get general information about current channel. This function returns an array containing the information that has been extracted from the <channel>-tag while parsing the RSS document.
array - an array of strings. The keys of the array are
'title' - name of the channel
'link' - URL to the channel site
'description' - description of the channel
Get items from RSS document. This function returns an array containing the set of items that are provided by the RSS document.
array - a two-dimensional array. Every inner array contains information about a site. Use the array key 'title' to get the article title and the key 'link' for the URL of the site.
Пример 63-1. Using getItems()
|
Get images from RSS document. This function returns an array containing the set of images that are provided by the RSS document.
array - a two-dimensional array. Every inner array contains information about an image of a site.
'title' - name of the channel
'link' - URL to the site
'url' - URL of the image
XML_Serializer serializes complex data structures like arrays or object as XML documents. This class helps you generating any XML document you require without the need for DOM.
Currently there are two ways in which XML_Serializer can be used in your applications:
use XML_Serializer's functionality to create XML documents in a specific XML application (e.g. RDF) that is being processed by an existing script)
use XML_Serializer's functionality to serialize data structures that have to be unserialized at a later point. This is possible by adding type information to all XML elements.
The package not only contains a serializer class but also a matching XML_Unserializer, which is able to virtually read any XML document and return an array or object structure that represents the data stored in the document.
There are several tutorials on XML_Serializer available, that help you get started.
Instant XML with PHP and PEAR::XML_Serializer by Harry Fuecks
Serializing XML With PHP by Vikram Vaswani
Таблица 63-1. Constants defined in Serializer.php
Name | Value | Line Number |
---|---|---|
XML_SERIALIZER_ERROR_NO_SERIALIZATION | 51 | 34 |
Таблица 63-2. Constants defined in Unserializer.php
Name | Value | Line Number |
---|---|---|
XML_UNSERIALIZER_ERROR_NO_UNSERIALIZATION | 151 | 34 |
This class can be used in two modes:
Create an XML document from an array or object that is processed by other applications.
This classes can be used to serialize any data structure in a way that it can later be unserialized again. XML_Serializer will store the type of the value and additional meta information in attributes of the surrounding tag. This meta information can later be used to restore the original data structure in PHP.
Example that uses the returnResult option to directly return the serialized XML document in the serialize() method.
In this example look at theses 3 lines.
$serializer = &new XML_Serializer($options); $foo = PEAR::raiseError('Just a test', 1234); $result = $serializer->serialize($foo); |
error_reporting(E_ALL); require_once 'XML/Serializer.php'; $options = array( XML_SERIALIZER_OPTION_INDENT => ' ', XML_SERIALIZER_OPTION_RETURN_RESULT => true ); $serializer = &new XML_Serializer($options); $foo = PEAR::raiseError('Just a test', 1234); $result = $serializer->serialize($foo); echo '<pre>'; echo htmlspecialchars($result); echo '</pre>'; |
And this is the result
<pear_error> <error_message_prefix /> <mode>1</mode> <level>1024</level> <code>1234</code> <message>Just a test</message> <userinfo /> <backtrace> <XML_Serializer_Tag> <file>pathToMypear\PEAR.php</file> <line>566</line> <function>pear_error</function> <class>pear_error</class> <type>-></type> <args> <XML_Serializer_Tag>Just a test</XML_Serializer_Tag> <XML_Serializer_Tag>1234</XML_Serializer_Tag> <XML_Serializer_Tag>1</XML_Serializer_Tag> <XML_Serializer_Tag>1024</XML_Serializer_Tag> <XML_Serializer_Tag /> </args> </XML_Serializer_Tag> <XML_Serializer_Tag> <file>pathToMyDocRoot\cvs.php.net\pear\xml_serializer\examples\serializeandreturn.php</file> <line>19</line> <function>raiseerror</function> <class>pear</class> <type>::</type> <args> <XML_Serializer_Tag>Just a test</XML_Serializer_Tag> <XML_Serializer_Tag>1234</XML_Serializer_Tag> </args> </XML_Serializer_Tag> </backtrace> <callback /> </pear_error> |
You can find the last version of this source code in the package : serializeAndReturn.php
This example shows how to create an RDF document with a few lines of code. This can also be done with mode => simplexml.
In this example look at theses 3 lines.
$serializer = new XML_Serializer($options); $result = $serializer->serialize($rdf); echo htmlentities($serializer->getSerializedData()); |
/** * @see serializeIndexedArray.php */ error_reporting(E_ALL); require_once 'XML/Serializer.php'; $options = array( "indent" => " ", "linebreak" => "\n", "typeHints" => false, "addDecl" => true, "encoding" => "UTF-8", "rootName" => "rdf:RDF", "rootAttributes" => array("version" => "0.91"), "defaultTagName" => "item", "attributesArray" => "_attributes" ); $serializer = new XML_Serializer($options); $rdf = array( "channel" => array( "title" => "Example RDF channel", "link" => "http://www.php-tools.de", "image" => array( "title" => "Example image", "url" => "http://www.php-tools.de/image.gif", "link" => "http://www.php-tools.de" ), "_attributes" => array( "rdf:about" => "http://example.com/foobar.html" ), array( "title" => "Example item", "link" => "http://example.com", "_attributes" => array( "rdf:about" => "http://example.com/foobar.html" ) ), array( "title" => "Another item", "link" => "http://example.com", "_attributes" => array( "rdf:about" => "http://example.com/foobar.html" ) ), array( "title" => "I think you get it...", "link" => "http://example.com", "_attributes" => array( "rdf:about" => "http://example.com/foobar.html" ) ) ) ); $result = $serializer->serialize($rdf); if( $result === true ) { echo "<pre>"; echo htmlentities($serializer->getSerializedData()); echo "</pre>"; } |
And this is the result
<?xml version="1.0" encoding="UTF-8"?> <rdf:RDF version="0.91"> <channel rdf:about="http://example.com/foobar.html"> <title>Example RDF channel</title> <link>http://www.php-tools.de</link> <image> <title>Example image</title> <url>http://www.php-tools.de/image.gif</url> <link>http://www.php-tools.de</link> </image> <item rdf:about="http://example.com/foobar.html"> <title>Example item</title> <link>http://example.com</link> </item> <item rdf:about="http://example.com/foobar.html"> <title>Another item</title> <link>http://example.com</link> </item> <item rdf:about="http://example.com/foobar.html"> <title>I think you get it...</title> <link>http://example.com</link> </item> </channel> </rdf:RDF> |
You can find the last version of this source code in the package : serializeRDF.php
Note : if you search how to parse (read) an RDF/RSS document, look at XML_RSS package.
This example shows how to add a DocType Declaration to the XML document
In this example look at theses 3 lines.
$serializer = new XML_Serializer($options); $result = $serializer->serialize($rdf); echo htmlentities($serializer->getSerializedData()); |
error_reporting(E_ALL); require_once 'XML/Serializer.php'; $options = array( "indent" => " ", "linebreak" => "\n", "addDecl" => true, "addDoctype" => true, "doctype" => array( 'uri' => 'http://pear.php.net/dtd/package-1.0', 'id' => '-//PHP//PEAR/DTD PACKAGE 0.1' ) ); $serializer = new XML_Serializer($options); $foo = PEAR::raiseError("Just a test", 1234); $result = $serializer->serialize($foo); if( $result === true ) { echo '<pre>'; echo htmlentities($serializer->getSerializedData()); echo '</pre>'; } |
And this is the result
<?xml version="1.0"?> <!DOCTYPE pear_error PUBLIC "-//PHP//PEAR/DTD PACKAGE 0.1" "http://pear.php.net/dtd/package-1.0"> <pear_error> <error_message_prefix /> <mode>1</mode> <level>1024</level> <code>1234</code> <message>Just a test</message> <userinfo /> <backtrace> <XML_Serializer_Tag> <file>pathToMyPear\PEAR.php</file> <line>566</line> <function>pear_error</function> <class>pear_error</class> <type>-></type> <args> <XML_Serializer_Tag>Just a test</XML_Serializer_Tag> <XML_Serializer_Tag>1234</XML_Serializer_Tag> <XML_Serializer_Tag>1</XML_Serializer_Tag> <XML_Serializer_Tag>1024</XML_Serializer_Tag> <XML_Serializer_Tag /> </args> </XML_Serializer_Tag> <XML_Serializer_Tag> <file>pathToMyDocumentRoot\cvs.php.net\pear\xml_serializer\examples\serializewithdtd.php</file> <line>24</line> <function>raiseerror</function> <class>pear</class> <type>::</type> <args> <XML_Serializer_Tag>Just a test</XML_Serializer_Tag> <XML_Serializer_Tag>1234</XML_Serializer_Tag> </args> </XML_Serializer_Tag> </backtrace> <callback /> </pear_error> |
You can find the last version of this source code in the package : serializeWithDTD.php
Class to unserialize XML documents that have been created with XML_Serializer. To unserialize an XML document you have to add type hints to the XML_Serializer options.
If no type hints are available, XML_Unserializer will guess how the tags should be treated, that means complex structures will be arrays and tags with only CData in them will be strings.
Options let you influence, how XML_Unserializer treats the parsed XML. It allows you to define, whether attributes should be parsed, whether to use associative arrays or objects for complex data types and more.
Options can be passed as an associative array to the constructor of XML_Unserializer. You may also use setOption(), or setOptions() to set one or more options after the instance of XML_Unserializer has been created.
Here is a list of all options supported by XML_Unserializer.
Таблица 63-1. XML_Unserializer options
Option | Possible values | Default | Description |
---|---|---|---|
complexType | 'array' or 'object' | 'array' | Defines, whether nested tags should be returned as associative arrays or objects |
tagAsClass | TRUE or FALSE | TRUE | Defines, whether the tag name should be used as the class name if complexType is set to 'object'. If no class with the name of the tag exists, that class defined by 'defaultClass' is used. |
defaultClass | any string | stdClass | Defines the class that is used to create objects, if the complexType option is set to 'object'. |
keyAttribute | any string or array | '_originalKey' | If the attribute specified in this option exists for a tag, the value will be used as key or property name in the parent object or array. You may also specify an associative array if you want to use differnt key attributes for different tags. In this case, the array key contains the tag name and the array vallue the corresponding attribute name. |
typeAttribute | any string | '_type' | If this attribute exists for a tag, the tag content will be converted to the specified type. Possible types are: string, integer, float, boolean, array and object |
classAttribute | any string | '_class' | If XML_Unserializer creates an object, it will be an instance of the value specified with the defaultClass option, unless the tag has the attribute specified in this option. If it is set, the classname stored in the attribute value will be used. |
parseAttributes | TRUE or FALSE | FALSE | With this option, you may tell XML_Unserializer to also parse the attributes of the tags. The next two options define how to treat the parsed attributes. |
attributesArray | FALSE or any string | FALSE | If set to false, the attributes will be treated like nested tags. If you set it to a string, a new aray will be created and stored in the parent structure using key you specified in this option |
prependAttributes | any string | '' | Allows you to specify a prefix for attribute names. |
contentName | any string | '_content' | If you decide to parse attributes or a tag contains cdata and tags, then the cdata will be stored in the index specified here. |
tagMap | associative array | array() | This allows you to map tag names to PHP classes. The names of the tags have to be in the keys and the values contain the class names to use for each tag. |
forceEnum | indexed array | array() | This allows you to specify a list of tags which will automatically be converted to an indexed array, independent of the number of repetitions of the tag. This can save you a some if conditions in your code. |
encoding | any valid encoding string | null | Defines the encoding of the original document. |
targetEncoding | any valid encoding string | null | Defines the target encoding of the resulting data. |
decodeFunction | any valid PHP callback | null | This option allows you to define a callback function or method, that will be applied to all character data and attributes in the document before they are stored in the result. This allows you to decode any decoded data in the XML or convert all content to lowercase. |
returnResult | TRUE or FALSE | FALSE | If set to TRUE XML_Unserializer::unserialize()() will return the result if the document could be unserialized instead of just TRUE. |
The following examples shows how to set options for XML_Unserializer.
Пример 63-1. Using the constructor
|
The following example shows how to set options for XML_Unserializer, if the instance already has been created.
Пример 63-2. Using setOption() and setOptions()
|
array $options - Options for the instance. Can also be set using XML_Unserializer::setOption()
Returns API version of XML_Unserializer. This may be useful to check if the needed functionality exists.
Unserialize an XML document from a string or a file.
The way the document is unserialized is influenced by the options you set in the constructor or with setOptions().
string $data - either the file name of an XML document or a string containing the XML document.
boolean $isFile - indicates whether the first parameter should is a filename (TRUE) or an XML string (FALSE).
array $options - Options to override the options that have been set previously. The options will only be used for this unserialization and then reset the the options you set before.
This method returns the result of the last unserialization. You have to call XML_Unserializer::unserialize() first.
This method will return the name of the root tag, after a document has been unserialized. This can be extremely useful when returning an array. You have to call XML_Unserializer::unserialize() first.
Options influence the behaviour of XML_Unserializer and are the most important part of XML_Unserializer.
You can use this method if you do not want to set all options in the constructor.
Options influence the behaviour of XML_Unserializer and are the most important part of XML_Unserializer.
You can use this method if you do not want to set all options in the constructor.
see XML_Unserializer::setOption() and XML_Unserializer::XML_Unserializer() on how to set options.
Translates SQL-Queries to XML-Resultsets.
XML_sql2xml takes an existing result set or a SQL statment and transforms it to an XML representation
In this tutorial, the examples refers to this database tables:
mysql> select * from bands; +----+--------------+------------+-------------+-------------+ | id | name | birth_year | birth_place | genre | +----+--------------+------------+-------------+-------------+ | 1 | The Blabbers | 1998 | London | Rock'n'Roll | | 2 | Only Stupids | 1997 | New York | Hip Hop | +----+--------------+------------+-------------+-------------+ mysql> select * from albums; +----+---------+------------------+------+-----------------+ | id | bandsID | title | year | comment | +----+---------+------------------+------+-----------------+ | 1 | 1 | BlaBla | 1998 | Their first one | | 2 | 1 | More Talks | 2000 | The second one | | 3 | 2 | All your base... | 1999 | The Classic | +----+---------+------------------+------+-----------------+ |
Let's start with an example using the default options. The new instance is bind to an DSN, so you have only to provide an SQL query. The instance fetches the result automatically; in $xmlstring you found the XML representation of the result set.
Пример 63-1. The simplest example
The content of $xmlstring based on the DB tables above is:
|
If your query result base on joined tables, a nested XML data structure can represent how the DBMS joins the tables. To enable or to disable this behavoir use setOptions() with the option key 'nested'. The default value is TRUE - the nesting is enabled.
Пример 63-2. Nested result set
The generated XML output in $xmlstring:
|
If you disable the nesting, the XML structure of rows is flat.
Пример 63-3. Unnested result sets
XML output:
|
There are three ways to pass the data for transforming to the object:
with a direct query
This way you see in the first part of the introduction already.
with an existing DB_result object
If you need the full power of the PEAR::DB or PEAR::MDB API, you should choose this way.
with an array
This is not directly an SQL to XML transformation; if you pass an indice array to the instance, the keys of the array are transformed into XML tags, their values into the tag content. This feature his helpful for adding data to an XML transformed result set.
This behavoir does connecting to the DBMS, quering and fetching he result automatically. XML_sql2xml requires an valid DSN as construtor parameter. The query has to be passed to the getXML() or add() method.
Take a look into the first part of the introduction for examples.
PEAR::DB and PEAR::MDB return the result set of a query as DB_result object. You have to provide a DB_common instance to the construtor and the DB_result instance to getXML() or add().
Пример 63-1. Passing a DB_Result object
|
The XML output in $xmlstring is equal to the example in "The typical using".
This way is the only one, if you want to benefit from all the features of the database APIs.
If you pass an nested array to getXML() or add(), it will be transformed into an XML document.
Пример 63-2. Passing an array
The XML output in $xmlstring:
|
You can call add() several result sets to XML document. Just call the method for every result set; if you have added all result sets, call getXml() without any arguments to get the XML document.
Пример 63-3. Adding result sets
|
The XPath support was introduced to provide an access to the result set after doing the SQL query. This allows further proccessing of the result set without quering the database again.
XPath is a W3-Standard and for further information about that, ask your preferred XSL/XML book, or http://www.w3.org/.
XML_sql2xml provides two functions for querying the result set: getXpathValue() and getXpathChildValues(). Both expect a XPath query and return the result as string or array.
Пример 63-1. getXpathValue
$xmlstring contains:
|
Пример 63-2. getXpathChildValues
$xmlstring contains:
|
You can insert an XPath query into an SQL query. In the example, first a SQL query is done, in the second a SQL query done again - but the parameter for bandsID is taken from the XPath expression in the curly braces. This expression is processed on the result set of the first SQL query.
Пример 63-3. Mixed query
|
The Constructor can take a Pear::DB Data Source Name (DSN) and will then connect to the database; or a PEAR::DB object handle, if you already connected the database before. Providing sql-strings will not work.
If you provide only a DSN, you have to add a DB_result object, SQL statment or an array later.
The $root parameter is used, if you want to provide another name for your root-tag than <root>. If you give an empty string (""), there will be no root element created here, but only when you add a resultset, array or SQL Statment. And the first tag of this result is used as the root tag.
mixed $dsn - PEAR::DB "data source name" or DB_common object
string $root - the name of the XML-root element.
Пример 63-1. Using XML_sql2xml()
|
General method for adding new result sets to the object. Give a SQL statment, a PEAR::DB_result object or an array as input parameter and the method calls the appropriate method for this input.
string $resultset - SQL statment, an DB_result object or an array
mixed $params - parameters for the following functions
XML_sql2xml::addResult(), XML_sql2xml::addSql(), XML_sql2xml::addArray(), XML_sql2xml::addXmlFile()
Adds the content of a XML file on the same level as a normal result set (mostly just below <root>).
string $file - file name
mixed $xpath - either a string with the XPath expression or an array with the keys "xpath"=>XPath expression and "root"=>tag/subtag/etc, which are the tags to be inserted before the result.
Adds the content of a xml-string on the same level as a normal result set (mostly just below <root>)
string $string - XML string
mixed $xpath - either a string with the XPath expression or an array with the keys "xpath"=>XPath expression and "root"=>tag/subtag/etc, which are the tags to be inserted before the result.
Adds an aditional result set generated from an SQL statement. The function executes the statment and transform it into XML. You have to pass an DSN to the constructor.
Adds an aditional result set generated from an array. The XML represents the nesting of the array.
Returns an XML string with a XML representation of the result set. The result set can be directly provided here, or if you need more than one in your XML, then you have to provide each of them with add() before you call getXML(), but the last one can also be provided here.
Returns an XML DomDocument object with a XML representation of the result sets. The result set can be directly provided here, or if you need more than one in your XML, then you have to provide each of them with add() before you call getXMLObject(), but the last one can also be provided here.
array $options - array of options. The array key defines the option to set. Avaible options are:
boolean $options['nested'] - if TRUE the result of an join query will be nested. The default value is FALSE.
boolean $options['tagNameRow'] - name for the row mark up tag. Default is >row<
boolean $options['tagNameResult'] - name for the result-set mark up tag. Default is >result<
constant $delete - the old sub options should be deleted
Sets the encoding for the db2xml transformation. The $encoding_from value depends on your database system; check the DBMS manual which encoding your system use to deliever result sets.
The $encoding_to sets the charset for the created XML document.
string $encoding_from - encoding to transform from
string $encoding_to - encoding to transform to
Package to statistically analyze an XML document.
XML_Statistics is a package that allows you to analyze XML documents, which can be files or strings.
XML_Statistics is able to count tags, attributes, processing instructions, external entities and cdata blocks. Furthermore you can apply filters so you are able to count only the tags in a specific depth or only the attributes of a specific tag.
The following examples shows how XML_Statistics can be used to analyze a document.
Пример 63-1. Basic example
|
Analyzes an XML document by reading from a file. You have to analyze a document before you can extract any statistical information.
Analyzes an XML document directly from a string. This can be useful if your documents are created on the fly by any other application. You have to analyze a document before you can extract any statistical information.
Counts how often a certain tag is used in the document. If no tagname is specified ot will count the total number of tags.
Thru nesting a tag can be at a certain depth. The root tag is at depth zero. By counting the amount of tags in a depth you can count the number of recordsets in an XML document.
Counts how often a certain processing instruction (e.g. <?PHP) is used in the document. The target is the 'language' of the processing instruction. You only need to specify the name, without the leading question mark. If no target is specified it will count the total number of processing instructions.
Counts how often a certain external is used in the document. If no name is specified ot will count the total number of external entities.
Counts how often a certain attribute is used in the document. If no attribute is specified ot will count the total number of tags.
With the second parameter you may limit the search to a special tag.
string $attribute - if no attribute name is supplied, all attributes are counted
string $tagname - this allows you to limit your search to a tag
integer occurences of the attribute or a PEAR_Error if the attribute could not be found.
This is influenced by the 'ignoreWhitespace' option. Furthermore a new chunk is counted when the parser find a linebreak or internal entity.
XML Transformations in PHP.
With the XML Transformer class one can easily bind PHP functionality to XML tags, thus transforming the input XML tree into an output XML tree without the need for XSLT. Single XML elements can be overloaded with PHP functions, methods and static method calls, XML namespaces can be registered to be handled by PHP classes.
Constructor of the XML_Transformer class. It can be passed an associative array that may have the following keys:
caseFolding: If TRUE, XML attribute and element names will be case-folded.
caseFoldingTo: May be either CASE_UPPER or CASE_LOWER and sets the target case for the case-folding.
debug: May be either TRUE or FALSE, thus enabling or disabling complete debugging information. May also be an array containing the names of elements to which the generated debugging information shall be limited. The special keywords "&CDATA" and "&RECURSE" may be used to enable debugging information for CDATA and recursion events.
recursiveOperation: If TRUE, the transformation will continue recursively until the XML contains no more overloaded elements. Can be overrided on a per-element basis.
overloadedElements: Associative array with pre-defined set of overloaded elements.
overloadedNamespaces: Associative array with pre-defined set of overloaded elements.
Overloads an XML element and binds its opening and closing tags to a PHP callback. A PHP callback can be one of the following:
A PHP Function.
A PHP Method on an object.
A static PHP Method.
The optional fourth parameter can be used to override the global setting for recursive operation.
Overloads an XML Namespace and binds all its elements to a PHP object, that must provide startElement($element, $attributes)() and endElement($element, $cdata)() methods.
If the PHP object provides a initObserver($namespacePrefix, $transformer)() method it is automatically called with the registered namespace prefix and a reference to the XML_Transformer object.
Starts the transformation, if it has not yet been started, for instance by the constructor.
Enables or disables debugging to error.log.
The parameter may be either TRUE or FALSE, thus enabling or disabling complete debugging information. May also be an array containing the names of elements to which the generated debugging information shall be limited. The special keywords "&CDATA" and "&RECURSE" may be used to enable debugging information for CDATA and recursion events.
Build XML documents using a tree representation
The XML_Tree package allows one to build XML data structures using a tree representation, without the need for an extension like DOMXML.
string $name - name of root element
string $content - data between the opening and closing tag
array $attributes - additional attributes for the tag. The attribute name is represented as the array key and the attribute value as entry for the key.
Inserts a child or tree into the tree in the path $path on position $pos and maintains namespace integrity
array $path - path to parent of child to insert
integer $pos - position of child to be inserted in its parents children-list
mixed $child - child-node (by XML_Tree, XML_Node or Name)
string $content - content (text) for new node
array $attributes - attribute-hash for new node
array $path - path to parent of child to remove
integer $pos - position of child in parents children-list
Collection of often needed methods that help you creating XML documents.
XML_Util is a utility class that helps you working with (and especially creating) XML documents.
All methods of XML_Util can be called statically, that means you do not have to instantiate an XML_Util object to use the provided methods.
The funcionality of XML_Util ranges from validating an XML tag name (as there are strict rules for tag and attribute names) to the creation of namespaced XML tags.
The following examples shows how some of the methods of XML_Util have to be used.
Пример 63-1. Some basic examples
|
array $attributes - assoc array containg attributes
boolean $sort - whether to sort the attributes alphabetically
boolean $multiline - whether to display the attributes on more than one line (makes it easier to read)
string $indent - indentation characters, only used when multiline is set to TRUE
string $linebreak - linebreak character, only used when multiline is set to TRUE
integer $entities - define, which entities should be replaced in the attribute values. One of XML_UTIL_ENTITIES_NONE, XML_UTIL_ENTITIES_XML, XML_UTIL_ENTITIES_XML_REQUIRED or XML_UTIL_ENTITIES_HTML
This method collapses empty tags like <foo></foo> with the short version <foo/> by applying a regular expression. This is especially helpful when dealing with XHTML-documents, as there is an important difference in rendering these tags in the browser.
This method has been added in XML_Util 1.1.0.
string $string - string, in which empty tags should be collapsed
integer $mode - collapse all empty tags (XML_UTIL_COLLAPSE_ALL) or only XHTML tags (XML_UTIL_COLLAPSE_XHTML_ONLY).
string $qname - qualified tag name
array $attributes - assoc array with attributes
string $content - string content of the tag
string $namespaceUri - URI of the namespace if xmlns attribute should be added
integer $replaceEntities - whether to replace XML entities in content, embedd it in a CData section or leave it untouched. Possible values are FALSE, XML_UTIL_REPLACE_ENTITIES or XML_UTIL_CDATA_SECTION.
array $tag - array containing information about the tag
integer $replaceEntities - whether to replace XML entities in content, embedd it in a CData section or leave it untouched. Possible values are FALSE, XML_UTIL_REPLACE_ENTITIES or XML_UTIL_CDATA_SECTION.
Пример 63-1. Creating a tag with XML_Util::createTagFromArray()
|
create a start element with attributes, namespace and adds 'xmlns' if needed. (<pear foo="bar">)
string $qname - qualified tag name
array $attributes - assoc array with attributes
string $namespaceUri - URI of the namespace if xmlns attribute should be added
Creates a CData section, by embedding the data in <!CDATA[ and ]]>. If you use a CData section inside an XML document, entities do not have to be replaced in this sections.
string $root - root tag
mixed $uri - URI of the document type definition or array containing the public id and the URI of the DTD
mixed $internalDtd - internal definitions
string $version - XML version
string $encoding - XML encoding
boolean $standalone - whether document is standalone
Checks, whether a string is a valid XML name. In XML the names of tags and attributes must follow strict rules. This method can be used to validate the names you are using.
In XML documents you are not allowed to use & and <. The have to be replaced with their respective entities. This method does this for you and furthermore replaces all other predefined XML entities.
This is the reverse function to XML_Util::replaceEntities()(). It replaces all XML (or HTML) entities in a string by their corresponding characters. This can be useful when working with XML documents without using an XML parser.
This method has been added in XML_Util 1.0.0.
Внимание |
This documention is outdated, it refers to an version older then 18 months. Please ask the maintainer of this package to update this documentation. |
Внимание |
Этот модуль является ЭКСПЕРИМЕНТАЛЬНЫМ. Это означает, что поведение его функций, имена функций и ВСЕ остальное может быть изменено в будущем без каких-либо уведомлений. Вы можете использовать этот модуль только на свой страх и риск. |
ImageMagick is a robust collection of tools and libraries to read, write, and manipulate an image in many image formats (over 68 major formats) including popular formats like TIFF, JPEG, PNG, PDF, PhotoCD, and GIF. With ImageMagick you can create images dynamically, making it suitable for Web applications. You can also resize, rotate, sharpen, color reduce, or add special effects to an image and save your completed work in the same or differing image format.
Замечание: The above text is from the ImageMagick Website (http://www.imagemagick.org/), therefore not everything does apply to this extension at the moment, but it will some time in the future. Hopefully. And the link above is also a great source, if you don't understand everything here.
imagick went through a major upgrade with version 0.9 and is not backwards compatible to older versions. You should look at the examples, which come with the package, for some documentation about the new API.
Read the INSTALL file, which comes with the package. Or just use the PEAR installer with "pear install imagick".
Any questions about the extension should be asked on one of the PEAR Mailing lists.
Внимание |
Этот модуль является ЭКСПЕРИМЕНТАЛЬНЫМ. Это означает, что поведение его функций, имена функций и ВСЕ остальное может быть изменено в будущем без каких-либо уведомлений. Вы можете использовать этот модуль только на свой страх и риск. |
Satellite is deprecated. It is suggested that you use Universe (http://universe-phpext.sourceforge.net/) and not Satellite.
The Satellite extension is used for accessing CORBA objects. You will need to set the idl_directory= entry in php.ini to a path where you store all IDL files you use.
See the Satellite README file for details about installing Satellite.
Внимание |
Эта функция является ЭКСПЕРИМЕНТАЛЬНОЙ. Это означает, что ее поведение, имя и ВСЕ остальное может быть изменено в будущем без каких-либо уведомлений. Вы можете использовать эту функцию только на свой страх и риск. |
This class provides access to a CORBA object. The ior parameter should be a string containing the IOR (Interoperable Object Reference) that identifies the remote object.
Пример 1. Sample IDL file
|
Пример 2. PHP code for accessing MyInterface
|
Внимание |
Эта функция является ЭКСПЕРИМЕНТАЛЬНОЙ. Это означает, что ее поведение, имя и ВСЕ остальное может быть изменено в будущем без каких-либо уведомлений. Вы можете использовать эту функцию только на свой страх и риск. |
This class represents the enumeration identified with the id parameter. The id can be either the name of the enumeration (e.g "MyEnum"), or the full repository id (e.g. "IDL:MyEnum:1.0").
Пример 1. Sample IDL file
|
Пример 2. PHP code for accessing MyEnum
|
Внимание |
Эта функция является ЭКСПЕРИМЕНТАЛЬНОЙ. Это означает, что ее поведение, имя и ВСЕ остальное может быть изменено в будущем без каких-либо уведомлений. Вы можете использовать эту функцию только на свой страх и риск. |
This class represents the structure identified with the id parameter. The id can be either the name of the struct (e.g "MyStruct"), or the full repository id (e.g. "IDL:MyStruct:1.0").
Пример 1. Sample IDL file
|
Пример 2. PHP code for accessing MyStruct
|
Внимание |
Эта функция является ЭКСПЕРИМЕНТАЛЬНОЙ. Это означает, что ее поведение, имя и ВСЕ остальное может быть изменено в будущем без каких-либо уведомлений. Вы можете использовать эту функцию только на свой страх и риск. |
This function returns TRUE if an exception has been caught.
Пример 1. Sample IDL file
|
Пример 2. PHP code for handling CORBA exceptions
|
Внимание |
Эта функция является ЭКСПЕРИМЕНТАЛЬНОЙ. Это означает, что ее поведение, имя и ВСЕ остальное может быть изменено в будущем без каких-либо уведомлений. Вы можете использовать эту функцию только на свой страх и риск. |
Return a repository id string. (E.g. "IDL:MyException:1.0".) For example usage see satellite_caught_exception().
Внимание |
Эта функция является ЭКСПЕРИМЕНТАЛЬНОЙ. Это означает, что ее поведение, имя и ВСЕ остальное может быть изменено в будущем без каких-либо уведомлений. Вы можете использовать эту функцию только на свой страх и риск. |
Return an exception struct. For example usage see satellite_caught_exception().
Внимание |
Этот модуль является ЭКСПЕРИМЕНТАЛЬНЫМ. Это означает, что поведение его функций, имена функций и ВСЕ остальное может быть изменено в будущем без каких-либо уведомлений. Вы можете использовать этот модуль только на свой страх и риск. |
This module provide additional session save handler for session module using PostgreSQL as a storage. user session save handler may be used, but this module is written in C. Therefore, this module is roughly 2 times faster than save handler written in PHP script.
Fail-over and load balance is planned to be implemented, but they are not available now.
Замечание: There will be functions for this module, but it is not available now.
This module works only under UNIX like OS.
short installation note:
You need at least PHP 4.1, PostgreSQL 7.1 and MM 1.1.3
Untar the tar.gz archive into php4/ext (Latest official releases can be found at SourceForge PHP Form Extension Project)
If the new directory is now called something like session_pgsql. You should name it to session_pgsql (except you only want to build it as self-contained php-module)
run ./buildconf in php4
run configure with --with-session-pgsql (and your other options)
make; make install
that's it.
PostgreSQL session save handler is still under development. Refer to README file in source distribution for configuration details.
I have at the moment not very much time to further develop this extension. I will implement more and more features in the near future.
If you have comments, bug fixes, enhancements or want to help developing this, you can drop me a mail at yohgaki@php.net. Any help is very welcome.
This module allows use of the SPPLUS Payment System of the Caisse d'Epargne (a French Bank).
Замечание: You will need to get the new kit_php for spplus. Feel free to contact us if you can't get it.
This module only works under *nix type operating systems (for now).
A short installation note:
You need at least PHP 4.1.0 and SPPLUS v.3
Just type 'pear install spplus' in your console.
More features will be implemented in the near future.
If you have comments, bug fixes, enhancements or want to help develop this module, you can drop nicos an email at nicos@php.net.
HIVE: All information for read only. Please respect copyright! |