Codeigniter & PHP - форсирование 404?
В codeigniter, как вы знаете, страница формы: /class/function/ID
, где class - имя контроллера, функция - это метод внутри контроллера, а ID - это параметр, который нужно передать этому методу.
Типичное использование будет (например, для книжного сайта) передать идентификатор книги функции, которая затем будет запрашивать базу данных для соответствующей книги. Моя проблема заключается в следующем: я беспорядочно и беспорядочно (в строке url) набрал идентификатор, отсутствующий в базе данных (с обычной точкой и просмотром страниц, это никогда не произойдет), и я получаю ошибки базы данных из-за остаточных запросов Я пытаюсь выполнить использование несуществующего идентификатора.
Я написал код, чтобы проверить, нет ли каких-либо строк, прежде чем пытаться использовать ID, но если идентификатор отсутствует, я хотел бы, чтобы пользователь получил страницу ошибки 404, а не пустую страницу или что-то (с тех пор это похоже на правильную функциональность). Это должно быть истинная 404 страница (а не просто загрузка вида, похожего на страницу 404), чтобы не закручивать поисковые системы. Хорошо - так мой вопрос таков: в нормальном потоке логики программы (как описано выше), как я могу заставить ошибку 404 использовать codeigniter? Спасибо.
Обновление: у воспламенителя кода есть функция show_404('page')
, но я не думаю, что это приведет к истинной ошибке HTTP 404...
Ответы
Ответ 1
show_404()
фактически отправляет соответствующие заголовки для поисковой системы, чтобы зарегистрировать ее как страницу 404 (она отправляет статус 404).
Используйте аддон Firefox, чтобы проверить заголовки, полученные при вызове show_404()
. Вы увидите, что он отправляет правильный код состояния HTTP.
Проверьте значение по умолчанию application/errors/error_404.php
. Первая строка:
<?php header("HTTP/1.1 404 Not Found"); ?>
Эта строка устанавливает статус HTTP как 404. Это все, что вам нужно, чтобы поисковая система читала вашу страницу как страницу 404.
Ответ 2
Если вы хотите создать страницу с пользовательскими ошибками, вы можете сделать следующее. В ваших библиотеках создайте имя файла MY_Exceptions и продолжите его с помощью CI_Exceptions. И затем переопределите функцию show_404(). В этой функции теперь вы можете создать экземпляр своего класса Controller с помощью функции get_instance(). Используя этот экземпляр, вы можете загрузить свою страницу ошибки 404.
class MY_Exceptions extends CI_Exceptions {
public function __construct(){
parent::__construct();
}
function show_404($page = ''){ // error page logic
header("HTTP/1.1 404 Not Found");
$heading = "404 Page Not Found";
$message = "The page you requested was not found ";
$CI =& get_instance();
$CI->load->view('/*Name of you custom 404 error page.*/');
}
Ответ 3
Только следующие шаги:
Шаг 1
Обновите файл application/config/routes.php
$route['404_override'] = 'error/error_404';
Шаг 2
Создайте свой собственный контроллер в папке контроллеров
ех. error.php
<?php
class Error extends CI_Controller
{
function error_404()
{
$data["heading"] = "404 Page Not Found";
$data["message"] = "The page you requested was not found ";
$this->load->view('error',$data);
}
}
?>
Шаг 3
Создайте свой просмотр в папке представлений
ех. error.php
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252" />
<title><?php echo $heading;?></title>
</head>
<body>
<?php echo $message;?>
</body>
</html>
Ответ 4
$this->output->set_status_header('404');
для генерации 404 заголовков.
Ответ 5
Да show_404() Отправляет 404, но это похоже на ад. Здесь было предложено несколько хаков, но зачем взломать, когда вы можете использовать встроенные функции?
перейти на CI 2.0, и вы сможете использовать потрясающие:
$route['404_override'] = 'errors/error_404';
Тогда у вас может быть общий контроллер ошибок, не беспокоясь о том, чтобы пытаться загружать представления, библиотеки и помощники WY слишком рано в экземпляре CI для правильной работы.
Ответ 6
попробуйте использовать
set_status_header(404);
Ответ 7
Создайте контроллер в папке приложений/контроллеров.
class Error extends Controller
{
function error_404()
{
$this->load->view('error');
}
}
Затем в вашем приложении/библиотеке расширьте класс Router, создав приложение/библиотеки/MY_Router.php
class MY_Router extends CI_Router
{
private $error_controller = 'error';
private $error_method_404 = 'error_404';
function MY_Router()
{
parent::CI_Router();
}
// this is just the same method as in Router.php, with show_404() replaced by $this->error_404();
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))
{
return $this->error_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...
return $this->error_404();
}
function error_404()
{
$segments = array();
$segments[] = $this->error_controller;
$segments[] = $this->error_method_404;
return $segments;
}
function fetch_class()
{
// if method doesn't exist in class, change
// class to error and method to error_404
$this->check_method();
return $this->class;
}
function check_method()
{
$class = $this->class;
if (class_exists($class))
{
if ($class == 'doc')
{
return;
}
if (! in_array('_remap', array_map('strtolower', get_class_methods($class)))
&& ! in_array(strtolower($this->method), array_map('strtolower', get_class_methods($class))))
{
$this->class = $this->error_controller;
$this->method = $this->error_method_404;
include(APPPATH.'controllers/'.$this->fetch_directory().$this->error_controller.EXT);
}
}
}
}
Если страница не существует, она будет перенаправлена на контроллер ошибок
Ответ 8
У меня была та же проблема с вами, и я нашел полное решение для этого в CodeIgniter 3. Здесь я хотел бы поэтапно поработать над ее решением. Конечно, нам нужно поддерживать пользовательскую страницу 404, чтобы удовлетворить потребности SEO.
- Показать 404 страницы для URL-адресов, которые не соответствуют схеме на маршрутах
- Добавить новый контроллер ошибок в приложении/контроллерах для поддержки пользовательской страницы 404.
class ErrorController extends CI_Controller
{
public function __construct()
{
parent::__construct();
}
public function index()
{
$this->output->set_status_header('404');
return $this->load->view('errors/error_404');
}
}
- Добавить новый пользовательский вид error_404.php для 404 страницы в приложении/представлениях/ошибках
<div>
<p>We are so sorry. The page you requested could not be found.</p>
</div>
- Объявить 404_overide в config/routes.php
$route['404_override'] = 'ErrorController';
- Показать 404 страницы для URL-адресов, которые соответствуют схеме в маршрутах, но указывают на несуществующий ресурс.
- Установите subclass_prefix в config/config.
$config['subclass_prefix'] = 'MY_';
- Определите свой собственный класс исключений в приложении/ядре
class MY_Exceptions extends CI_Exceptions {
public function __construct() {
parent::__construct();
}
function show_404($page = '', $log_error = TRUE) {
$CI = &get_instance();
$CI->output->set_status_header('404');
$CI->load->view('errors/error_404');
echo $CI->output->get_output();
exit;
}
}
- Вызовите show_404(), где хотите. Здесь я создал свой собственный класс модели ужина в приложении/моделях и проверил результаты запроса. Другие модели расширят модель ужина и покажут страницу 404, если они не смогли найти ресурс.
abstract class MY_Model extends CI_Model
{
protected $table = 'table_name';
public function __construct()
{
parent::__construct();
$this->load->database();
}
public function find($id)
{
$result = $this->db->get_where($this->table, ['id' => $id]);
$data = $result->row_object();
if (!$data) {
show_404();
}
return $data;
}
}