Обработка ошибки 404

  • Содержание

Существует несколько способов обработать ошибку 404 в контроллере CodeIgniter’a. Рассмотрим их достоинства и недостатки.

Вариант 1

Используем роуты. В файле routes.php перечислим всевозможные способы переадресации. В конец добавим строчку

$route["(:any)"] = 'error_handler';

Метод довольно простой, однако сообщить роботу, что эта страница не найдена, не удастся. Кроме того, не всегда возможно перечислить все правила в массиве роута.

Вариант 2

Расширим класс роута. Предлагаю скрипт, который вызовет контроллер error_handler, если требуемый не найден. Как и в первом варианте, данный скрипт не обрабатывает исключение show_404(), поэтому мы не перейдем к error_handler, если есть контроллер, но нет метода. Или если мы вручную вызываем show_404(). К достоинствам метода можно отнести установку заголовка, сообщающего роботу об ошибке:

header("HTTP/1.1 404 Not Found");

Исходный код:

class MY_Router extends CI_Router{

	function __construct()
	{
		parent::CI_Router();
	}

	function _validate_request($segments)
	{
		// Does the requested controller exist in the root folder?
		if (file_exists(APPPATH.'controllers/'.$segments[0].EXT))
		{
			return $segments;
		}

		// Is the controller in a sub-folder?
		if (is_dir(APPPATH.'controllers/'.$segments[0]))
		{
			// Set the directory and remove it from the segment array
			$this->set_directory($segments[0]);
			$segments = array_slice($segments, 1);

			if (count($segments) > 0)
			{
				// Does the requested controller exist in the sub-folder?
				if ( ! file_exists(APPPATH.'controllers/'.
					$this->fetch_directory().$segments[0].EXT))
				{
					//show_404($this->fetch_directory().$segments[0]);
					return $this->my_404();
				}
			}
			else
			{
				$this->set_class($this->default_controller);
				$this->set_method('index');

				// Does the default controller exist in the sub-folder?
				if ( ! file_exists(APPPATH.'controllers/'.
					$this->fetch_directory().$this->default_controller.EXT))
				{
					$this->directory = '';
					return array();
				}

			}

			return $segments;
		}

		// Can't find the requested controller…
		//show_404($segments[0]);
		return $this->my_404();
	}

	function my_404(){
		// return an array with the name of the controller
		// we want as the 404-handler…
		header("HTTP/1.1 404 Not Found");
		return array('error_handler');
	}
}

Вариант 3

Работаем с исключением.

class MY_Exceptions extends CI_Exceptions{

	function __construct()
	{
		parent::CI_Exceptions();
	}

	function show_404($page='')
	{
		header("HTTP/1.1 404 Not Found");
		header('Location: /error_handler');
		exit;
	}
}

Способ универсальный, так как обрабатывает исключение. Все, что вызывает ошибку 404, будет перенаправлено на контроллер error_handler. Но в этом и весь недостаток этого варианта - после редиректа мы теряем ссылку на несуществующую страницу. Ее можно передавать в качестве параметра:

header('Location: /error_handler'.$_SERVER['REQUEST_URI']);

Однако при этом будьте внимательны. URL может быть не правильно прочитан, что рекурсивно вызовет исключение о несуществующей странице.

Понравилась статья? Подпишись на RSS.

Mootools WYSIWYM редакторИзучаем MooTools. Шаг 1 - Введение

Комментарии

  • MIchail1982 написал 21 ноября 2009 года

    как вариант использовать 3й метод и устанавливать в сессию переменную со значением

    $_SERVER['REQUEST_URI']
    Ответить
  • Levik написал 30 августа 2010 года

    А нельзя обработать 404 ошибку непосредственно в /error/error_404.php?

    Ответить