PHP, MVC, 404 - Как я могу перенаправить на 404?

Я пытаюсь создать свой собственный MVC в качестве практики и обучения. Пока это то, что у меня есть (index.php):

<?php
require "config.php";

$page = $_GET['page'];
if( isset( $page ) ) { 
    if( file_exists( MVCROOT . "/$page.php" ) ) {
        include "$page.php";
    } else {
        header("HTTP/1.0 404 Not Found");
    }
}


?>

Моя проблема в том, что я не могу использовать заголовок для отправки на 404, потому что заголовки уже отправлены. Должен ли я просто перенаправить на 404.html или есть лучший способ? Не стесняйтесь критиковать то, что у меня есть (это очень мало). Буду рад предложениям и идеям. Спасибо!


person Strawberry    schedule 16.06.2010    source источник
comment
Попробуйте удалить или закомментировать строку echo "isset is true".   -  person BoltClock    schedule 16.06.2010
comment
О да, я использовал это для тестирования. Позвольте мне удалить это.   -  person Strawberry    schedule 16.06.2010
comment
Что произойдет, если $_GET['page'] равно '../../../../etc/passwd'? (например, example.com/index. php?page=../../../../etc/passwd)   -  person Morfildur    schedule 29.06.2010


Ответы (3)


Стандартная практика в средах MVC заключается в использовании буферизации вывода (ob_start() , ob_get_contents() и ob_end_clean()), чтобы контролировать, как, когда и что будет отправлено пользователю.

Таким образом, до тех пор, пока вы фиксируете вывод своей платформы, он не будет отправлен пользователю, пока вы этого не захотите.

Чтобы загрузить 404, вы должны использовать (например):

<?php
require "config.php";

$page = $_GET['page'];
ob_start();

if (isset($page)) {
    echo "isset is true";
    if (file_exists(MVCROOT."/$page.php")) {
        include MVCROOT."/$page.php";
        $output = ob_get_contents();
        ob_end_clean();
        echo $output;
    } else {
        ob_end_clean(); //we don't care what was there
        header("HTTP/1.0 404 Not Found");
        include MVCROOT."/error_404.php"; // or echo a message, etc, etc
    }
}
?>

Надеюсь, это поможет.

person Austin Hyde    schedule 16.06.2010
comment
Я ожидаю сообщение 404, но это просто пустая страница в Firefox. В других браузерах пишет сломано. - person Strawberry; 16.06.2010
comment
Во многих случаях, если вместе с кодом ответа нет контента, браузер предоставит свой собственный. Попробуйте добавить свою страницу 404 после заголовка. Я обновлю свой ответ. - person Austin Hyde; 16.06.2010

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

Итак, если вы хотите дать пользователю ошибку 404, ищущую ошибку в php-коде, вы должны использовать простое перенаправление на 404.html.

С другой стороны, если у вас есть доступ к файлам конфигурации сервера, вы можете запрограммировать это на сервере, а не на работающей на нем веб-странице. Вы можете использовать WAMP для практики...

Я надеюсь, вы меня понимаете. Циаа

ИЗМЕНИТЬ я должен добавить:

$страница = $_GET['страница'];

Это выдаст вам ошибку, если $_GET['page'] не установлен, вы ДОЛЖНЫ проверить isset($_GET['page']) перед попыткой его использования.

person DomingoSL    schedule 16.06.2010
comment
@Doug, это не выдаст вам ошибку, но выдаст предупреждение. Вы должны сделать что-то вроде $page = isset($_GET['page'])?$_GET['page']:null; Таким образом, предупреждения не генерируются, и вы знаете, что точное значение $page в событии $_GET['page'] не установлено. - person Austin Hyde; 16.06.2010
comment
правильно, не ошибка, предупреждение... все еще улучшаю свой английский :) - person DomingoSL; 18.06.2010

Вы должны либо перенаправить, либо просто включить его, вот измененный код:

require "config.php";

$page = $_GET['page'];
if( isset( $page ) ) { 
    echo "isset is true";
    if( file_exists( MVCROOT . "/$page.php" ) ) {
        include  MVCROOT . "$page.php";
    } else {
        include  MVCROOT . "404.html";
    }
}
person Sarfraz    schedule 16.06.2010
comment
Это просто включение страницы, сообщающей пользователю об ошибке 404, с фактическим заголовком HTTP 404, полностью исчезнувшим. - person BoltClock; 16.06.2010
comment
@BoltClock: Да, это правда, в основном это предложение OP Должен ли я просто перенаправить на 404.html - person Sarfraz; 16.06.2010