我正在尝试将数据从PHP发送到jQuery成功处理程序,然后处理该数据。
我通过php echo
简单地做到了这一点,然后在ajax成功处理程序响应文本中接收回显字符串。这不是我的问题。
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成功响应文本被填满两件事:
- 警告字符串
- php返回字符串,因此js的if条件失败。
你没有。
如果在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');
}