Как обрабатывать уведомления, предупреждения и ошибки php в REST api?

В REST API ответ 200 показывает успешную операцию. PHP по умолчанию выводит сообщение об ошибке непосредственно в тело ответа без изменения кода ответа. В СПА текст ответа не отображается непосредственно пользователю. Поэтому, когда приложение не работает должным образом, я проверяю тело ответа через FireBug, чтобы проверить возможные исключения PHP (которые вызывают недействительный ответ json). Есть ли способ отправить определенный HTTP-код на все ошибки PHP?

Есть ли способ изменить код ответа HTTP в соответствии с существованием любых ошибок PHP? Или, возможно, взять текст ошибки и отправить его в формате json без проблем. (в стадии разработки)

Обновление: Исключение Catching (try/catch/final) - это не то, что я ищу.

Ответ 1

Конечно, вы можете изменить статус HTTP в PHP:

<?php 
   header("HTTP/1.1 502 Bad Gateway");
?> 

Вы можете изменить сообщение и код, но вы должны быть осторожны с стандартными кодами

Ответ 2

Скажем, например, что вас беспокоят только фатальные ошибки во время выполнения, фатальные ошибки времени компиляции и предупреждения во время выполнения. Установите отчет об ошибках на желаемый уровень с помощью функции error_reporting().

error_reporting( E_ERROR | E_COMPILE_ERROR | E_WARNING );

Поскольку пользовательский обработчик ошибок (позже ниже) не может обрабатывать фатальные ошибки, будут отображаться фатальные сообщения об ошибках. Чтобы избежать использования функции ini_set() и установите для параметра display_errors значение 0.

ini_set( 'display_errors', 0 );

Теперь создайте собственный обработчик ошибок с set_error_handler(), чтобы полностью обойти обработчик ошибок PHP для указанных типов ошибок (не относится к фатальным ошибкам).

/* The following error types cannot be handled with a user defined function: 
 *  E_ERROR, E_PARSE, E_CORE_ERROR, E_CORE_WARNING, E_COMPILE_ERROR, E_COMPILE_WARNING
 * The standard PHP error handler is completely bypassed for the error types specified
 *  unless the callback function returns FALSE.
 */
function exception_error_handler( $severity, $message, $file, $line ) 
{
    if ( !( error_reporting() & $severity ) ) {
        // This error code is not included in error_reporting
        return;
    }

    // code for handling errors
}
set_error_handler( "exception_error_handler" );

Неустранимые ошибки могут быть обработаны при завершении работы с помощью register_shutdown_function(). Обработчик завершения работы выполняется после завершения script или завершается (это также относится к ошибкам). Нам нужно получить информацию о последней произошедшей ошибке (error_get_last()), а затем проверить, является ли это типом ошибки, которую мы track (что здесь действительно не требуется, поскольку ошибки, которые не указаны в error_reporting, не будут запущены, но может быть полезно для фильтрации ошибок), и, наконец, вызовите обработчик исключений.

function fatal_error_shutdown() 
{
    $last_error = error_get_last();
    if ( error_reporting() & $last_error['type'] )
        call_user_func_array( 'exception_error_handler', $last_error );
}
register_shutdown_function( 'fatal_error_shutdown' );

Теперь вы можете использовать собственный обработчик исключений, чтобы поймать необработанные исключения (в том числе фатальные) и заставить код ответа (с помощью header()).

Ответ 3

Используйте фреймворк или библиотеку обработчика ошибок.

В зависимости от того, какую структуру вы выберете, вы можете настроить, как этот обработчик ошибок представляет ошибки. Обработчик ошибок, с которым я связан, по-видимому, поддерживает сериализацию ошибок в JSON по умолчанию, вы должны проверить его документацию.

С рамкой, здесь пример для Laravel 4:

App::error(function(Exception $exception, $code) {
    Log::error($exception);
    return Response::json(["code" => $code, "message" => $exception->getMessage()], $code);
});

Обратите внимание, что если вы полагаетесь на глобальный обработчик ошибок, как правило, проблема в другом месте - вы не должны полагаться на нее для обработки своих ошибок; вместо этого используйте try/catch, где это необходимо.

Ответ 4

set_error_handler функция - это то, что я пропустил. Я придумал следующий код. Любой лучший ответ приветствуется.

function jsonErrorHandler()
{
   if (error_reporting()) {

        http_response_code(500);
        header('Content-Type: application/json; charset=utf-8');
        $response = array_combine(['errno', 'errstr', 'errfile', 'errline', 'errcontext'], func_get_args());
        die(json_encode($response));

  }
}

set_error_handler('jsonErrorHandler');

Ответ 5

Хотя какая-то часть вашего вопроса ответила здесь Возврат кодов статуса http с апитом-априори

Я бы предложил не отправлять другой http-код для многих предупреждений, ошибок и уведомлений. Необходимо выполнить внутреннюю ошибку сервера 500 (http code 500), и вам не нужно подвергать специфику ошибки вашим потребителям API. Конечно, вы можете регистрировать все ошибки/уведомления/предупреждения для отладки и исправления вашего приложения.

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

Ответ 6

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

Ответ 7

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

PHP имеет несколько функций для изменения кода состояния, я бы рекомендовал http_response_code(), поскольку он проще в использовании: вам нужно только отправьте код состояния HTTP, и он напишет вам полный заголовок.

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

function log_error($errno, $errstr, $errfile = '', $errline = 0, $errcontext = array())
{
    // Save the error to the error log.
    // You may want to add more information than $errstr in the log, so feel free to change this line.
    error_log($errstr);

    // If headers haven't been sent, you can set a new one.
    if (!headers_sent())
    {
        // 500 is the most generic error when the error comes from your application.
        http_response_code(500);

        // Checking if you're in debug mode allows you to show you errors while developping, and hiding them for users.
        // Change this line by your own checks.
        if (IS_DEBUG)
        {
            // Send the correct Content-Type header.
            header('Content-Type: application/json; charset=utf-8');

            // Sending information about the error.
            echo json_encode(array(
                'error' => $errstr // Once again, you may want to add more information.
            ));

            // Exiting since we do not want the script to continue.
            exit;
        }
        else
        {
            // Do whatever you want here, it will be shown to your users if you're not in debug mode.
            // But do not forget to exit.
            exit;
        }
    }
}

// Setting your function as an error handler.
set_error_handler('error_handler');

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

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

Ответ 8

В Yii Framework, обработка таких вопросов очень эффективно.

Они использовали PHP set_exception_handler ('exceptionHandlerFunction') и set_error_handler ( 'errorHandlerFunction'), чтобы обрабатывать все типы исключений и ошибок (предупреждения, уведомления).

В FATAL Error, register_shutdown_function ('fatalHandlerFunction')

Теперь, для демонстрации, Yii работает очень эффективно.

В функции error/exception/fatal handler, до конфигурации, чтобы либо выбросить ошибку на клиентскую сторону, либо отобразить хорошо отформатированную ошибку.

Если вы хотите отобразить хорошо отформатированный, Yii передает маршрут на действие SystemController Error.

Вы также можете выполнить Как обрабатывать ошибки Yii.

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