CodeIgniter предоставляет неплохие возможности по обработке ошибок, но мне они показались недостаточными по следующим причинам:
Будем это исправлять =)
Указываем обработчик исключений в файле /system/codeigniter/CodeIgniter.php
рядом со строчкой
теперь при возникновении исключения будет вызываться метод _exception_handler2 из файла /system/codeigniter/Common.php.
А вот собственно и сам метод:
Для того чтобы админстратор получал уведомление о ошибках на сайте на почтовый ящик, необходимо в файле /system/application/config/config.php указать почтовый адрес администратора:
Если вы не хотите чтобы сообщения отсылались — не указывайте этот параметр или оставьте его пустым.
Расширяем базовый класс Exceptions — в директории /system/application/libraries/
создаем файл MY_Exceptions.php со следующим содержимым:
Не забывайте. что для включения механизма ведения логов необходимо в файле /system/application/config/config.php указать у параметра log_threshold значением '1'.
Вы можете скачать исходники (Файлы CodeIgniter.php и Common.php от CodeIgniter 1.7.2)
Код довольно простой — думаю что все ясно по исходникам.
Если все таки вопросы возникнут — с удовольствием отвечу в комментариях.
В комментариях Mordred посоветовал использовать хуки вместо того чтобы править файлы ядра для вызова кода установки обработчика исключений и самого обработчика — спасибо за совет, я так и поступил.
Для начала надо включить механизм куков, для этого в файле /system/application/config/config.php параметр enable_hooks устанавливаем в TRUE:
Затем устанавливаем сам хук в файле /system/application/config/hooks.php пишем:
Данный код означает что при старте системы буд��т вызыван метод addExceptionHandler из файла /system/application/hooks/exception_hook.php. Вот содержимое этого файла:
В итоге файлы ядра фреймворка остаются нетронутыми.
Скачать новые исходники можно здесь.
Заодно были сделаны небольшие доработки — если ошибка возникала до загрузки контроллера — не срабатывала отсылка уведомлений админу, так как нужные классы для этого загружены не были, теперь стоит проверка и если нужный класс не загружен, то загружаем тогда его, плюс правки по мелочи.
Оригинал статьи
- отсутствует возможность обработки исключений
- отсутствует возможность уведомлять администратора сайта о возникающих ошибках через почту
- довольно скудная информацию о возникающих ошибках (в фреймворке с которым я работал раньше текст ошибки дополняется дампом глобальных переменных, что очень сильно облегчает процесс отладки, хотелось бы подобную схему увидеть и в CodeIgniter)
Будем это исправлять =)
Обработка исключений (см. ниже вариант без правки файлов ядра)
Указываем обработчик исключений в файле /system/codeigniter/CodeIgniter.php
set_exception_handler('_exception_handler2');
рядом со строчкой
set_error_handler('_exception_handler');
теперь при возникновении исключения будет вызываться метод _exception_handler2 из файла /system/codeigniter/Common.php.
А вот собственно и сам метод:
/**
* Обработчик исключений
*
*/
function _exception_handler2($errstr)
{
$error =& load_class('Exceptions');
// Выводим текст об исключении на экран
echo $error->show_error('error', nl2br($errstr));
// Should we log the error? No? We're done...
$config =& get_config();
if ($config['log_threshold'] == 0)
{
return;
}
// Пишем сообщение в лог
$error->log_exception('Exception', $errstr, '', '');
exit;
}
Уведомление по почте и дополнительная информация по ошибкам
Для того чтобы админстратор получал уведомление о ошибках на сайте на почтовый ящик, необходимо в файле /system/application/config/config.php указать почтовый адрес администратора:
/* |-------------------------------------------------------------------------- | Уведомление администратора об ошибках на сайте |-------------------------------------------------------------------------- | | Если вы хотите чтобы администратору приходили письма о возникающих ошибках и исключениях | Укажите у следующего параметра значением адрес почтового ящика администратора | */ $config['log_to_email'] = 'admin@site.ru';
Если вы не хотите чтобы сообщения отсылались — не указывайте этот параметр или оставьте его пустым.
Расширяем базовый класс Exceptions — в директории /system/application/libraries/
создаем файл MY_Exceptions.php со следующим содержимым:
class MY_Exceptions extends CI_Exceptions
{
/**
* Exception Logger
*
* Метод заменяет базовый добавляя возможности
* отсылать сообщению администратору сайта о ошибках
* и выводить дополнительную информацию в лог
*
* @access private
* @param string the error severity
* @param string the error string
* @param string the error filepath
* @param string the error line number
* @return string
*/
function log_exception($severity, $message, $filepath, $line)
{
// Отсылаем сообщение администратору сайта
$this->adminmail($message);
$severity = ( ! isset($this->levels[$severity])) ? $severity : $this->levels[$severity];
// Дополняем текст сообщения дампам переменных окружения
$message .= "\n" . $this->GetGlobalVariables() . $filepath.' '.$line . "\n\n";
log_message('error', 'Severity: '.$severity.' --> '.$message, TRUE);
}
/**
* 404 Page Not Found Handler
*
* Метод дополняет базовый возможностю отсылать администратору сообщение
* в случае возникновения ошибки
*
* @access private
* @param string
* @return string
*/
function show_404($page = '')
{
// Отсылаем сообщение
$message = '404 Page Not Found --> '.$page;
$this->adminmail($message);
parent::show_404($page);
}
/**
* Возвращает дамп переменных окружения
*
* @return string дамп переменных окружения
*/
function GetGlobalVariables()
{
$content = 'REMOTE_ADDR = '.$_SERVER["REMOTE_ADDR"]."\n";
if (isset($_SERVER["HTTP_REFERER"]))
{
$content .= 'HTTP_REFERER = '.$_SERVER["HTTP_REFERER"]."\n";
}
$content .= 'USER_AGENT = '.$_SERVER["HTTP_USER_AGENT"]."\n";
$content .= '$_SERVER[\'REQUEST_URI\'] = ';
$content .= var_export(@$_SERVER['REQUEST_URI'], true);
$content .= "\n".'$_GET = ';
$content .= var_export(@$_GET, true);
$content .= "\n".'$_POST = ';
$content .= var_export(@$_POST, true);
$content .= "\n";
return $content;
}
/**
* Метод отсылает сообщение о ошибки на почту администратору
*
* @return
* @param object $message
*/
function adminmail($message)
{
$CI =& get_instance();
// Если конфиг не загружен - загружаем
if (!isset($CI->config))
{
$CI->config = & load_class('Config');
}
// Если загрузчик не загружен - загружаем
if (!isset($CI->load))
{
$CI->load = & load_class('Loader');
}
// Загружаем класс email
if (!isset($CI->email))
{
$CI->email = & load_class('Email');
}
// Для почтового класса необходим класс Language
if (!isset($CI->lang))
{
$CI->lang = & load_class('Language');
}
// Почтовый адрес администратора
$email = $CI->config->item('log_to_email');
// Если адрес не указан - ничего не делаем
if (!strlen($email))
{
return;
}
// Отсылаем
$CI->email->from('noreply');
$CI->email->to($email);
$CI->email->subject('Возникла ошибка на сайте');
$CI->email->message($message);
$CI->email->send();
}
}
Не забывайте. что для включения механизма ведения логов необходимо в файле /system/application/config/config.php указать у параметра log_threshold значением '1'.
Вы можете скачать исходники (Файлы CodeIgniter.php и Common.php от CodeIgniter 1.7.2)
Код довольно простой — думаю что все ясно по исходникам.
Если все таки вопросы возникнут — с удовольствием отвечу в комментариях.
UPDATE: Добавление обработчика исключений с помощью хуков
В комментариях Mordred посоветовал использовать хуки вместо того чтобы править файлы ядра для вызова кода установки обработчика исключений и самого обработчика — спасибо за совет, я так и поступил.
Для начала надо включить механизм куков, для этого в файле /system/application/config/config.php параметр enable_hooks устанавливаем в TRUE:
$config['enable_hooks'] = TRUE;
Затем устанавливаем сам хук в файле /system/application/config/hooks.php пишем:
$hook['pre_system'] = array(
'class' => '',
'function' => 'addExceptionHandler',
'filename' => 'exception_hook.php',
'filepath' => 'hooks'
);
Данный код означает что при старте системы буд��т вызыван метод addExceptionHandler из файла /system/application/hooks/exception_hook.php. Вот содержимое этого файла:
if (! defined('BASEPATH')) exit('No direct script access allowed');
/**
* Установка обработчика исключений
*
*/
function addExceptionHandler()
{
set_exception_handler('_exception_handler2');
}
/**
* Обработчик исключений
*
*/
function _exception_handler2($errstr)
{
$error =& load_class('Exceptions');
$error->adminmail('1');
// Выводим текст об исключении на экран
echo $error->show_error('error', nl2br($errstr));
// Should we log the error? No? We're done...
$config =& get_config();
if ($config['log_threshold'] == 0)
{
return;
}
// Пишем сообщение в лог
$error->log_exception('Exception', $errstr, '', '');
exit;
}
В итоге файлы ядра фреймворка остаются нетронутыми.
Скачать новые исходники можно здесь.
Заодно были сделаны небольшие доработки — если ошибка возникала до загрузки контроллера — не срабатывала отсылка уведомлений админу, так как нужные классы для этого загружены не были, теперь стоит проверка и если нужный класс не загружен, то загружаем тогда его, плюс правки по мелочи.
Оригинал статьи
