web-dev-qa-db-ja.com

Codeigniter&PHP-404を強制する?

ご存知のように、codeigniterでは、フォームは_/class/function/ID_のページです。ここで、classはコントローラー名、functionはコントローラー内のメソッド、IDはそのメソッドに渡すパラメーターです。

典型的な使用法は(たとえば、本のサイトの場合)、適切な本をデータベースに照会する関数に本のIDを渡すことです。私の問題はこれです:データベースに存在しないIDをいじり回して(URL文字列に)ランダムに入力しました(通常のポイントとクリックのブラウズではこれは起こりません)、残りのクエリが原因でデータベースエラーが発生します存在しないIDで実行しようとしています。

IDを使用する前に返された行があるかどうかを確認するコードを記述しましたが、IDが存在しない場合、ユーザーに空白ページなどではなく404エラーページを取得してもらいたいのです(これは適切な機能)。これは、検索エンジンで混乱しないように、真の404ページである必要があります(404ページのように見えるビューを単にロードするだけではありません)。さて-だから私の質問はこれです:通常のプログラムロジックフロー内で(上記のように)codeigniterを使用して404エラーを強制するにはどうすればよいですか?ありがとう。

pdate:コードイグナイターにはshow_404('page')関数がありますが、これにより真のHTTP 404エラーが生成されるとは思いません...

25
oym

show_404()は、検索エンジンが404ページとして登録するための適切なヘッダーを実際に送信します(404ステータスを送信します)。

Firefoxアドオンを使用して、show_404()を呼び出すときに受信したヘッダーを確認します。適切なHTTPステータスコードを送信することがわかります。

デフォルトを確認するapplication/errors/error_404.php。最初の行は次のとおりです。

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

その行はHTTPステータスを404に設定します。検索エンジンがページを404ページとして読み取るために必要なのはこれだけです。

51
Andrew Moore
        $this->output->set_status_header('404');

404ヘッダーを生成します。

9
Jubair

カスタムエラーページが必要な場合は、次のことを実行できます。ライブラリでファイル名を作成しますMY_ExceptionsとCI_Exceptionsで拡張します。そしてshow_404()関数をオーバーライドしますこの関数では、&get_instance()関数を使用してControllerクラスのインスタンスを作成できます。このインスタンスを使用して、カスタム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.*/');

}
8
sagar27

次の手順のみに従ってください:

ステップ1 application/config/routes.phpファイルを更新します

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

ステップ2コントローラフォルダ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);
}
}
?>

ステップビューフォルダ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>
7
NBN

これを使ってみてください

set_status_header(404);
3
GianFS

はいshow_404()は404を送信しますが、地獄のように見えます。ここでいくつかのハックが提案されていますが、組み込みの機能を使用できるのになぜハックするのですか?

CI 2.0にアップグレード すると、すばらしい機能を使用できるようになります。

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

そうすれば、CIインスタンスの早い段階でビュー、ライブラリ、ヘルパーをロードして適切に機能することを心配せずに、一般的なエラーコントローラーを使用できます。

3
Phil Sturgeon

私はあなたと同じ問題を抱えていて、CodeIgniter 3でこれに対する完全な解決策を見つけました。ここで、それを解決する方法を段階的に共有したいと思います。もちろん、SEO要件を満たすには、カスタム404ページをサポートする必要があります。

  1. ルートのスキーマと一致しないURLの404ページを表示する
    • application/controllersに新しいエラーコントローラーを追加して、カスタム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'); 
    } 
}
  • application/views/errorsの404ページに新しいカスタムビューerror_404.phpを追加します
<div>
    <p>We are so sorry. The page you requested could not be found.</p> 
</div>
  • Config/routes.phpで404_overideを宣言する
$route['404_override'] = 'ErrorController';
  1. ルートのスキーマに一致するが、存在しないリソースを指しているURLの404ページを表示します。
    • config/configでsubclass_prefixを設定します。
$config['subclass_prefix'] = 'MY_';
  • application/coreでカスタム例外クラスを定義します
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
Tung Nguyen

Application/controllersフォルダーにコントローラーを作成します。

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

次に、application/libraryでapplication/libraries/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);
        }
    }
}

}

ページが存在しない場合、エラーコントローラーにルーティングされます

0
Zorancho