Подтвердить что ты не робот

Чистый способ бросить исключение php через jquery/ajax и json

Есть ли простой и простой способ бросить исключения php через jQuery-ответ jquery/ajax.

4b9b3361

Ответ 1

Вы можете сделать что-то подобное в PHP (предполагая, что это вызвано через AJAX):

<?php

try {
    if (some_bad_condition) {
        throw new Exception('Test error', 123);
    }
    echo json_encode(array(
        'result' => 'vanilla!',
    ));
} catch (Exception $e) {
    echo json_encode(array(
        'error' => array(
            'msg' => $e->getMessage(),
            'code' => $e->getCode(),
        ),
    ));
}

В JavaScript:

$.ajax({
    // ...
    success: function(data) {
        if (data.error) {
            // handle the error
            throw data.error.msg;
        }
        alert(data.result);
    }
});

Вы также можете запустить обработчик error: $.ajax(), возвращая заголовок 400 (например):

header('HTTP/1.0 400 Bad error');

Или используйте Status:, если вы находитесь в FastCGI. Обратите внимание, что обработчик error: не получает данные об ошибке; для выполнения этого вы должны переопределить, как работает $.ajax():)

Ответ 2

Facebook что-то делает в своем SDK для PHP, где они генерируют исключение, если по какой-либо причине HTTP-запрос завершился с ошибкой. Вы можете воспользоваться этим подходом и просто вернуть данные об ошибках и исключениях, если выбрано исключение:

<?php

header('Content-Type: application/json');

try {
    // something; result successful
    echo json_encode(array(
        'results' => $results
    ));
}
catch (Exception $e) {
    echo json_encode(array(
        'error' => array(
            'code' => $e->getCode(),
            'message' => $e->getMessage()
        )
    ));
}

Затем вы можете просто прослушать клавишу error в ваших вызовах AJAX в JavaScript:

<script>
    $.getJSON('http://example.com/some_endpoint.php', function(response) {
        if (response.error) {
            // an error occurred
        }
        else {
            $.each(response.results, function(i, result) {
                // do something with each result
            });
        }
    });
</script>

Ответ 3

Если все ошибки должны обрабатываться одинаково (показывая диалог). Вы можете сделать это следующим образом:

PHP End:

public function throwJsonException($msg) {
    echo json_encode(array('error'=> true, 'msg' => $msg));
}

throwJsonException('login invalid!');

конец jQuery:

$(document).ajaxSuccess(function(evt, request, settings){
    var data=request.responseText;
    if (data.length>0) {
        var resp=$.parseJSON(data);
        if (resp.error)
        {
            showDialog(resp.msg);
            return;
        }                   
    }    
});

Ответ 4

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

function ajaxExceptionHandler($e) {
    echo json_encode(array(
        'error' => array(
        'code' => $e->getCode(),
        'msg' => $e->getMessage())
    ));
}

Затем в вашем обработчике ajax

set_exception_handler('ajaxExceptionHandler');

Ответ 5

Начиная с PHP 7.3 мы можем генерировать исключение с неверными данными JSON:

try {  
  json_decode("{", false, 512, JSON_THROW_ON_ERROR);  
}  
catch (\JsonException $exception) {  
  echo $exception->getMessage(); // displays "Syntax error"  
}

Ответ 6

Я использую этот подход для преобразования исключений в JSON:

<?php

namespace MyApp\Utility;

use Throwable;

trait JsonExceptionTrait
{    
    public function jsonException(Throwable $exception)
    {
        return json_encode([
            'message' => $exception->getMessage(),
            'code' => $exception->getCode(),
            'file' => $exception->getFile(),
            'line' => $exception->getLine(),
            'trace' => $exception->getTrace()
        ]);
    }
}

тогда просто в моих контроллерах:

<?php

namespace MyApp\Controller;

use MyApp\Utility\JsonExceptionTrait;

class UserController extends AbstractController
{
    use JsonExceptionTrait;

     /**
     * @param int $userId
     * @return JsonResponse
     */
    public function getAction(int $userId): JsonResponse
    {
        try {
            $user = $this->userService->getUser($userId);
            return new Response($user);
        } catch (EntityNotFoundException $exception) {
            return new Response(
                $this->jsonException($exception),
                JsonResponse::HTTP_NOT_FOUND
            );
        }
    }