Ошибка 404 для index php

Веб-серверы Nginx и Apache мало похожи друг на друга, и их отличия касаются не только особенностей подключения пользователей, но и обработки URL на сервере. Очень часто новые пользователи Nginx получают ошибку 404 для URL, которые, по сути, должны были бы работать.

В этой статье рассмотрим, почему возникает ошибка «404 not found Nginx», а также способы её устранения и отладки.Мы не будем разбираться с ситуацией, когда файла действительно нет на сервере — это решение, не требующее пояснений. Мы рассмотрим проблему обработки location в Nginx.

Давайте сначала разберёмся, как обрабатываются URL в Nginx. Когда веб-сервер определил, к какому блоку server (сайту) нужно передать запрос пользователя, просматриваются все префиксные блоки location и выбирается тот, который подходит лучше всего. Например, рассмотрим стандартную конфигурацию для WordPress. Здесь префиксные location отмечены зелёным, а с регулярным выражением — оранжевым:

location / {
index index.html index.php;
}
location /favicon.ico {
access_log off;
}
location ~* .(gif|jpg|png)$ {
expires 30d;
}
location ~ .php$ {
fastcgi_pass localhost:9000;
fastcgi_param SCRIPT_FILENAME
$document_root$fastcgi_script_name;
include fastcgi_params;
}

Префиксные локейшены всегда начинаются с символа /. Регулярные же содержат символы регулярных выражений: ~ $ ^ * и так далее. Если пользователь запрашивает favicon.ico, то будет выбран второй location, так как он лучше всего соответствует запросу, при любом другом запросе будет выбран location /, так как он соответствует всем запросам, а других префиксных location у нас нет. Это просто, а дальше начинается магия. После того, как был найден нужный location, Nginx начинает проверять все регулярные выражения в порядке их следования в конфигурационном файле.

При первом же совпадении Nginx останавливает поиск и передаёт управление этому location. Или, если совпадений не было найдено, используется ранее обнаруженный префиксный location. Например, если запрос заканчивается на .php, то первый location будет проигнорирован, а управление передастся четвёртому (~ .php$)

Таким образом, любое неверно составленное регулярное выражение в любой части конфигурационного файла может полностью всё сломать. Поэтому разработчики рекомендуют по минимум использовать регулярные выражения. Что касается вложенных location, то обрабатываются они так же как и основные, только уже после передачи управления в нужный location. Путём чтения конфигурационного файла понять, какой location вызывает 404 сложно, поэтому, чтобы исправить ошибку, нам понадобиться режим отладки Nginx.

Как включить режим отладки Nginx?

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

nginx -V

В выводе должна быть строчка «—with-debug». Если её нет, значит отладка не поддерживается, и надо установить версию с поддержкой. В CentOS такой пакет называется nginx-debug. Для его установки наберите:

sudo yum install nginx-debug

Теперь появился ещё один исполняемый файл, и он собран уже с поддержкой отладки:

nginx-debug -V

Откройте конфигурационный файл вашего сайта или глобальный конфигурационный файл, если вы не задавали настройки логов отдельно для каждого сайта, и в конце стоки error_log замените error на debug:

error_log /var/log/nginx/domains/test.losst.pro.error.log debug

Останавливаем обычную версию и запускаем версию с отладкой:

systemctl stop nginx
systemctl start nginx-debug

Как исправить «404 Not Found Nginx»?

1. Регулярные выражения

Как я уже сказал выше, самой частой проблемой, которая вызывает 404, являются регулярные выражения. Смотрим, что происходит в лог файле:

tail -f /var/log/nginx/domains/test.losst.pro.error.log

Видим, что серверу пришёл запрос /vstats. Дальше он проверяет location: /, /robots.txt, /vatsts/, /site-control/. Здесь уже можем понять, в чём проблема — промазали на один слеш. Дальше проверяются все регулярные выражения, и, так как в них ничего найдено не было, выбирается location /.

Далее директива try_files пытается найти файл /vstats, не находит и ищет index.php, который, в свою очередь, возвращает 404.

Если мы наберём, то что ожидает видеть Nginx — /vstats/, то откроется наша страница статистики.

Если мы добавим к конфигурационному файлу ещё один location с регулярным выражением, например:

location ~* {
try_files $uri $uri/ =404;
}

То абсолютно все запросы будут обрабатываться именно этим регулярным выражением и, естественно, что ничего работать не будет. Видим, что приходит запрос /vstats/:

Он совпадает с префиксным location, но потом Nginx видит наше регулярное выражение и передаёт управление ему.

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

2. Недостаточно памяти

Если php-скрипту не хватило оперативной памяти для выполнения, и его процесс был убит операционной системой, то Nginx тоже может вернуть ошибку 404. Такое поведение вы будете наблюдать, когда скрипт очень долго выполняется, а потом появляется «404 Not Found» или страница ошибки вашего движка. Обычно эта неисправность тоже видна в отладочном логе.

Решить такую проблему можно, освободив память на сервере, часто такое может возникать из-за утечек памяти в php, когда процессы php-fpm занимают почти всю память на сервере. Поэтому перезапуск php-fpm решает проблему:

systemctl restart php-fpm

Чтобы избежать этой проблемы в будущем, можно настроить автоматический перезапуск процессов после обработки определённого количества запросов. Например каждые 200 запросов:

vi /etc/php-fpm.d/www.conf

pm.max_requests = 200

3. Не найден index

Если вы запрашиваете URL вида /vstats/, но в настройках Nginx не указан файл index, который нужно использовать для этой ссылки, то у вас ничего не выйдет, и вы получите 404. Вы можете добавить директиву index в ваш location:

location / {
index index.php index.html index.htm;
}

Или сразу в server, в Nginx все location наследуют директивы, установленные в server.

4. Другие проблемы

Подобных проблем, вызывающих 404 в Nginx, может быть очень много, но все они решаемы, и всё, что нужно для их решения, есть в отладочном логе Nginx. Просто анализируйте лог и на основе этого вносите исправления.

Выводы

В этой статье мы рассмотрели основные причины, из-за которых может возникнуть ошибка 404 not found Nginx. Как видите, может быть много проблем, но всё достаточно просто решается. А с какими проблемами, вызывающими эту ошибку, вы сталкивались? Как их решали? Напишите в комментариях!

Обнаружили ошибку в тексте? Сообщите мне об этом. Выделите текст с ошибкой и нажмите Ctrl+Enter.

Creative Commons License

Статья распространяется под лицензией Creative Commons ShareAlike 4.0 при копировании материала ссылка на источник обязательна .

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

Why wont this work? I get a blank page.

danorton's user avatar

danorton

11.8k7 gold badges44 silver badges52 bronze badges

asked Jan 12, 2009 at 22:26

2

Your code is technically correct. If you looked at the headers of that blank page, you’d see a 404 header, and other computers/programs would be able to correctly identify the response as file not found.

Of course, your users are still SOL. Normally, 404s are handled by the web server.

  • User: Hey, do you have anything for me at this URI webserver?
  • Webserver: No, I don’t, 404! Here’s a page to display for 404s.

The problem is, once the web server starts processing the PHP page, it’s already passed the point where it would handle a 404

  • User: Hey, do you have anything for me at this URI webserver?
  • Webserver: Yes, I do, it’s a PHP page. It’ll tell you what the response code is
  • PHP: Hey, OMG 404!!!!!!!
  • Webserver: Well crap, the 404 page people have already gone home, so I’ll just send along whatever PHP gave me

In addition to providing a 404 header, PHP is now responsible for outputting the actual 404 page.

answered Jan 13, 2009 at 1:39

Alana Storm's user avatar

Alana StormAlana Storm

164k91 gold badges394 silver badges596 bronze badges

10

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();
}

If you look at the last two echo lines, that’s where you’ll see the content. You can customize it however you want.

womble's user avatar

womble

12k5 gold badges52 silver badges66 bronze badges

answered Jan 12, 2009 at 22:37

Evan Fosmark's user avatar

Evan FosmarkEvan Fosmark

98.4k36 gold badges105 silver badges117 bronze badges

That is correct behaviour, it’s up to you to create the contents for the 404 page.
The 404 header is used by spiders and download-managers to determine if the file exists.
(A page with a 404 header won’t be indexed by google or other search-engines)

Normal users however don’t look at http-headers and use the page as a normal page.

answered Jan 12, 2009 at 22:32

Bob Fanger's user avatar

Bob FangerBob Fanger

28.8k7 gold badges62 silver badges78 bronze badges

1

For the record, this is the all-case handler:

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

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

answered Oct 7, 2012 at 7:20

Silviu-Marian's user avatar

Silviu-MarianSilviu-Marian

10.5k6 gold badges50 silver badges72 bronze badges

1

Load default server 404 page, if you have one, e.g. defined for apache:

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

answered Jun 8, 2011 at 12:01

Kitet's user avatar

KitetKitet

1411 silver badge2 bronze badges

3

Another solution, based on @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);

If you are programming a website that hosted in a server you do not have control, you will not know which file is the «404missing.html». However you can still do this.

In this way, you provided exactly the same outcome of a normal 404 page on the same server. An observer will not be able to distinguish between an existing PHP page returns 404 and a non-existing page.

answered Jul 2, 2013 at 3:45

Earth Engine's user avatar

Earth EngineEarth Engine

9,9585 gold badges47 silver badges78 bronze badges

try with:

header("Status: 404 Not Found");
header('HTTP/1.0 404 Not Found');

Bye!

answered Oct 15, 2013 at 4:47

Jorge Olaf's user avatar

Jorge OlafJorge Olaf

5,6879 gold badges40 silver badges73 bronze badges

A little bit shorter version. Suppress odd echo.

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.");
}

answered Oct 10, 2010 at 5:55

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;
}

never simplify the echo statements, and never forget the semi colon like above, also why run a substr on the page, we can easily just run php_self

answered Jun 19, 2011 at 5:20

Jesse's user avatar

JesseJesse

211 bronze badge

1

If you want the server’s default error page to be displayed, you have to handle this in the server.

answered Jan 12, 2009 at 23:37

Gumbo's user avatar

GumboGumbo

641k109 gold badges775 silver badges843 bronze badges

You’re doing it right though it could use some refining. Looks like that’s been addressed so let’s talk practical application benefits:

An old website of ours that has a large collection of multilingual tech docs was executing this inside an if else conditional:

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

The problem (besides the unhelpful message and bad user experience) being that we generally use a link crawler (in our case integrity) to check out bad links and missing documents. This means that we were getting a perfectly correct 200 no error response telling us that there was a file there. Integrity didn’t know that we were expecting a PDF so we had to manually add a 404 header with php. By adding your code above the die (because nothing afterwards would execute and header should always be before any rendered html anyway), integrity (which behaves more or less like a browser) would return a 404 and we would know exactly where to look for missing files. There are more elegant ways of telling the user that there is an error, but by serving a 404 error you are not only notifying browsers and browser-like programs of the error but (I believe-correct me if I’m wrong) are also recording those errors in your server logs where you can easily grep for 404s.

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

answered Jul 16, 2013 at 21:51

Jacob Stazewski's user avatar

Try this:

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();
}

Soroush's user avatar

Soroush

9071 gold badge9 silver badges27 bronze badges

answered Jul 22, 2015 at 5:35

Mohammad Farhoudi's user avatar

You know, in my website i created something like this:

        $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>");

}

i hope it helps you.

answered Aug 10, 2013 at 23:20

GGG's user avatar

GGGGGG

6401 gold badge9 silver badges27 bronze badges

I came up to this problem.. I think that redirecting to a non existing link on your server might do the trick ! Because the server would return his 404:
header('Redirect abbb.404.nonexist'); < that doesnt exist for sure

answered Nov 11, 2010 at 7:43

GorillaApe's user avatar

GorillaApeGorillaApe

3,59110 gold badges62 silver badges105 bronze badges

1

If you want to show the server’s default 404 page, you can load it in a frame like this:

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

answered Jul 10, 2012 at 23:07

cicada's user avatar

2

Htaccess переадресация 404 ошибка примеры

ErrorDocument 404 Редирект 404 htaccess или редирект на страницу 404, errordocument в файле htaccess сегодня полностью разберемся во всех возможных ситуациях, которые возникают с с использованием htaccess редирект 404

Всё о htaccess редирект 404 errordocument

  1. Что такое редирект htaccess 404
  2. Как настроить 404 ошибку в htaccess
  3. Как настроить 404 ошибку в htaccess -> единая точка входа

Еще смотри: tema=404

  1. Что такое редирект htaccess 404

    Редирект в файле htaccess создается для того, чтобы при возникновении ошибки 404 на вашем сайте происходила переадресация… туда, куда вы захотите!
    Обычно делают переадресацию на собственный файл -> 404.html

    Зачем нужен редирект на файл 404.html

    Нам нужно, чтобы наш посетитель не ушел с нашего сайта! Поэтому после того, как он увидит страницу 404.html, ему можно сделать редирект на главную!

    Конечно же… никаких таких правил в web-e не существует, что именно по такому алгоритму должна обрабатываться ошибка 404.

    У вас есть выбор… оставить пользователя смотреть на не найденную страницу и предоставить выбор ему…

    Либо переадресовать на существующую страницу!

  2. Как настроить 404 ошибку в htaccess

    Настраивать ничего не нужно! Просто нужно прописать правило редиректа и всё! Для того, чтобы прописать редирект при появлении ошибки 404Ю в файле htaccess прописываем редирект страницы на 404:

    ErrorDocument 404 /404.html

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

    ErrorDocument 404 /путь_до_файла/название_файла_.html

    Как настроить 404 ошибку в htaccess

    Как сделать редирект с 404 на главную htaccess

    В файле htaccess, внутри правила ErrorDocument прописываем файл не 404.html? а адрес главной! И когда произойдет 404 ошибка то редирект произойдет на главную, если по домену открывается файл index.html:

    ErrorDocument 404 /index.html

    Как сделать редирект уже в файле 404.html
    После того, как ваш редирект вна 404 сработает, то пользователя переместят на страницу 404.html. далее вы можете сделать простую переадресацию html уже на любую страницу!

  3. Как настроить 404 ошибку в htaccess -> единая точка входа

    Когда у вас единая точка входа, то те выше приведенные правила редиректов работать просто не будут, потому, что при любом случае, все запросы будут отправляться на какую-то страницу!

    Как настроить 404 ошибку в htaccess если у вас единая точка входа!?

    Когда я делал свой редирект на 404 единой точки входа, ничего внятного в интернетах по этому вопросу не было написано! Поэтому, я сам до этого дошел!

    Если url из адресной строки пролетел мимо всех проверок, то создается переменная $no_page. В этом подпункте мы как раз касались немного, темы структуры единой точки входа — тема проверок, и в том числе там фигурирует эта переменная:

    $no_page = 1;

    В самом низу перед html тегами, делаем условие, существует ли переменная $no_page, если да то:

    Отправляем заголовок 404 — поскольку поисковая система никак не сможет узнать, что данная страница не существует!

    Далее просто инклудим 404.html страницу

    Останавливаем скрипт!

    if($no_page)

    {

    header(«HTTP/1.0 404 Not Found»);

    include(‘404.html’);

    exit;

    }

    Как настроить 404 ошибку в htaccess если у вас единая точка входа!?

Не благодарите, но ссылкой можете поделиться!

COMMENTS+

 
BBcode


(PHP 5 >= 5.4.0, PHP 7, PHP 8)

http_response_codeПолучает или устанавливает код ответа HTTP

Описание

http_response_code(int $response_code = 0): int|bool

Список параметров

response_code

Код ответа устанавливается с помощью опционального параметра response_code.

Возвращаемые значения

Если response_code задан, то будет возвращён предыдущий код
статуса. Если response_code не задан, то будет возвращён
текущий код статуса. Оба этих значения будут по умолчанию иметь код состояния 200,
если они используются в окружении веб-сервера.

Если response_code не задан и используется не в окружении
веб-сервера (например, в CLI), то будет возвращено false. Если
response_code задан и используется не в окружении
веб-сервера, то будет возвращено true (но только если не был установлен предыдущий
код статуса).

Примеры

Пример #1 Использование http_response_code() в окружении веб-сервера


<?php// Берём текущий код и устанавливаем новый
var_dump(http_response_code(404));// Берём новый код
var_dump(http_response_code());
?>

Результат выполнения данного примера:

Пример #2 Использование http_response_code() в CLI


<?php// Берём текущий код по умолчанию
var_dump(http_response_code());// Устанавливаем код
var_dump(http_response_code(201));// Берём новый код
var_dump(http_response_code());
?>

Результат выполнения данного примера:

bool(false)
bool(true)
int(201)

Смотрите также

  • header() — Отправка HTTP-заголовка
  • headers_list() — Возвращает список переданных заголовков (или готовых к отправке)

craig at craigfrancis dot co dot uk

11 years ago


If your version of PHP does not include this function:

<?phpif (!function_exists('http_response_code')) {
        function
http_response_code($code = NULL) {

            if (

$code !== NULL) {

                switch (

$code) {
                    case
100: $text = 'Continue'; break;
                    case
101: $text = 'Switching Protocols'; break;
                    case
200: $text = 'OK'; break;
                    case
201: $text = 'Created'; break;
                    case
202: $text = 'Accepted'; break;
                    case
203: $text = 'Non-Authoritative Information'; break;
                    case
204: $text = 'No Content'; break;
                    case
205: $text = 'Reset Content'; break;
                    case
206: $text = 'Partial Content'; break;
                    case
300: $text = 'Multiple Choices'; break;
                    case
301: $text = 'Moved Permanently'; break;
                    case
302: $text = 'Moved Temporarily'; break;
                    case
303: $text = 'See Other'; break;
                    case
304: $text = 'Not Modified'; break;
                    case
305: $text = 'Use Proxy'; break;
                    case
400: $text = 'Bad Request'; break;
                    case
401: $text = 'Unauthorized'; break;
                    case
402: $text = 'Payment Required'; break;
                    case
403: $text = 'Forbidden'; break;
                    case
404: $text = 'Not Found'; break;
                    case
405: $text = 'Method Not Allowed'; break;
                    case
406: $text = 'Not Acceptable'; break;
                    case
407: $text = 'Proxy Authentication Required'; break;
                    case
408: $text = 'Request Time-out'; break;
                    case
409: $text = 'Conflict'; break;
                    case
410: $text = 'Gone'; break;
                    case
411: $text = 'Length Required'; break;
                    case
412: $text = 'Precondition Failed'; break;
                    case
413: $text = 'Request Entity Too Large'; break;
                    case
414: $text = 'Request-URI Too Large'; break;
                    case
415: $text = 'Unsupported Media Type'; break;
                    case
500: $text = 'Internal Server Error'; break;
                    case
501: $text = 'Not Implemented'; break;
                    case
502: $text = 'Bad Gateway'; break;
                    case
503: $text = 'Service Unavailable'; break;
                    case
504: $text = 'Gateway Time-out'; break;
                    case
505: $text = 'HTTP Version not supported'; break;
                    default:
                        exit(
'Unknown http status code "' . htmlentities($code) . '"');
                    break;
                }
$protocol = (isset($_SERVER['SERVER_PROTOCOL']) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0');header($protocol . ' ' . $code . ' ' . $text);$GLOBALS['http_response_code'] = $code;

            } else {

$code = (isset($GLOBALS['http_response_code']) ? $GLOBALS['http_response_code'] : 200);

            }

            return

$code;

        }
    }

?>

In this example I am using $GLOBALS, but you can use whatever storage mechanism you like... I don't think there is a way to return the current status code:

https://bugs.php.net/bug.php?id=52555

For reference the error codes I got from PHP's source code:

http://lxr.php.net/opengrok/xref/PHP_5_4/sapi/cgi/cgi_main.c#354

And how the current http header is sent, with the variables it uses:

http://lxr.php.net/opengrok/xref/PHP_5_4/main/SAPI.c#856

Stefan W

8 years ago


Note that you can NOT set arbitrary response codes with this function, only those that are known to PHP (or the SAPI PHP is running on).

The following codes currently work as expected (with PHP running as Apache module):
200 – 208, 226
300 – 305, 307, 308
400 – 417, 422 – 424, 426, 428 – 429, 431
500 – 508, 510 – 511

Codes 0, 100, 101, and 102 will be sent as "200 OK".

Everything else will result in "500 Internal Server Error".

If you want to send responses with a freestyle status line, you need to use the `header()` function:

<?php header("HTTP/1.0 418 I'm A Teapot"); ?>

Thomas A. P.

7 years ago


When setting the response code to non-standard ones like 420, Apache outputs 500 Internal Server Error.

This happens when using header(0,0,420) and http_response_code(420).
Use header('HTTP/1.1 420 Enhance Your Calm') instead.

Note that the response code in the string IS interpreted and used in the access log and output via http_response_code().

Anonymous

9 years ago


Status codes as an array:

<?php
$http_status_codes
= array(100 => "Continue", 101 => "Switching Protocols", 102 => "Processing", 200 => "OK", 201 => "Created", 202 => "Accepted", 203 => "Non-Authoritative Information", 204 => "No Content", 205 => "Reset Content", 206 => "Partial Content", 207 => "Multi-Status", 300 => "Multiple Choices", 301 => "Moved Permanently", 302 => "Found", 303 => "See Other", 304 => "Not Modified", 305 => "Use Proxy", 306 => "(Unused)", 307 => "Temporary Redirect", 308 => "Permanent Redirect", 400 => "Bad Request", 401 => "Unauthorized", 402 => "Payment Required", 403 => "Forbidden", 404 => "Not Found", 405 => "Method Not Allowed", 406 => "Not Acceptable", 407 => "Proxy Authentication Required", 408 => "Request Timeout", 409 => "Conflict", 410 => "Gone", 411 => "Length Required", 412 => "Precondition Failed", 413 => "Request Entity Too Large", 414 => "Request-URI Too Long", 415 => "Unsupported Media Type", 416 => "Requested Range Not Satisfiable", 417 => "Expectation Failed", 418 => "I'm a teapot", 419 => "Authentication Timeout", 420 => "Enhance Your Calm", 422 => "Unprocessable Entity", 423 => "Locked", 424 => "Failed Dependency", 424 => "Method Failure", 425 => "Unordered Collection", 426 => "Upgrade Required", 428 => "Precondition Required", 429 => "Too Many Requests", 431 => "Request Header Fields Too Large", 444 => "No Response", 449 => "Retry With", 450 => "Blocked by Windows Parental Controls", 451 => "Unavailable For Legal Reasons", 494 => "Request Header Too Large", 495 => "Cert Error", 496 => "No Cert", 497 => "HTTP to HTTPS", 499 => "Client Closed Request", 500 => "Internal Server Error", 501 => "Not Implemented", 502 => "Bad Gateway", 503 => "Service Unavailable", 504 => "Gateway Timeout", 505 => "HTTP Version Not Supported", 506 => "Variant Also Negotiates", 507 => "Insufficient Storage", 508 => "Loop Detected", 509 => "Bandwidth Limit Exceeded", 510 => "Not Extended", 511 => "Network Authentication Required", 598 => "Network read timeout error", 599 => "Network connect timeout error");
?>

Source: Wikipedia "List_of_HTTP_status_codes"

viaujoc at videotron dot ca

2 years ago


Do not mix the use of http_response_code() and manually setting  the response code header because the actual HTTP status code being returned by the web server may not end up as expected. http_response_code() does not work if the response code has previously been set using the header() function. Example:

<?php
header
('HTTP/1.1 401 Unauthorized');
http_response_code(403);
print(
http_response_code());
?>

The raw HTTP response will be (notice the actual status code on the first line does not match the printed http_response_code in the body):

HTTP/1.1 401 Unauthorized
Date: Tue, 24 Nov 2020 13:49:08 GMT
Server: Apache
Connection: Upgrade, Keep-Alive
Keep-Alive: timeout=5, max=100
Transfer-Encoding: chunked
Content-Type: text/html; charset=UTF-8

403

I only tested it on Apache. I am not sure if this behavior is specific to Apache or common to all PHP distributions.

Anonymous

8 years ago


You can also create a enum by extending the SplEnum class.
<?php/** HTTP status codes */
class HttpStatusCode extends SplEnum {
    const
__default = self::OK;

        const

SWITCHING_PROTOCOLS = 101;
    const
OK = 200;
    const
CREATED = 201;
    const
ACCEPTED = 202;
    const
NONAUTHORITATIVE_INFORMATION = 203;
    const
NO_CONTENT = 204;
    const
RESET_CONTENT = 205;
    const
PARTIAL_CONTENT = 206;
    const
MULTIPLE_CHOICES = 300;
    const
MOVED_PERMANENTLY = 301;
    const
MOVED_TEMPORARILY = 302;
    const
SEE_OTHER = 303;
    const
NOT_MODIFIED = 304;
    const
USE_PROXY = 305;
    const
BAD_REQUEST = 400;
    const
UNAUTHORIZED = 401;
    const
PAYMENT_REQUIRED = 402;
    const
FORBIDDEN = 403;
    const
NOT_FOUND = 404;
    const
METHOD_NOT_ALLOWED = 405;
    const
NOT_ACCEPTABLE = 406;
    const
PROXY_AUTHENTICATION_REQUIRED = 407;
    const
REQUEST_TIMEOUT = 408;
    const
CONFLICT = 408;
    const
GONE = 410;
    const
LENGTH_REQUIRED = 411;
    const
PRECONDITION_FAILED = 412;
    const
REQUEST_ENTITY_TOO_LARGE = 413;
    const
REQUESTURI_TOO_LARGE = 414;
    const
UNSUPPORTED_MEDIA_TYPE = 415;
    const
REQUESTED_RANGE_NOT_SATISFIABLE = 416;
    const
EXPECTATION_FAILED = 417;
    const
IM_A_TEAPOT = 418;
    const
INTERNAL_SERVER_ERROR = 500;
    const
NOT_IMPLEMENTED = 501;
    const
BAD_GATEWAY = 502;
    const
SERVICE_UNAVAILABLE = 503;
    const
GATEWAY_TIMEOUT = 504;
    const
HTTP_VERSION_NOT_SUPPORTED = 505;
}

divinity76 at gmail dot com

2 years ago


if you need a response code not supported by http_response_code(), such as WebDAV / RFC4918's "HTTP 507 Insufficient Storage", try:

<?php
header
($_SERVER['SERVER_PROTOCOL'] . ' 507 Insufficient Storage');
?>
result: something like

HTTP/1.1 507 Insufficient Storage

Rob Zazueta

9 years ago


The note above from "Anonymous" is wrong. I'm running this behind the AWS Elastic Loadbalancer and trying the header(':'.$error_code...) method mentioned above is treated as invalid HTTP.

The documentation for the header() function has the right way to implement this if you're still on < php 5.4:

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

Anonymous

10 years ago


If you don't have PHP 5.4 and want to change the returned status code, you can simply write:
<?php
header
(':', true, $statusCode);
?>

The ':' are mandatory, or it won't work

Steven

7 years ago


http_response_code is basically a shorthand way of writing a http status header, with the added bonus that PHP will work out a suitable Reason Phrase to provide by matching your response code to one of the values in an enumeration it maintains within php-src/main/http_status_codes.h. Note that this means your response code must match a response code that PHP knows about. You can't create your own response codes using this method, however you can using the header method.

In summary - The differences between "http_response_code" and "header" for setting response codes:

1. Using http_response_code will cause PHP to match and apply a Reason Phrase from a list of Reason Phrases that are hard-coded into the PHP source code.

2. Because of point 1 above, if you use http_response_code you must set a code that PHP knows about. You can't set your own custom code, however you can set a custom code (and Reason Phrase) if you use the header method.

Richard F.

9 years ago


At least on my side with php-fpm and nginx this method does not change the text in the response, only the code.

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

The resulting response is HTTP/1.1 404 OK

stephen at bobs-bits dot com

8 years ago


It's not mentioned explicitly, but the return value when SETTING, is the OLD status code.
e.g.
<?php

$a

= http_response_code();
$b = http_response_code(202);
$c = http_response_code();var_dump($a, $b, $c);// Result:
// int(200)
// int(200)
// int(202)
?>

Chandra Nakka

5 years ago


On PHP 5.3 version, If you want to set HTTP response code. You can try this type of below trick :)

<?php

header

('Temporary-Header: True', true, 404);
header_remove('Temporary-Header');?>

yefremov {dot} sasha () gmail {dot} com

8 years ago


@craig at craigfrancis dot co dot uk@ wrote the function that replaces the original. It is very usefull, but has a bug. The original http_response_code always returns the previous or current code, not the code you are setting now. Here is my fixed version. I also use $GLOBALS to store the current code, but trigger_error() instead of exit. So now, how the function will behave in the case of error lies on the error handler. Or you can change it back to exit().

if (!function_exists('http_response_code')) {
    function http_response_code($code = NULL) {    
        $prev_code = (isset($GLOBALS['http_response_code']) ? $GLOBALS['http_response_code'] : 200);

        if ($code === NULL) {
            return $prev_code;
        }

        switch ($code) {
            case 100: $text = 'Continue'; break;
            case 101: $text = 'Switching Protocols'; break;
            case 200: $text = 'OK'; break;
            case 201: $text = 'Created'; break;
            case 202: $text = 'Accepted'; break;
            case 203: $text = 'Non-Authoritative Information'; break;
            case 204: $text = 'No Content'; break;
            case 205: $text = 'Reset Content'; break;
            case 206: $text = 'Partial Content'; break;
            case 300: $text = 'Multiple Choices'; break;
            case 301: $text = 'Moved Permanently'; break;
            case 302: $text = 'Moved Temporarily'; break;
            case 303: $text = 'See Other'; break;
            case 304: $text = 'Not Modified'; break;
            case 305: $text = 'Use Proxy'; break;
            case 400: $text = 'Bad Request'; break;
            case 401: $text = 'Unauthorized'; break;
            case 402: $text = 'Payment Required'; break;
            case 403: $text = 'Forbidden'; break;
            case 404: $text = 'Not Found'; break;
            case 405: $text = 'Method Not Allowed'; break;
            case 406: $text = 'Not Acceptable'; break;
            case 407: $text = 'Proxy Authentication Required'; break;
            case 408: $text = 'Request Time-out'; break;
            case 409: $text = 'Conflict'; break;
            case 410: $text = 'Gone'; break;
            case 411: $text = 'Length Required'; break;
            case 412: $text = 'Precondition Failed'; break;
            case 413: $text = 'Request Entity Too Large'; break;
            case 414: $text = 'Request-URI Too Large'; break;
            case 415: $text = 'Unsupported Media Type'; break;
            case 500: $text = 'Internal Server Error'; break;
            case 501: $text = 'Not Implemented'; break;
            case 502: $text = 'Bad Gateway'; break;
            case 503: $text = 'Service Unavailable'; break;
            case 504: $text = 'Gateway Time-out'; break;
            case 505: $text = 'HTTP Version not supported'; break;
            default:
                trigger_error('Unknown http status code ' . $code, E_USER_ERROR); // exit('Unknown http status code "' . htmlentities($code) . '"');
                return $prev_code;
        }

        $protocol = (isset($_SERVER['SERVER_PROTOCOL']) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0');
        header($protocol . ' ' . $code . ' ' . $text);
        $GLOBALS['http_response_code'] = $code;

        // original function always returns the previous or current code
        return $prev_code;
    }
}

Anonymous

4 years ago


http_response_code() does not actually send HTTP headers, it only prepares the header list to be sent later on.
So you can call http_reponse_code() to set, get and reset the HTTP response code before it gets sent.

Test code:
<php
http_response_code(500);  // set the code
var_dump(headers_sent());  // check if headers are sent
http_response_code(200);  // avoid a default browser page

Kubo2

6 years ago


If you want to set a HTTP response code without the need of specifying a protocol version, you can actually do it without http_response_code():

<?php

header

('Status: 404', TRUE, 404);?>

zweibieren at yahoo dot com

7 years ago


The limited list given by Stefan W is out of date. I have just tested 301 and 302 and both work.

divinity76 at gmail dot com

6 years ago


warning, it does not check if headers are already sent (if it is, it won't *actually* change the code, but a subsequent call will imply that it did!!),

you might wanna do something like
function ehttp_response_code(int $response_code = NULL): int {
    if ($response_code === NULL) {
        return http_response_code();
    }
    if (headers_sent()) {
        throw new Exception('tried to change http response code after sending headers!');
    }
    return http_response_code($response_code);
}

In this tutorial, we are going to show you how to send a “404 Not Found” header using PHP.

This can be especially useful in cases when you need to display a 404 message if a particular database record does not exist.

By sending a 404 HTTP status code to the client, we can tell search engines and other crawlers that the resource does not exist.

To send a 404 to the client, we can use PHP’s http_response_code function like so.

//Send 404 response to client.
http_response_code(404)
//Include custom 404.php message
include 'error/404.php';
//Kill the script.
exit;

Note that this function is only available in PHP version 5.4 and after.

If you are using a PHP version that is older than 5.4, then you will need to use the header function instead.

//Use header function to send a 404
header($_SERVER["SERVER_PROTOCOL"]." 404 Not Found", true, 404);
//Include custom message.
include 'errors/404.php';
//End the script
exit;

In the code above, we.

  1. Send the response code to the client.
  2. We include a PHP file that contains our custom “404 Not Found” error. This file is not mandatory, so feel free to remove it if you want to.
  3. We then terminated the PHP script by calling the exit statement.

If you run one of the code samples above and check the response in your browser’s developer tools, then you will see something like this.

Request URL:http://localhost/test.php
Request Method:GET
Status Code:404 Not Found
Remote Address:[::1]:80
Referrer Policy:no-referrer-when-downgrade

Note the Status Code segment of the server’s HTTP response. This is the 404 header.

When should I use this?

In most cases, your web server will automatically handle 404 errors if a resource does not exist.

However, what happens if your script is dynamic and it selects data from your database? What if you have a dynamic page such as users.php?id=234 and user 234 does not exist?

The file users.php will exist, so your web server will send back a status of “200 OK”, regardless of whether a user with the ID 234 exists or not.

In cases like this, we may need to manually send a 404 Not Found header.

Why isn’t PHP showing the same 404 message as my web server?

You might notice that your web server does not serve its default “404 Not Found” error message when you manually send the header with PHP.

404 Not Found

The default message that Apache displays whenever a resource could not be found.

This is because, as far as the web server is concerned, the file does exist and it has already done its job.

One solution to this problem is to make sure that PHP and your web server display the exact same 404 message.

For example, with Apache, you can specify the path of a custom error message by using the ErrorDocument directive.

ErrorDocument 404 /errors/404.php

The Nginx web server also allows you to configure custom error messages.

В этой статье разберем вопрос, нужно ли ставить перенаправление со страниц index.php сайта.

Подписчик спрашивает: «На сайте index.php отдает 404 ошибку. Что лучше: 301 редирект сделать или пусть остается ошибка 404?»

Для тех, кто не в курсе, расскажу: index.php — это во многих CMS-системах основной исполняемый файл, к которому идет обращение, когда вы только зашли на сайт. Его не всегда видно, технически это может быть сделано так, что этот index.php есть, но обращение к нему идет в скрытом режиме, и вы его в адресной строке не видите. Но он часто имеется.

И почему вообще возник такой вопрос в нашем, посвященном SEO, блоге? Потому что многие CMS-системы, многие движки выдают по адресу index.php ту же самую версию главной страницы, что и без него.

Например, вы заходите на «site.ru» и на «site.ru/index.php» — и получаете одну и ту же страницу. Это плохо, как, в принципе, и все дубли страниц на сайте. А если еще есть и какие-то ссылки на «index.php», заходы, то она может попасть в индекс, и здесь поисковик будет решать, какой вариант ему оставить в индексе: «site.ru» или «site.ru/index.php». К тому же еще и часть внешних ссылок на такую страницу может идти, и если вы ее закроете 404 ошибкой, то эти ссылки просто пропадут — ни вес, ни анкорная составляющая по ним передаваться не будет.

Таким образом, если у вас такая ситуация возникла, то оставлять подобную страницу открытой нельзя, нужно что-то с ней сделать. Но если закроете ее 404, то как уже сказал, те ссылки, которые на нее ведут, пропадут. Либо, в случае, когда она где-то проиндексировалась, стала ранжироваться, по каким-то запросам выходить, и люди начали на нее переходить, тогда, если поставите 404, то все накопленные положительные моменты пропадут: ссылки, которые на нее ведут, поведенческие факторы, которые у нее были, а её возраст не то, чтобы занулиться, но, скажем так, никак не будет помогать вашему сайту.

И даже если она нигде не выходила, но ссылки на нее были, то тоже не очень хорошо, если это всё пропадет. Поэтому 404 я бы не рекомендовал ставить, а лучше 301 редирект, либо чтобы rel canonical на ней стоял. Этот атрибут в блоке <head> страницы ставится, и он указывает на основную версию, вам достаточно просто указать там ваш «site.ru».

И в этих случаях — что в случае 301 редиректа, что в случае rel canonical — все основные параметры, которые шли на ту страницу, факторы, которые могут влиять на продвижение вашей главной страницы: ссылки, которые на нее шли, поведенчески, которые на ней были (если были), возраст, если какой-то накопился — они перетекают на вашу основную. Ну возраст вряд ли будет больше, чем у главной, поэтому в этом смысле можно не сильно беспокоиться, а вот ссылки и поведенческие запросто могут перетечь.

К тому же, если, опять же, есть внешние ссылки, размещенные в таких местах, откуда могут переходить люди, то пользователи могут расстроиться, если там будет выходить 404 ошибка, а так их через редирект перекинет на основную. Поэтому я бы поставил 301 редирект. Тут главное смотреть, чтобы когда вы будете его ставить, у вас ничего не поломалось. Потому что index.php — это важная техническая страница, и если топорно подойти к вопросу, то можно что-то поломать. Потому здесь будьте аккуратнее. В остальном особо секретов никаких нет, и 301 редирект или canonical лучше, чем 404.


Понравилась статья? Поделить с друзьями:
  • Ошибка 404 но при этом страница существует
  • Ошибка 404 гугл что это такое
  • Ошибка 404 ничего не найдено
  • Ошибка 404 выдавать мою страницу
  • Ошибка 404 нет такой страницы яндекс как исправить