如何将数据从php发送到jquery ajax成功处理程序,以防php抛出警告


How to send data from php to jquery ajax success handler in case php throws a warning?

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

我通过php echo简单地做到了这一点,然后在ajax成功处理程序响应文本中接收回显字符串。这不是我的问题。

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到ajax成功处理程序,如果有任何警告从php?

你没有。

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

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

在错误情况下,您应该捕获PHP警告和错误,并相应地匹配400/500 HTTP错误代码。

然后你不在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
            ...
        }
    }
});

如果您对区分错误码不感兴趣,您可以使用以下模式:

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内核组件。在您的成功案例中,这也应该取代您的回声驱动解决方案。你也可以看看像Silex这样的微框架,它已经为你做了大量的HTTP请求/响应处理,而不必重新发明轮子。

我已经写了一个非常基本的示例,作为一个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响应。

下面的例子使用了http,因为我容易忘记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)"
}

如果你想看到它的实际效果,可以在github上查看。

附加一个错误处理程序,并将警告、错误和响应分开。最好从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);
    }
});

因此,首先,我建议您的php代码永远不要'抛出'错误或警告,并且您编写的任何代码都应该针对该错误进行测试。我想你已经明白了这一部分,但我提到这一点是为了一个可能稍后到达这里的偶然读者。

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

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

但是,如果你正在谈论自己抛出异常,在这种情况下,你可以创建一个response类来负责映射你的响应。对客户端的任何响应都应该是该类的一个实例。然后,创建一个新的类异常,扩展原始的异常,使其易于抛出。为该类添加一个方法,该方法将异常数据转换为响应数据,并将其作为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);
    }
}

这是没有办法的因为你不希望PHP抛出错误信息,最好的办法是使用if else if...阶梯,比如

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