【问题标题】:How to send data from php to jquery ajax success handler in case php throws a warning?如果php抛出警告,如何将数据从php发送到jquery ajax成功处理程序?
【发布时间】:2015-10-14 11:20:54
【问题描述】:

我正在尝试将数据从 PHP 发送到 jQuery 成功处理程序,然后再处理该数据。

我只是通过 php echo 完成了它,然后在 ajax 成功处理程序响应文本中收到了 echo 字符串。这不是我的问题。

PHP:

function function_name() {
    $Id = $_POST['id'];
    if(/*condition*/){
        echo "yes";
    }
}

JS:

$.ajax({
    type:'POST',
    data:{action:'function_name', id:ID},
    url: URL,
    success: function(res) {
        if(res == 'yes'){
            alert(res);
        }
    }
});

上面的例子提示是。到现在为止,一切都是完美的。

我的问题是假设如果 PHP 抛出任何警告,ajax 成功响应文本会填充两件事:

  1. 警告字符串
  2. php 回显字符串,因此是 js if 条件 失败。

如果 php 有任何警告,将数据从 php 发送到 ajax 成功处理程序的最佳成功方法是什么?

【问题讨论】:

  • 你可以在php页面添加errorhandler ..
  • @RohitKumar 由于其他一些功能,警告已经存在。我的 ajax 调用正在工作并正确执行 php 函数。所以从技术上讲,我的 ajax 调用永远不会在错误处理程序中结束,因为它成功地执行了脚本。但是当我警告成功处理程序响应文本时,它会打印警告字符串以及我的函数的回显字符串。
  • error_handler in php ,将处理任何警告和错误出现..只有你必须在没有警告的情况下传递你需要的数据,或者为了更好的应用程序设计使用 json 来分离警告/错误和数据..check我的回答如下

标签: javascript php jquery ajax


【解决方案1】:

你没有。

如果在 php 端出现错误或警告,这不应该归结为响应。

在正常成功的情况下,您的服务器会返回 HTTP 200 OK 响应。

在错误情况下,您应该捕获 PHP 警告和错误,并将其相应地匹配到合适的 400/500 HTTP error code

然后您不在success 方法中处理这种情况,而是在适当的错误回调中处理。

让我们从 JavaScript 开始:

这是我如何处理这种情况的示例:

$.ajax({
    type: "POST",
    url: url,
    data: $form.serialize(),
    success: function(xhr) {
        //everything ok
    },
    statusCode: {
        400: function(xhr, data, error) {
            /**
             * Wrong form data, reload form with errors
             */
            ...
        },
        409: function(xhr, data, error) {
            // conflict
            ...
        }
    }
});

如果您不想区分错误代码,可以使用this pattern instead

var jqxhr = $.post( "example.php", function() {
  alert( "success" );
})
  .done(function() {
    alert( "second success" );
  })
  .fail(function() {
    alert( "YOUR ERROR HANDLING" );
  })
  .always(function() {
    alert( "finished" );
});

现在让我们处理 PHP 服务器端:

您当然必须调整您的 PHP 以呈现正确的响应,我强烈建议您使用经过良好测试的解决方案,例如symfony2 HTTP Kernel component。这也应该在您的成功案例中取代您的回声驱动解决方案。您不妨研究像 Silexdo the bulk of the HTTP request/response handling already for you 这样的微框架,而无需重新发明轮子。

我已经编写了一个非常基本的示例,它可以是这样的 silex 应用程序:

index.php:

<?php
use Kopernikus\Controller\IndexController;
require_once __DIR__ . '/vendor/autoload.php';

$app = new Silex\Application();

$app['debug'] = true;

$className = IndexController::class;

$app->register(new Silex\Provider\ServiceControllerServiceProvider());
$app['controller.index'] = $app->share(
    function () use ($app) {
        return new IndexController();
    }
);
$app->post('/', "controller.index:indexAction");

$app->error(
    function (\Exception $e, $code) {
        switch ($code) {
            case 404:
                $message = 'The requested page could not be found.';
                break;
            default:
                $message = $e->getMessage();
        }

        return new JsonResponse(
            [
                'message' => $message,
            ]
        );
    }
);        
$app->run();

src/Kopernikus/Controller/IndexController.php:

<?php
namespace Kopernikus\Controller;

use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;

/**
 * IndexController
 **/
class IndexController
{
    public function indexAction(Request $request)
    {
        $data = $request->request->get('data');

        if ($data === null) {
            throw new BadRequestHttpException('Data parameter required');
        }

        return new JsonResponse(
            [
                'message' => $data,
            ]
        );
    }
}

如果一切正常,请求服务器现在只会返回 HTTP 200 OK 响应。

以下示例使用 httpie,因为我倾向于忘记 curl 的语法。

成功案例:

$ http --form  POST http://localhost:1337 data="hello world"
HTTP/1.1 200 OK
Cache-Control: no-cache
Connection: close
Content-Type: application/json
Date: Wed, 14 Oct 2015 15:37:30 GMT
Host: localhost:1337
X-Powered-By: PHP/5.5.9-1ubuntu4.13

{
    "message": "hello world"
}

错误案例:

错误请求,缺少参数:

$ http --form  POST http://localhost:1337 
HTTP/1.1 400 Bad Request
Cache-Control: no-cache
Connection: close
Content-Type: application/json
Date: Wed, 14 Oct 2015 15:37:00 GMT
Host: localhost:1337
X-Powered-By: PHP/5.5.9-1ubuntu4.13

{
    "message": "Data parameter required"
}

方法无效:

$ http --form  GET  http://localhost:1337 data="hello world"
HTTP/1.1 405 Method Not Allowed
Allow: POST
Cache-Control: no-cache
Connection: close
Content-Type: application/json
Date: Wed, 14 Oct 2015 15:38:40 GMT
Host: localhost:1337
X-Powered-By: PHP/5.5.9-1ubuntu4.13

{
    "message": "No route found for \"GET /\": Method Not Allowed (Allow: POST)"
}

如果你想看到它的实际效果,feel free to check it out on github

【讨论】:

  • @danish 我已经更新了答案以包含一个基本的 silex 示例。
【解决方案2】:

附加一个错误处理程序,并将您的警告、错误和响应分开。最好从 json 中执行,这样您就可以通过客户端进行过滤

$response=array();
// A user-defined error handler function
function myErrorHandler($errno, $errstr, $errfile, $errline) {
    global $response;
    $err= "<b>Custom error:</b> [$errno] $errstr<br>";
    $err.=  " Error on line $errline in $errfile<br>";
    $response['error']=$response['error'].PHP_EOL.$err;
}

// Set user-defined error handler function
set_error_handler("myErrorHandler");

//now your stuff
function function_name() {
    global $response;
    $Id = $_POST['id'];
    if(/*condition*/){
        $response['data']="yes";
        echo $response['data'];
        //better option
        //echo json_encode($response); **get data and errors sepratly**
    }
}

现在,如果您想过滤错误和数据,请分别使用 json_encode 并在成功的 ajax 中编写代码 -

$.ajax({
    type:'POST',
    data:{action:'function_name', id:ID},
    url: URL,
    success: function(res) {
        var response=JSON.parse(res);
        if(response.errors!="")
         { alert('error occured - '+ response.errors);}
        alert("data recived "+  response.data);

    }
});

【讨论】:

    【解决方案3】:

    首先,我建议您的 php 代码永远不要“抛出”错误或警告,并且您编写的任何代码都应该进行测试。我想你无论如何都理解那部分,但我提到这一点是为了可能稍后到达这里的普通读者。

    错误或警告不应该是一般 js 应该依赖或检查或实现功能的条件。 但是,在开发理想的有效代码时,您可能希望缓冲输出,通过设置错误处理程序,您很可能会检索缓冲的输出并将其发送到 js,希望以 JSON 的形式发送。

    【讨论】:

      【解决方案4】:

      本机 PHP 警告、致命错误和通知不应成为最终用户的关注点。这些类型的错误表明你使用了错误的东西,你应该修复它。

      但是,如果您是在谈论自己抛出异常,在这种情况下,您可以创建一个 response 类来负责映射您的响应。对客户端的任何响应都应该是此类的一个实例。然后,您创建一个新类 exception,它扩展了原始 exception 以便轻松抛出。向此类添加一个方法,将异常数据转换为响应数据并将其作为 JSON 回显。

      class MyResponse {
           protected $code;
           protected $response;
           protected $isException;
           protected $formFields;
      
      /**
       * Creates a NavResponse object that will be delivered to the browser.
       */
          function __construct($code, $response = null, $field = false, $exception = false) {
              $this->code = $code;
              $this->formField = $field;
              $this->response = $response;
              $this->isException = $exception;
          }
      }
      
      class MyException extends Exception {
      
          function __construct($code, $log = null, $field = null) {
              self::$exceptionThrown = true;
              $this->_code = $code;
              $this->_field = $field;
              if ($log) {
                  // store log message.
              }
          }
      
          public function response() {
              return new MyResponse($this->_code, null, $this->_field, true);
          }
      }
      

      【讨论】:

      • 我同意这个意图,但不同意解决方案,因为它再次重新发明了轮子。有一些工具可以处理请求和响应,并且应该注意它们的可维护性,它们是PSR-7-combatible。
      【解决方案5】:

      对此您无能为力,因为您不希望 PHP 抛出错误消息,最好的办法是使用类似 if else if... 的阶梯

      if (res == 'yes') {
          alert(res);
      } else if (res == 'no') {
          alert('no');
      } else {
           alert('error');
      }           
      

      【讨论】:

        猜你喜欢
        • 2011-08-26
        • 1970-01-01
        • 1970-01-01
        • 2015-02-28
        • 1970-01-01
        • 2017-11-14
        • 2021-12-31
        • 2019-04-30
        • 1970-01-01
        相关资源
        最近更新 更多