Смекни!
smekni.com

Учебник php (стр. 21 из 26)

trigger_error
Генерация ошибки.

Синтаксис :
void trigger_error(string error_msg [, int error_type])

Явно вызывает функцию, установленную для обработки ошибок, и обычно используется в паре с обработчиком ошибок. Функция способна генерировать только пользовательские типы ошибок ( семейство констант E_USER), и по умолчанию, если не указан тип ошибки error_type, он считается E_USER_NOTICE.

Возможно конструировать сложные конструкции генерации и обработки ошибок и исключительных ситуаций.

if(assert($divisor == 0)) trigger_error ("Нельзяделитьна 0 ", E_USER_ERROR);

user_error
Синонимфункцииtrigger_error().

Синтаксис :
void user_error(string error_msg [, int error_type])

Установка пользовательского обработчика ошибок

set_error_handler
Установка пользовательского обработчика ошибок.

Синтаксис :
string set_error_handler(string error_handler)

Функция возвращает имя функции, ранее определенной в качестве обработчика ошибок (или FALSE при ошибке), и устанавливает, в качестве нового обработчика, функцию с указанным в аргументе error_handler именем.

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

Функция, устанавливаемая в качестве обработчика ошибок, должна принимать пять параметров (три последних являются дополнительными и могут не обрабатываться):

· код ошибки

· строку, описывающую ошибку

· имя сценария, в котором произошла ошибка

· номер строки сценария, содержащей ошибку

· контекст (массив, содержащий значения переменных, в момент возникновения ошибки)

<?// определить константы пользовательских ошибокdefine(FATAL, E_USER_ERROR);define(ERROR, E_USER_WARNING);define(WARNING, E_USER_NOTICE); // установить, какие ошибки должны обрабатываться в сценарииerror_reporting (FATAL | ERROR | WARNING); // пользовательскийобработчикошибокfunction myErrorHandler($errno,$errstr,$errfile,$errline) { switch ($errno) { case FATAL: echo "<b>Критическаяошибка</b> [$errno] $errstr<br>&bsol;n"; echo "встроке: $errline файла:".$errfile; echo ", PHP ".PHP_VERSION." (".PHP_OS.")<br>&bsol;n"; echo "Aborting...<br>&bsol;n"; exit -1; break; case ERROR: echo "<b>Ошибка</b> [$errno] $errstr<br>&bsol;n"; break; case WARNING: echo "<b>Предупреждение</b> [$errno] $errstr<br>&bsol;n"; break; default: echo "Неизвестныйтипошибки: [$errno] $errstr<br>&bsol;n";}} // функция для проверки обработки ошибок// (масштабирование массиваfunction scale_by_log($vect, $scale) { if(!is_numeric($scale) || $scale <= 0)trigger_error("вычислить log(x) для x <= 0 нельзя. ", "(x = $scale)", FATAL); if(!is_array($vect)) { trigger_error("Требуетсямассив ", ERROR); return null; } for($i=0; $i<count($vect); $i++) { if(!is_numeric($vect[$i]))trigger_error("Элемент ($i) не число и егозначениемсчитается 0", WARNING); $temp[$i]=log($scale)*$vect[$i];} return $temp;} // установить пользовательский обработчик ошибок$old_error_handler=set_error_handler("myErrorHandler"); $a=array(2,3,"foo",5.5,43.3,21.11);print_r($a); $b=scale_by_log($a,M_PI); // здесь выдается предупреждениеecho "Массив, масштабированный на логарифм(Пи): ";print_r($b); $c=scale_by_log("not array",2,3); // здесьошибкаvar_dump($c); $d=scale_by_log($a, -2.5); // здесь критическая ошибка echo "Продолжение сценария...";?>

При выполнении сценария вывод будет следующим:

Array( [0] => 2 [1] => 3 [2] => foo [3] => 5.5 [4] => 43.3 [5] => 21.11)<b>Предупреждение</b> [1024] Элемент (2) не число, и его значением считается 0<br>Массив, масштабированный на логарифм(Пи): Array( [0] => 2.2894597716988 [1] => 3.4341896575482 [2] => 0 [3] => 6.2960143721717 [4] => 49.566804057279 [5] => 24.165247890281)<b>Ошибка</b> [512] Требуется массив <br>NULL<b>Критическая ошибка</b> [256] вычислить log(x) для x <=0 нельзя, (x = -2.5)<br> в строке: 37, файла E:&bsol;www&bsol;exampl.php, PHP 4.0.5 (WINNT)<br>Aborting...<br>

Не забывайте, что при установке пользовательского обработчика ошибок стандартный обработчик PHP не используется. Установки error_reporting() также не будут иметь эффекта, и пользовательский обработчик должен уметь обрабатывать все виды ошибок (значение error_reporting() можно выяснить и действовать соответсвенно). Заметьте, что код ошибки будет равен 0, если ошибка возникла в функции, вывод ошибок для которой был блокирован оператором "@".

Также помните, что завершать сценарий в обработчике необходимо явно (например, с помощью функции die()), если, конечно, в этом есть необходимость. Если обработчик ошибок завершается с помощью return, то выполнение сценария продолжается с того места, в котором возникла ошибка (то есть исполняются инструкции, которые следуют за той инструкцией, в которой возникла ошибка).

Зачем нужны сессии. Механизм работы сессий

Зачем нужны сессии?

Сессия представляет собой механизм, позволяющий хранить некоторые данные, индивидуальные для каждого пользователя (например, его имя и номер счета), между запусками сценария.

В Web-программировании есть один класс задач, который может вызвать довольно много проблем, если писать сценарий "в лоб". Речь идет о слабой стороне CGI - невозможности запустить программу на длительное время, позволив ей при этом обмениваться данными с пользователями.

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

Реализация такой схемы оказывается для Web-приложений довольно нетривиальной проблемой. Действительно, нам придется хранить все ранее введенные данные в каком-нибудь хранилище, которое должно аннулироваться, если пользователь вдруг передумает и уйдет с сайта. Для этого можно использовать функции сериализации и файлы. Однако ими мы решаем только половину проблемы: нам нужно как то привязать конкретного пользователя к конкретному временному хранилищу. Действительно, предположим, мы этого не сделали. Тогда, если в момент заполнения какой-нибудь формы одним пользователем на сайт зайдет другой и тоже попытается ввести свои данные, получится белеберда.
Все эти проблемы решаются при помощи сессий.

Механизм работы сессий

Для начала должен существовать механизм, который бы позволил PHP идентифицировать каждого пользователя, запустившего сценарий. То есть при следующем запуске PHP нужно однозначно определить, кто его запустил: тот же человек, или другой. Делается это путем присвоения клиенту так называемого уникального идентификатора сессии. Чтобы этот идентификатор был доступен при каждом запуске сценария, PHP помещает его Cookies браузера. Теперь, зная идентификатор (дальше SID), PHP может определить, в каком же файле на диске храняться данные пользователя.

Немного о том, как сохранять переменную (обязательно глобальную) в сессии. Для этого мы должны ее зарегестрировать с помощью специальной функции. После регистрации мы можем быть уверены, что при следующем запуске сценария тем же пользователем она получит то же самое значение, которое было у нее при предыдущем завершении программы. Это произойдет потому, что при завершении сценария PHP автоматически сохраняет все переменные, зарегестрированные в сессии, во временное хранилище. Конечно, можно в любой момент аннулировать переменную - вычеркнуть ее из сессии, или же уничтожить вообще все данные сессии.

Где же находиться то промежуточное хранилище, которое использует PHP? Вообще говоря, вы вольны сами это задать, написав соответствующие функции и зарегестрировав их как обработчики сессии. Впрочем, делать это не обязательно: в PHP уже существуют обработчики по умолчанию, которые хранят данные в файлах. Если вы не собираетесь создавать что-то особенное, вам они вполне подойдут.

Инициализация сессии и регистрация переменных

session_start
Эта функция инициализирует механизм сессий для текущего пользователя, запустившего сценарий.

Синтаксис :
void session_start()

· Если посетитель запускает программу впервые, у него устанавливается Cookies с уникальным идентификатором, и создается временное хранилище, ассоциированное с этим идентификатором.

· Определяется, какое хранилище связано с текущим идентификатором пользователя.

· Если в хранилище имеются какие-то переменные, их значения восстанавливаются. Точнее, создаются глобальные переменные, которые были сохранены в сессии при предыдущем завершении сценария.

Надо заметить, что если вы поставили в настройках PHP режим session.auto_start=1, то функция инициализации вызывается автоматически при запуске сценария. Так же надо следить за тем, чтобы до нашей функции не было никакого вывода в браузер - иначе PHP не сможет установить SID для пользователя.
Функция всегда возвращает true.

session_register
Указывает PHP на то, что ту или иную переменную нужно сохранить в сессии.

Синтаксис :
bool session_register(mixed name [, mixed name1, ...])

Функция принимает в параметрах одно или несколько имен переменных (имена задаются в скобках, без знака $ слева), регистрируют их в текущей запущенной сессии и возвращает true, если регистрация прошла успешно.

Повторная запись одной переменной в сессии не приведет к ошибке.

<?session_start();session_register("count");$count=@$count+1;?><h2>Счетчик</h2>В текущей сессии работы с браузером вы открыли эту страницу<?=$count?> раз(а). Закройте браузер, чтобы обнулить счетчик.</body>

Имя группы сессии

Надо отметить, что на одном и том же сайте могут существовать сразу несколько сценариев, которые нуждаются в услугах поддержки сессий PHP. Они "ничего не знают" друг о друге, поэтому временные хранилища для сессий должны выбираться не только на основе идентификатора пользователя, но и на основе того, какой из сценариев запросил обслуживание сессии.
Для наглядности рассмотрим пример:

Пусть разработчик А написал сценарий счетчика. Он использует переменную $count, и не имеет никаких проблем. До тех пор, пока разработчик В, ничего не знающий о сценарии А, не создал систему статистики, которая тоже использует сессии. Самое ужасное, что он также регистрирует переменную $count, не зная о том, что она уже занята. В результате, как всегда, страдает пользователь: запустив сначало сценарий разработчика В, а потом - А, он видит, что данные счетчиков перемешались.

Нам нужно как-то разграничить сессии, принадлежащие одному сценарию, от сессии, принадлежащих другому. К счастью, разработчики PHP предусмотрели такое положение вещей. Мы можем давать группам сессии непересекающиеся имена, и сценарий, знающий имя своей группы сессии, сможет получить к ней доступ. Вот теперь-то разработчики А и В могут оградить свои сценарии от проблем с пересечением имен переменных. Достаточно в первой программе указать PHP, что мы хотим использовать группу с именем, например, sesA, а во второй - sesB.