2009-08-06 26 views
21

en CodeIgniter, como es sabido, una página de la forma: /class/function/ID, donde la clase es el nombre del controlador, la función es el método dentro del controlador, y el ID es el parámetro para pasar a ese método.Codeigniter & PHP - forzando un 404?

El uso típico sería (para un sitio de libro por ejemplo) para pasar el ID de libro a la función que luego consultar la base de datos para el libro apropiado. Mi problema es este: me equivoqué y escribí al azar (en la cadena url) una ID que no está presente en la base de datos (con el punto normal y haga clic en buscar esto nunca sucedería) y recibo errores en la base de datos debido a las consultas residuales Intento realizar el trabajo con una identificación inexistente.

He escrito un código para verificar si hay alguna fila devuelta antes de intentar usar el ID, pero si el ID no existe me gustaría que el usuario obtenga una página de error 404 en lugar de una página en blanco o algo (ya que esto parece una funcionalidad adecuada). Esto tendría que ser un verdadero página 404 (no simplemente cargando una vista que se parece a una página 404) para que no se atornille con los motores de búsqueda. Está bien - por lo que mi pregunta es la siguiente: en el flujo de la lógica del programa normal (como se describe más arriba) ¿Cómo puedo forzar un error 404 usando CodeIgniter? Gracias.

actualización: CodeIgniter tiene una función show_404('page') pero no creo que esto va a generar un verdadero error HTTP 404 ...

Respuesta

47

show_404() realmente envía las cabeceras apropiadas para un motor de búsqueda para registrarlo como Página 404 (envía el estado 404).

Use un complemento de Firefox para verificar los encabezados recibidos al llamar al show_404(). Verás que envía el código de estado HTTP adecuado.

Comprobar el valor por defecto application/errors/error_404.php. La primera línea es:

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

Esa línea fija el estado HTTP como 404. Es todo lo que necesita para el motor de búsqueda para leer su página como una página 404.

+0

¡Esa es una gran noticia! No es que no te crea, pero intentaré verificar esto antes de aceptar tu respuesta. Gracias – oym

+0

Gracias! Corto, simple y efectivo. –

+0

sí, funciona en codeigniter también. realizar la función page_not_found y llamarlo desde config/rutas '$ route [ '404_override'] = 'Bienvenido/page_not_found';' \t 'page_not_found función() \t { \t \t cabecera ("HTTP/1.1 404 Not Found"); $ this-> load-> view ('page_not_found'); } ' –

0

Crear controlador en su carpeta application/controllers.

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

Luego, en su aplicación/biblioteca de extender la clase Router mediante la creación de aplicaciones/bibliotecas/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); 
     } 
    } 
} 

}

Si no existe la página, que serán enviados a error controller

+1

Creo que deberías acreditar al autor original de este código. Encontrado aquí http://maestric.com/doc/php/codeigniter_404 – goliatone

8

Si desea una página de error personalizada, puede hacer lo siguiente. En sus bibliotecas crear un nombre de archivo MY_Exceptions a nd extiéndalo con CI_Exceptions. Y luego anule la función show_404(). En esta función ahora puede crear una instancia de su clase Controller utilizando & función get_instance(). Y utilizando esta instancia puede cargar su página 404 Error personalizada .

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

Sí show_404() enviará un 404, pero parece que el infierno. Se han sugerido algunos hacks aquí, pero ¿por qué hackear cuando puedes usar las características integradas?

Upgrade to CI 2.0 y usted será capaz de utilizar el increíble:

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

, entonces puede tener un controlador de errores general sin tener que preocuparse por tratar de cargar puntos de vista, las bibliotecas y los ayudantes WY demasiado pronto en el CI instancia para funcionar correctamente.

7

sólo sigue estos pasos:

Paso 1 actualizar su archivo application/config/routes.php

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

Paso 2 Crear su propio controlador de los controladores en la carpeta ex. 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); 
} 
} 
?> 

Paso 3 Crear su punto de vista en las vistas de carpetas ex. 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> 
2

intento de utilizar este

set_status_header(404); 
7
 $this->output->set_status_header('404'); 

para generar 404 cabeceras.

0

tuve el mismo problema con usted y he encontrado una solución completa para esto en CodeIgniter 3. Aquí me gustaría compartir paso a paso la forma de resolverlo. Por supuesto, debemos admitir una página 404 personalizada para satisfacer los requisitos de SEO.

  1. Mostrar página 404 para las direcciones URL que no coincide con el esquema en rutas
    • Añadir un nuevo controlador de error en application/controllers para apoyar una página 404 personalizada.
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'); 
    } 
} 
  • Agregar una nueva vista personalizada error_404.php de página 404 en application/views/errors
<div> 
    <p>We are so sorry. The page you requested could not be found.</p> 
</div> 
  • 404_overide Declare en config /routes.php
$route['404_override'] = 'ErrorController'; 
  1. Mostrar página 404 para las direcciones URL que coinciden con el esquema de rutas, pero el punto de recurso no existente.
    • Establecer subclass_prefix en config/config.
$config['subclass_prefix'] = 'MY_'; 
  • definir la clase de excepciones personalizadas en aplicación/núcleo
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; 
    } 

} 
  • llamada show_404() donde desee. Aquí, creé mi clase de modelo de cena personalizada en la aplicación /modelos y comprobé los resultados de la consulta allí. Otros modelos ampliarán el modelo de cena y mostrarán la página 404 si no pudieron encontrar un recurso.
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; 
    } 
} 
Cuestiones relacionadas