【问题标题】:Clean way to throw php exception through jquery/ajax and json通过 jquery/ajax 和 json 抛出 php 异常的干净方法
【发布时间】:2012-09-23 11:47:45
【问题描述】:

有没有一种干净、简单的方法可以通过 json 响应 jquery/ajax 调用来抛出 php 异常。

【问题讨论】:

  • 为什么要抛出异常?返回一个不触发异常的错误状态可能会更好。
  • 我的意思是我在服务器端尝试了catch,我想将错误消息放入json响应中。

标签: php jquery


【解决方案1】:

我使用这种方法将异常转换为 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
            );
        }
    }

【讨论】:

    【解决方案2】:

    作为对先前答案的补充,您可以将异常处理程序设置为仅在所需脚本中使用,而不是在所有异常中重复相同的 json 编码代码。例如:

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

    然后,在您的 ajax 处理程序中,

    set_exception_handler('ajaxExceptionHandler');
    

    【讨论】:

      【解决方案3】:

      你可以在 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);
          }
      });
      

      您还可以通过返回 400(例如)标头来触发 $.ajax() 的 error: 处理程序:

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

      如果您使用的是 FastCGI,请使用 Status:。请注意,error: 处理程序不会收到错误详细信息;要实现这一点,您必须覆盖 $.ajax() 的工作方式:)

      【讨论】:

      • 谢谢。反正有没有触发jquery ajax错误回调?
      • 对于 PHP >=5.4 你可以使用http_response_code(400);
      • 您可能还想加入'stack' =&gt; $e-&gt;getTrace(),这样您也可以获得一个不错的堆栈数组。
      • @ArnovanOordt 必须小心,因为堆栈跟踪往往会泄露代码细节
      • @Jack True,但在测试时非常方便:)
      【解决方案4】:

      如果所有错误都应该以相同的方式处理(例如显示一个对话框)。 你可以这样做:

      PHP 结束:

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

      【讨论】:

        【解决方案5】:

        Facebook 在他们的 PHP SDK 中做了一些事情,如果 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()
                )
            ));
        }
        

        然后,您可以在 JavaScript 中的 AJAX 调用中侦听 error 键:

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-10-20
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多