Codeigniter & PHP - форсирование 404? - PullRequest
       6

Codeigniter & PHP - форсирование 404?

24 голосов
/ 06 августа 2009

В codeigniter, как вы знаете, страница формы: /class/function/ID, где class - это имя контроллера, function - это метод внутри контроллера, а ID - параметр для передачи этому методу.

Типичное использование (например, для сайта книги) - передать идентификатор книги в функцию, которая затем запросит базу данных для соответствующей книги. Моя проблема заключается в следующем: я возился и случайно (в строке URL) набрал идентификатор, которого нет в базе данных (при обычном просмотре по точке и щелчку это никогда не произойдет), и я получаю ошибки базы данных из-за остаточных запросов Я пытаюсь выполнить, используя несуществующий идентификатор.

Я написал код, чтобы проверить, есть ли какие-либо строки, возвращенные перед попыткой использовать идентификатор, но если идентификатор не существует, я бы хотел, чтобы пользователь получил страницу с ошибкой 404, а не пустую страницу или что-то еще ( это похоже на правильную функциональность). Это должна быть настоящая страница 404 (а не просто загрузка представления, похожего на страницу 404), чтобы не связываться с поисковыми системами. Итак, мой вопрос таков: в рамках нормального логического потока программы (как описано выше), как я могу форсировать ошибку 404, используя codeigniter? Спасибо.

Обновление : воспламенитель кода имеет функцию show_404('page'), но я не думаю, что это приведет к ошибке HTTP 404 ...

Ответы [ 8 ]

49 голосов
/ 06 августа 2009

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

Используйте дополнение Firefox для проверки заголовков, полученных при вызове show_404(). Вы увидите, что он отправляет правильный код статуса HTTP.

Проверьте значение по умолчанию application/errors/error_404.php. Первая строка:

<?php header("HTTP/1.1 404 Not Found"); ?>

Эта строка устанавливает HTTP-статус равным 404. Это все, что нужно поисковой системе для чтения вашей страницы как страницы 404.

8 голосов
/ 15 ноября 2013
        $this->output->set_status_header('404');

для генерации 404 заголовков.

8 голосов
/ 26 октября 2010

Если вам нужна пользовательская страница ошибки, вы можете сделать следующее: в ваших библиотеках создайте имя файла MY_Exceptions и расширьте его с помощью CI_Exceptions . А затем переопределите функцию show_404 () .В этой функции теперь вы можете создать экземпляр вашего класса Controller с помощью функции & get_instance (). И с помощью этого экземпляра вы можете загрузить свою пользовательскую страницу 404 Error.

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.*/');

}
7 голосов
/ 20 августа 2011

Только следующие шаги:

Шаг 1 Обновите файл application / config / rout.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>
3 голосов
/ 26 октября 2010

Да show_404 () БУДЕТ отправить 404, но это похоже на ад. Здесь было предложено несколько хаков, но зачем взламывать, если вы можете использовать встроенные функции?

Обновите до CI 2.0 , и вы сможете использовать удивительные:

$route['404_override'] = 'errors/error_404';

Тогда вы можете иметь контроллер общих ошибок, не беспокоясь о попытке загрузить представления, библиотеки и помощники WY слишком рано в экземпляре CI для правильной работы.

2 голосов
/ 01 марта 2017

У меня была такая же проблема с вами, и я нашел полное решение для этого в CodeIgniter 3. Здесь я хотел бы шаг за шагом рассказать, как ее решить. Конечно, нам нужно поддерживать пользовательскую страницу 404, чтобы удовлетворить требования SEO.

  1. Показать страницу 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 / rout.php
$route['404_override'] = 'ErrorController';
  1. Показать страницу 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 () куда хотите. Здесь я создал свой класс модели ужина в application / models и проверил там результаты запроса. Другие модели расширят модель ужина и покажут страницу 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;
    }
}
2 голосов
/ 26 июля 2013

попробуйте использовать это

set_status_header(404);
0 голосов
/ 23 августа 2009

Создать контроллер в папке приложения / контроллеров.

class Error extends Controller
{
function error_404()
{
    $this->load->view('error');
}
}

Затем в вашем приложении / библиотеке расширить класс Router, создав application / library / 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);
        }
    }
}

}

Если страница не существует, она будет перенаправлена ​​на контроллер ошибок

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...