我有一系列 PHP API 脚本,几乎在所有情况下都会向调用应用程序返回一个关联数组。
PHP:
$returnInfo = array() ;
$returnInfo[] = array("success"=>true,"key1"=>"value1","key2"=>"value2",...) ;
//Then at the end of the API:
sendResponse(200,json_encode($returnInfo)) ;
function sendResponse($status, $body) {
$status_header = 'HTTP/1.1 ' .$status. ' ' .getStatusCodeMessage($status);
header($status_header);
header('Content-type: application/json');
echo $body;
}
最近从 PHP 7.3 升级到 8.2 后,我的应用程序在调用 PHP API 时开始报告不一致的错误。 大多数情况下,同一个 API 调用工作正常,但偶尔会失败。 在应用程序内部,HTTP 调用检查响应 200 以及返回的数据是否为数组或对象。 在所有失败中,我的应用程序实际上报告 200 已收到成功响应。 然后,根据response.data是ARRAY还是OBJECT,然后执行X或Y。
当数据是 ARRAY 时,应用程序偶尔会报告错误。
function objArray(val,type) {
//type = 1 = object
// 2 = array
if (type == 1) {
return (!!val) && (val.constructor === Object) ;
} else if (type == 2) {
return (!!val) && (val.constructor === Array) ;
}
}
var baseUrl = "https://api.example.com/apiFile.php" ;
var req = {
method: 'POST',
url: baseUrl,
timeout:httpTimeout,
headers: headers,
data: JSON.stringify(dataObj)
}
return $http(req)
.then(function(response){
if (response.status == 200 && objArray(response.data,2)) {
...
... do stuff with response
...
} else {
var err = resError(req,response) ;
err.callBack = "Success" ;
throw err ;
}
当应用程序正确接收数据时,我将
response.data[0]
返回到原始调用函数,以便应用程序(和用户)继续。
但是当
throw err ;
发生时,它会调用另一个 api 脚本将错误的详细信息发送到我的服务器。 捕获的错误是(以及其他一些自定义消息):
status = 200
statusText = SUCCESS RESPONSE ERROR: OK
callBack = Success
因为 API 返回
200
我知道 response.status == 200
是 true,但它一定意味着 objArray(response.data,2)
没有返回 TRUE
- 导致响应过程的 else
部分抛出错误.
这仅在从 PHP 7.3 升级到 PHP 8.2 后开始。 那么 PHP 8.2 中发生了什么变化...或者变得更加严格和/或更不宽容...导致我的应用程序
sometimes
将response.data视为不是数组?
应用程序的生产版本是偶尔产生错误的版本,不幸的是,该版本没有任何在错误处理程序中返回响应数据的方法,我必须推送应用程序的新版本才能做到这一点。 我一直在尝试想办法让 API 欺骗错误处理程序发送response.data,但目前还没有任何结果。 而且我无法在实时测试中复制该错误......非常令人沮丧。
我认为问题很可能是你的
$response.data
仍然是string
。
如果是这种情况,请尝试使用
JSON.parse()
: 解析数据
if (response.status == 200 && objArray(JSON.parse(response.data),2)) {
//-------------------------------------^^^^^^^^^^^-------------^
...
... do stuff with response
...
}
或者只是做更详细的验证:
let error = false;
if ( response.status == 200 )
{
let data = response.data;
// If maybe JSON, then try to parse it or revert back to string.
if ( ( typeof data == 'string' ) || ( data instanceof String ) )
{
let oldData = data;
try
{
data = JSON.parse(data);
}
catch
{ // Reverts to old string value if JSON.parse fails.
data = oldData;
}
}
// If really an array.
if ( Array.isArray(data) )
{
// Do stuff with data that is array.
// Which is not the case for associavie arrays.
}
// Or if an object.
else if ( typeof data == 'object' )
{
// Do stuff with data that is object. Which is the case for
// associative arrays.
}
// Or if anything else.
else
{
// Do stuff with other data types that are not array or object,
// like numbers and strings.
error = true;
}
}
// If not status 200.
else
{
error = true;
}
if ( error )
{
var err = resError(req,response) ;
err.callBack = "Success" ;
// You can also add extra information to your error, like:
err.errorMessage = error?.message ?? error;
throw err ;
}