Ошибка CodeIgniter 2.1 с show_404() и 404_override
Я уже давно работаю с CodeIgniter, и сейчас я делаю проект для клиента, которому нужна пользовательская страница 404. Все в порядке, а 404_override
отлично работает.
Моя проблема возникает, когда посетитель пытается получить доступ к статье, которая не существует. Я бы хотел вызвать функцию show_404()
, но это показывает мне страницу "out of box"
404, а не та, что написана в 404_override.
Я видел некоторые исправления для более старых версий, но я не могу заставить его работать в 2.1. Поэтому, если кто-нибудь может мне помочь, я был бы очень благодарен.
Ответы
Ответ 1
Перенаправление является самым чистым; загрузка представления тоже может работать.
Проблема в том, что show_404() обычно называется ПОСЛЕ того, как ваш контроллер уже загружен (что-то должно было показать, что он показывает 404). CI не любит загружать второй контроллер в этот момент, что является основным препятствием.
Ваш лучший вариант, вероятно, заключается в расширении функции show_404() класса Exceptions для перенаправления на ваш маршрут 404. Без переадресации вы застрянете в показе представления или что-то, что вам известно, имеет все "дополнительные данные", необходимые для вызова 404 (или, я думаю, вы также можете загрузить его в классе "Исключения" ). Это может стать очень сложным в некоторых динамических представлениях.
Вам явно нужно что-то более продвинутое, чем просто редактирование шаблона 404 в папке с ошибками. У меня были проблемы с попыткой доступа к get_instance() из этого файла, так как иногда он загружался до создания контроллера. Поэтому будьте осторожны, если вы попробуете это;)
Обновление: Здесь приведен рабочий пример расширения функции show_404() для загрузки представления
<?php
// application/core/MY_Exceptions.php
class MY_Exceptions extends CI_Exceptions {
public function show_404()
{
$CI =& get_instance();
$CI->load->view('my_notfound_view');
echo $CI->output->get_output();
exit;
}
}
Ответ 2
Моим быстрым подходом к решению проблемы является создание функции в файле с автозагрузкой в проекте, над которым я работаю. Этот помощник просто перенаправляет на пользовательскую страницу 404. Поэтому я просто вызываю show_my_404()
вместо show_404()
function show_my_404(){
//Using 'location' not work well on some windows systems
redirect('controller/page404', 'location');
}
Ответ 3
function show_404($page = '', $log_error = TRUE)
{
if ($log_error)
{
log_message('error', '404 Page Not Found --> '.$page);
}
redirect(base_url().index_page().'/controller/error_page');
//OR
//redirect('SOME URL');
exit;
}
Ответ 4
Я искал одно и то же, но нашел довольно длинные решения, такие как создание собственного контроллера ошибок и класса исключений или просто перенаправление на страницу 404 (что не очень хорошо семантически).
Итак, я немного изучил, как CI называет маршрут "404_override" внутренне. Вот решение, которое я придумал:
// Override show_404 method
function show_404(){
// Load Router and Core classes.
$RTR =& load_class('Router', 'core');
// Get class and method for 404 from routes.php
$x = explode('/', $RTR->routes['404_override']);
$class = $x[0];
$method = (isset($x[1]) ? $x[1] : 'index');
// Get current class and method for callback
$callback_class = $RTR->fetch_class();
$callback_method = $RTR->fetch_method();
// Can also log here, using callback class and method.
// Create object for callback
$CI = new $callback_class;
call_user_func_array(array(&$CI, $method), array_slice(array($class,$method), 2));
} // End!
Добавьте эту функцию в файл system/core/CodeIgniter.php.
Это переопределит функцию show_404. Вы можете вызвать его из своих контроллеров, и он будет вызывать маршрут "404_override", указанный в файле route.php.