Почему мое приложение PHP не отправляет ошибку 404?


140
if (strstr($_SERVER['REQUEST_URI'],'index.php')) {
    header('HTTP/1.0 404 Not Found');
}

Почему это не работает? У меня пустая страница.


1
Лучшим вариантом было бы отправить статус 404 и сразу добавить свою пользовательскую страницу 404. Это то, что я делал раньше.
Rocky

На моем PHP-сервере он работает отлично. Вышеупомянутая строка возвращает страницу 404 сервера по умолчанию. Я полагаю, что это можно настроить на сервере.
Elmue

Ответы:


306

Ваш код технически правильный. Если вы посмотрите на заголовки этой пустой страницы, вы увидите заголовок 404, и другие компьютеры / программы смогут правильно определить ответ как файл, который не найден.

Конечно, ваши пользователи по-прежнему SOL. Обычно сообщения 404 обрабатываются веб-сервером.

  • Пользователь: Эй, у вас есть что-нибудь для меня на этом веб-сервере URI?
  • Веб-сервер: Нет, 404! Вот страница для отображения 404.

Проблема в том, что как только веб-сервер начинает обрабатывать страницу PHP, он уже прошел точку, в которой он будет обрабатывать 404

  • Пользователь: Эй, у вас есть что-нибудь для меня на этом веб-сервере URI?
  • Веб-сервер: Да, это страница PHP. Он скажет вам, какой код ответа
  • PHP: Эй, OMG 404 !!!!!!!
  • Веб-сервер: Вот дерьмо, люди с 404-й страницей уже разошлись по домам, поэтому я просто пришлю все, что мне дал PHP

Помимо предоставления заголовка 404, PHP теперь отвечает за вывод фактической страницы 404.


49
14-летняя девочка или нет, но этот маленький глупый диалог действительно имел для меня смысл.
rbwhitaker 08

20
PHP было 14 лет
Адам Линч

1
Stack Overflow необходимо добавить функциональность к +1 для стиля. Это получит все +1.
Джей Керидо,

30
Вот как должна быть написана документация! Особенно документация Apache, которую я действительно ненавижу :)
Гарри

4
чертовски блестяще объяснено! сделал мой день!
Андрей Кристиан Продан

78
if (strstr($_SERVER['REQUEST_URI'],'index.php')){
    header('HTTP/1.0 404 Not Found');
    echo "<h1>404 Not Found</h1>";
    echo "The page that you have requested could not be found.";
    exit();
}

Если вы посмотрите на последние две строки эха, вы увидите их содержимое. Вы можете настроить его, как хотите.


74

Это правильное поведение , вам решать, создавать содержимое для страницы 404.
Заголовок 404 используется пауками и менеджерами загрузки, чтобы определить, существует ли файл.
(Страница с заголовком 404 не будет индексироваться Google или другими поисковыми системами)

Однако обычные пользователи не смотрят http-заголовки и используют страницу как обычную страницу.


20
FWIW, в случае 404, IE возвращает свою стандартную страницу «не найдено», если контент короткий (предполагается, что сервер просто говорит «не найден» и решает отобразить для пользователя более удобную страницу).
Серж Вотье

16

Для записи это универсальный обработчик:

<?php
header($_SERVER["SERVER_PROTOCOL"]." 404 Not Found");
header("Status: 404 Not Found");

$_SERVER['REDIRECT_STATUS'] = 404;
?> <!-- 404 contents below this line -->


Нет, просто поместите эти вещи в начало файла, а затем перейдите к настраиваемой странице 404.
Сильвиу-Мариан

14

Загрузите страницу 404 сервера по умолчанию, если она у вас есть, например, определенная для apache:

if(strstr($_SERVER['REQUEST_URI'],'index.php')){
  header('HTTP/1.0 404 Not Found');
  readfile('404missing.html');
  exit();
}

он не работает, отображается предупреждение: readfile (404missing.html): не удалось открыть поток: нет такого файла или каталога в /var/www/.com/public_html/index1.php в строке 61

2
@AMB Это потому, что вам нужно создать этот файл самостоятельно.
Super Cat

@SuperCat, спасибо, теперь я перечитал ошибку, и теперь все ясно.,


4

Другое решение, основанное на @ Kitet's.

header($_SERVER["SERVER_PROTOCOL"]." 404 Not Found");
header("Status: 404 Not Found");

$_SERVER['REDIRECT_STATUS'] = 404;
//If you don't know which web page is in use, use any page that doesn't exists
$handle = curl_init('http://'. $_SERVER["HTTP_HOST"] .'/404missing.html');
curl_exec($handle);

Если вы программируете веб-сайт, размещенный на сервере, которым вы не можете управлять, вы не будете знать, какой файл является «404missing.html». Однако вы все еще можете это сделать.

Таким образом, вы обеспечили тот же результат, что и обычная страница 404 на том же сервере. Наблюдатель не сможет различить существующую страницу PHP, возвращающую 404, и несуществующую страницу.



2

Немного укороченная версия. Подавить нечетное эхо.

if (strstr($_SERVER['REQUEST_URI'],'index.php')){
  header('HTTP/1.0 404 Not Found');
  exit("<h1>404 Not Found</h1>\nThe page that you have requested could not be found.");
}

2
if($_SERVER['PHP_SELF'] == '/index.php'){ 
   header('HTTP/1.0 404 Not Found');
   echo "<h1>404 Not Found</h1>";
   echo "The page that you have requested could not be found.";
   die;
}

никогда не упрощайте эхо-операторы и никогда не забывайте точку с запятой, как указано выше, а также зачем запускать substr на странице, мы можем легко просто запустить php_self


2
потому что REQUEST_URI - это не то же самое, что PHP_SELF. Особенно если у вас есть переписывание URL.
Timo Huovinen

1

Если вы хотите, чтобы отображалась страница ошибок сервера по умолчанию, вы должны обработать это на сервере.


1

Вы делаете это правильно, хотя это требует некоторой доработки. Похоже, это уже решено, поэтому давайте поговорим о практических преимуществах приложения:

Наш старый веб-сайт с большой коллекцией многоязычной технической документации выполнял это внутри условного if else:

    if (<no file found>){
        die("NO FILE HERE");
    }

Проблема (помимо бесполезного сообщения и плохого взаимодействия с пользователем) в том, что мы обычно используем сканер ссылок (в нашем случае целостность) для проверки плохих ссылок и недостающих документов. Это означает, что мы получили совершенно правильный ответ 200 без ошибок, говорящий нам, что там был файл. Integrity не знала, что мы ожидаем PDF-файл, поэтому нам пришлось вручную добавить заголовок 404 с помощью php. Добавив свой код над кристаллом (потому что впоследствии ничего не будет выполняться, а заголовок всегда должен быть перед любым визуализированным html), целостность (которая ведет себя более или менее как браузер) вернет 404, и мы точно знаем, где искать отсутствующие файлы. Есть более элегантные способы сообщить пользователю, что произошла ошибка,

    header('HTTP/1.0 404 Not Found');
    die("NO FILE HERE");

1

Попробуй это:

if (strstr($_SERVER['REQUEST_URI'],'index.php')) {
    header('HTTP/1.0 404 Not Found');
    echo "<head><title>404 Not Found</title></head>";
    echo "<h1>Not Found</h1>";
    $uri   = rtrim(dirname($_SERVER['PHP_SELF']), '/\\');
    echo "<p>The requested URL ".$uri." was not found on this server.</p>";
    exit();
}

0

Знаете, на своем сайте я создал что-то вроде этого:

        $uri=$_SERVER['REQUEST_URI'];
        $strpos=strpos($uri, '.php');
        if ($strpos!==false){
        $e404="The page requested by you: &quot".$_SERVER['REQUEST_URI']."&quot, doesn't exists on this server.";
        $maybe=str_replace('.php','',$uri);
        $maybe=str_replace('/','',$maybe);
        die("<center><h1>404</h1><hr><h3>$e404</h3><h3>Maybe try <a href=$maybe>www.leaveyortexthere.p.ht/$maybe</a>?</center>");

}

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


-4

Я столкнулся с этой проблемой ... Я думаю, что перенаправление на несуществующую ссылку на вашем сервере может помочь! Потому что сервер вернет его 404:
header('Redirect abbb.404.nonexist');<, которого точно не существует


7
Если вы это сделаете, это также вернет 302. Лучше не перенаправляйте свои 404-е. вместо этого используйте код состояния 404 и отобразите сообщение «Не найдено».
Rocky

-17

Если вы хотите показать страницу 404 сервера по умолчанию, вы можете загрузить ее во фрейме следующим образом:

echo '<iframe src="/something-bogus" width="100%" height="100%" frameBorder="0" border="0" scrolling="no"></iframe>';

4
Он должен получить какой-то значок за худший ответ, который я видел на этом сайте.
MadTurki 08

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.