Php как правильно обработать ошибку 404

These are all great answers for redirecting to 404 error, for a single page. Here’s a solution that will allow you to test a condition and redirect for any script on your site.

Write up a .htaccess file, with the rewrite rules, and using [QSA,NC,L] to maintain the page location and the header post/get arguments…

RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php [QSA,NC,L]

This will cause every page to redirect to ./index.php (feel free to rename this if you’re already using an index.php). The URL will not be changed. Then, in index.php, check some condition, and if passes, include the $_SERVER variable indicating the script, otherwise, do a custom 404. This means you can simply control the exception handling in index.php with…

$someNon404Condition = file_exists($_SERVER['PHP_SELF']);
if ($someNon404Condition) {
    include($_SERVER['PHP_SELF']);   // do the stuff
} else {
    print("404!  Why are you trying to access " . $_SERVER['PHP_SELF'] . "?");
}

This lets you do tons of other things, too! Forget a static 404.html page, with a dynamic one you can…

  • Your condition can be as complicated as you can code: check authentication, check for permanent redirects, maybe you want to expire content automatically? Etc., etc..
  • Search your DB for explode('/', $_SERVER['PHP_SELF']), and then display a list of those matched results under the header «Maybe this is what you were looking for?»
  • Respond to user-level events: Is it a 404 because the page was moved? Then handle a redirect. Is it a 404 because a moderator deleted it and it was the user’s post? Tell the user a moderator deleted their post. Etc., etc..
  • Make API calls, dynamic code, etc., etc., the possibilities are there.

Essentially, what I am doing is intercepting a 404 using ErrorDocument in .htaccess, and pointing it at getFile.php. getFile then grabs the file name out of the url and searches for it in the mysql database, getting the data and applying appropriate headers.

In my dev environment (up-to-date LAMP server running under ubuntu) everything seems to work fine, but the site is being hosted on GoDaddy, and there seems to be some issue with the headers returned. I think GoDaddy returns a 404, then sends the data anyway.

The result is when I right click on a link that is to be handled in this manner, I can ‘Save As’, and everything works fine. If the file is an image, it opens no problem. But if I just click the link and it is a file that is to be downloaded rather than viewed in a browser, I get ‘File Not Found’ errors, across all browsers. Firebug Console claims it is a 404 error, regardless of whether the file successfully transfers. My code is the following:

$folder = explode( "/" , $_SERVER["REQUEST_URI"] );
$pageName = $folder[sizeof($folder)-1];

$sql = "SELECT data, mimeType, OCTET_LENGTH(data) AS size FROM tblFiles WHERE fileName = '".$pageName."' AND active=1;";

$result = mysql_query("$sql") or die();

$data = mysql_fetch_array($result);

header("HTTP/1.0 200 OK");
header("Content-Type: ".$data['mimeType']);
header("Content-Length: ".$data['size']);

echo $data['data'];

And the .htaccess file:

ErrorDocument 404 /FILES/dbFiles/getFile.php

Now this is the full .htaccess file present at /FILES/dbFiles. I don’t know if GoDaddy is expecting more stuff in there, but it seems to work just as written on my own server.

I’ve tried numerous combinations of header info with no positive effect.

My code apparently works, but I can’t seem to prevent that 404 from happening.

Thanks!
-Jer

(PHP 5 >= 5.4.0, PHP 7, PHP

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.

Закрытие

2

×

Дополнительные материалы бесплатно предоставляются только зарегистрированным пользователям.

Для скачивания исходных файлов необходимо авторизоваться под своим аккаунтом через соответствующую форму.

Для тех кто не зарегистрирован, можно это сделать на вкладке Регистрация.

Статья сборника Как установить графический редактор GIMP

Устанавливаем графический редактор GIMP

  1. Выбор графического редактора
  2. Устанавливаем программу GIMP
  3. Устанавливаем Руководство пользователя


Здравствуйте уважаемый посетитель!

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

В статье Устанавливаем бесплатный графический редактор GIMP речь пойдет о бесплатной программе GIMP, которая позволяет в полной мере решать вопросы по созданию элементов дизайна веб-страниц. И будет показано, как ее установить на локальный компьютер.

Кроме того здесь можно будет посмотреть, как в этот редактор добавить встроенное «Руководство пользователя», а также приведен бесплатный видеокурс, где можно поближе с ним познакомиться.

Для тех же, кто хочет заниматься дизайном на платном Adobe Photoshop (фотошоп), здесь также упомянут и такой вариант, основанный на использовании продления льготного бесплатного периода фотошопа на неопределенное время…

    Cайт на практическом примере

    Текущее состояние создаваемого сайта

    Здесь можно посмотреть текущее состояние сайта, создаваемого в рамках цикла статей Самописный сайт с нуля своими руками.

    Исходные файлы данного сайта можно скачать из прилагаемых к статьям дополнительных материалов.

    • Предыдующая статья: Делаем выпадающее меню на CSS

    Лого sayt-sozdat.ru

    2019-10-23

    Здравствуйте, уважаемый посетитель!

    Этой статьей начинается новый раздел, в котором будет рассматриваться достаточно важный вопрос, без решения чего невозможно обеспечить нормальное функционирование любого сайта. Речь идет об обработке ошибочных ситуаций на стороне веб-сервера при выполнении PHP, а также статуса протокола HTTP с кодом 404.

    В частности, здесь мы рассмотрим три, наиболее часто, встречающихся случая возникновения ошибок:

    1. ошибка 404, возникающая в отсутствии запрашиваемого ресурса на сайте, что соответствует статусу 404 (Not Found) протокола HTTP;
    2. ошибка 500, которая может быть вызвана, как фатальными ошибками PHP, приводящими к прекращению работы скрипта, так и другими критическими ситуациями, соответствующими внутренней ошибки сервера (Internal Server Error);
    3. не фатальные (предупреждения) ошибки PHP, которые не останавливают работу скрипта и не оказывают какого-либо существенного влияния формирование страницы, но требуют определенных действий по их перехвату, сохранению и анализу, а также скрытию сообщений об ошибках на страницах сайта.

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

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

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

    • Ошибка 404 (Not Found) статуса HTTP
    • Внутренняя ошибка сервера 500 (Internal Server Error)
    • Не фатальные (предупреждающие) ошибки PHP
    • Сохранение лог-файлов ошибок
    • Автоматическая отправка почтовых сообщений при критических ошибках

    Ошибка 404 (Not Found) статуса HTTP


    В большинстве случаев ошибка с кодом 404 (Not Found) протокола HTTP может возникать по следующим причинам:

    • ошибки в URL, которые допускают пользователи при непосредственном вводе ссылок в адресном поле браузера;
    • внешние неверные ссылки, указывающие на несуществующие страницы сайта;
    • наличие внутренних битых ссылок на отсутствующие на сайте ресурсы, включая изображения и другие файлы, используемые при формировании веб-страниц;
    • неправильный редирект на страницу, которая сменила адрес;

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

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

    • доверие пользователей — по мере использования сайта посетитель привыкает к его дизайну. В случае появления технической страницы 404, отличающейся от привычного дизайна сайта, вряд ли у пользователя улучшиться от этого впечатление. А скорей всего, наоборот, возникнет определенное недоверие к такому ресурсу;
    • поведение пользователей — на своей странице можно расположить ссылки на разделы сайта и наиболее популярные материалы. Поэтому, если пользователь попав на такую страницу, не закроет ее покинув сайт, а продолжит пользоваться имеющимся в нем контентом, то это будет благоприятно сказываться на поведенческом факторе.

    Для примера ниже показана скриншот страницы 404, которая используется здесь на сайте. Где видно, что попав на нее, пользователь с легкостью сможет и дальше пользоваться сайтом не покидая его.

    Пример страницы 404

    Рис.1 Пример страницы 404

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

    Помимо этого, для поисковой оптимизации, необходимо правильно обрабатывать такого вида ошибки, отправляя в ответах сервера код, соответствующий статусу протокола HTTP 404 (Not Found), а не 200 (OK) или какой-либо другой.

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

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

    А далее, хорошим решением будет, сохранять полученную информацию в логах и отправлять сообщения по почте, сигнализируя администратору сайта, о том, что с ресурсами сайта не все в порядке, отчего требуется оперативное вмешательство. Подробнее об этом будет рассказано чуть позднее в других разделах статьи.

    Внутренняя ошибка сервера 500 (Internal Server Error)


    Внутренняя ошибка сервера 500 (Internal Server Error) — второй вид ошибок, которому здесь будет уделено внимание. В основном это фатальные ошибки PHP, при которых работа скрипта прекращается, что вызывает невозможность полноценного отображения и функционирования страницы. К этой категории можно отнести следующие виды:

    • E_ERROR — ошибка при невозможности выполнения скрипта, например, вызов несуществующей функции, ошибка распределения памяти и т.п.;
    • E_PARSE — в случае грубой ошибки синтаксиса, при которой интерпретатор PHP не может определить, какие действия требуется выполнить;
    • E_CORE_ERROR — ошибки, которые происходят во время запуска РНР;
    • E_COMPILE_ERROR — ошибки на этапе компиляции.

    Кроме этого ошибка 500 может возникать и в других случаях, относящихся к внутренней ошибке сервера. Например, причиной, при котором сервер выдает статус 500 может быть и простая ошибка синтаксиса файла .htaccess.

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

    Однако, работа в PHP при возникновении фатальных ошибок имеет свои особенности, так как в этих случаях выполнение скрипта останавливается. И для того, чтобы определить ошибку, которая привела к его остановке, требуются определенные действия.

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

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

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

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

    Пример страницы 500

    Рис.2 Пример страницы ошибки 500

    Можно обратить внимание, что страница ошибки 500 отличается от предыдущей тем, что в ней отсутствуют некоторые блоки сайта. Обусловлено это тем, что она намерена создана с использованием только элементов HTML без какого-либо использования кода PHP.

    Не фатальные (предупреждающие) ошибки PHP


    Другой вид ошибок PHP — не фатальные при которых не происходит прекращение работы скрипта. К этой категории относятся такие предопределенные константы, как: E_WARNING, E_NOTICE, E_CORE_WARNING, E_COMPILE_WARNING, E_USER_WARNING, E_USER_NOTICE, E_STRICT, E_DEPRECATED, E_USER_DEPRECATED, с описанием которых можно ознакомиться здесь.

    скриншот 76

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

    • задание уровня протоколирования ошибок;
    • запрет вывода сообщений об ошибках для пользователя в целях безопасности и недопущения злоумышленников к излишней информации о сайте;
    • перехват некритичных ошибок для возможности их анализа;
    • сохранение информации об ошибках в лог-файлах.

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

    Остальные же действия по задание их уровня и запрещению вывода сообщений на страницу будут определяться настройкой конфигурации протоколирования ошибок во время выполнения, которую можно изменить с помощью использования функции ini_set() с нужными параметрами, либо соответствующими директивами файла .htaccess.

    Сохранение лог-файлов ошибок


    В PHP существует встроенный механизм сохранения отчета об ошибочных ситуациях в PHP в журнал ошибок сервера, или в какой-либо другой файл, назначенный в настройках конфигурации протоколирования ошибок.

    Однако существует и другое, на мой взгляд, более удобное решение — это сохранение всех возникающих при работе сайта ошибок в отдельные лог-файлы в зависимости от их вида. Тем более при таком подходе можно создавать журналы не только для ошибок PHP, но и для других ошибочных ситуаций.

    В нашем случае при создании механизма обработки ошибок будет предусмотрено сохранение отчета по следующим категориям:

    • запрос к несуществующим ресурсам сайта (ошибка 404) при переходе с внутренних ссылок;
    • все остальные случаи ошибки 404 при запросах с внешних ссылок;
    • фатальные ошибки PHP;
    • не фатальные ошибки PHP;

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

    Автоматическая отправка почтовых сообщений при критических ошибках


    И последняя функциональная возможность, которая будет использована в создаваемом механизме, это автоматическая отправка почтовых сообщений в случае возникновения серьезных проблем в работе сайта.

    К таким случаям будут отнесены два, наиболее значимых вида ошибок:

    • фатальные ошибки PHP;
    • запрос к несуществующим ресурсам сайта (ошибка 404) при переходе с внутренних ссылок;

    По поводу фатальных ошибок PHP, наверное, не возникает вопроса, почему на их появление следует оперативно реагировать.

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

    И при практическом рассмотрении этого вопроса мы посмотрим примеры, как из почтовых сообщений можно увидеть, когда на какой-либо странице возникает битая ссылка на несуществующую страницу. А также случаи с обнаружением переходов на другие ресурсы, которых по каким-либо причинам, в действительности, нет на сайта. Например, при теге , в котором в атрибуте src задан путь к несуществующему файлу изображения.

    Ниже показан скриншот такого почтового сообщения из реальной жизни.

    Пример почтового сообщения об ошибке 404

    Рис.2 Пример почтового сообщения об ошибке 404

    Таким образом, здесь перечислены в общем виде все те функциональные возможности, которыми будет обладать рассматриваемая система обработки ошибок. А что использовать, каждый будет волен для себя решить сам.

    Далее мы перейдем к практической реализации всего сказанного, и в первую очередь рассмотрим обработку запросов на несуществующие ресурсы сайта, что соответствует коду 404 статуса HTTP.

    С уважением,

    • Следующая сатья: Делаем собственную страницу ошибки 404

    Если у Вас возникли вопросы, или есть какие-либо пожелания по представлению материала, либо заметили какие-нибудь ошибки, а быть может просто хотите выразить свое мнение, пожалуйста, оставьте свои комментарии. Такая обратная связь очень важна для возможности учета мнения посетителей.

    Буду Вам за это очень признателен!

    • Главная»
    • Уроки»

    • PHP»

    • Создаем единую страницу для обработки ошибок
    • Метки урока:
    • php
    • кодинг
    • разное

    Создаем единую страницу для обработки ошибок

    В данном уроке представлено очень простое решение для обработки различных ошибок HTTP, таких как 404, 500 и так далее, в одном файле PHP. Нужно создать массив кодов ошибок и установить правила перенаправления на наш PHP файл. То есть, можно использовать одну страницу для обработки нескольких ошибок.

    Перенаправление

    В файле .htaccess вашего сервера нужно установить правила для обработки ошибок. В нашем случае мы будем перенаправлять все ошибки в наш файл errors.php, который будет формировать страницу HTML для посетителя. Добавляем в файл .htaccess следующие правила:

    ErrorDocument 400 /errors.php
    ErrorDocument 403 /errors.php
    ErrorDocument 404 /errors.php
    ErrorDocument 405 /errors.php
    ErrorDocument 408 /errors.php
    ErrorDocument 500 /errors.php
    ErrorDocument 502 /errors.php
    ErrorDocument 504 /errors.php
    

    PHP

    Теперь создаем файл errors.php, который должен располагаться в корневом каталоге вашего сервера (так как такое его местоположение установлено в заданных нами выше правилах в файле .htaccess).

    $status = $_SERVER['REDIRECT_STATUS'];
    $codes = array(
           400 => array('400 Плохой запрос', 'Запрос не может быть обработан из-за синтаксической ошибки.'),
           403 => array('403 Запрещено', 'Сервер отказывает в выполнении вашего запроса.'),
           404 => array('404 Не найдено', 'Запрашиваемая страница не найдена на сервере.'),
           405 => array('405 Метод не допускается', 'Указанный в запросе метод не допускается для заданного ресурса.'),
           408 => array('408 Время ожидания истекло', 'Ваш браузер не отправил информацию на сервер за отведенное время.'),
           500 => array('500 Внутренняя ошибка сервера', 'Запрос не может быть обработан из-за внутренней ошибки сервера.'),
           502 => array('502 Плохой шлюз', 'Сервер получил неправильный ответ при попытке передачи запроса.'),
           504 => array('504 Истекло время ожидания шлюза', 'Вышестоящий сервер не ответил за установленное время.'),
    );
     
    $title = $codes[$status][0];
    $message = $codes[$status][1];
    if ($title == false || strlen($status) != 3) {
           $message = 'Код ошибки HTTP не правильный.';
    }
     
    echo '<h1>Внимание! Обнаружена ошибка '.$title.'!</h1>
    <p>'.$message.'</p>';
    

    Готово!

    Конечно, код PHP может формировать и более информативную страницу для пользователя. При формировании разметки стоит учесть рекомендации для страниц, выводящих информацию об ошибках.


    5 последних уроков рубрики «PHP»

    • Фильтрация данных с помощью zend-filter

      Когда речь идёт о безопасности веб-сайта, то фраза «фильтруйте всё, экранируйте всё» всегда будет актуальна. Сегодня поговорим о фильтрации данных.

    • Контекстное экранирование с помощью zend-escaper

      Обеспечение безопасности веб-сайта — это не только защита от SQL инъекций, но и протекция от межсайтового скриптинга (XSS), межсайтовой подделки запросов (CSRF) и от других видов атак. В частности, вам нужно очень осторожно подходить к формированию HTML, CSS и JavaScript кода.

    • Подключение Zend модулей к Expressive

      Expressive 2 поддерживает возможность подключения других ZF компонент по специальной схеме. Не всем нравится данное решение. В этой статье мы расскажем как улучшили процесс подключение нескольких модулей.

    • Совет: отправка информации в Google Analytics через API

      Предположим, что вам необходимо отправить какую-то информацию в Google Analytics из серверного скрипта. Как это сделать. Ответ в этой заметке.

    • Подборка PHP песочниц

      Подборка из нескольких видов PHP песочниц. На некоторых вы в режиме online сможете потестить свой код, но есть так же решения, которые можно внедрить на свой сайт.

    Понравилась статья? Поделить с друзьями:
  • Php вывод ошибок в переменную
  • Php вывод ошибок в консоли
  • Php вывод ошибок в html
  • Php вывести ошибку в файл
  • Php вывести ошибку в div