我是怎么也用 PHP 处理不了这段 jsonp 了

2015-05-28 20:17:21 +08:00
 airbasic

一个接口会返回一段jsonp数据,由于要用PHP处理它,我想先把它去掉首尾,改造成一段json,然后再用json_decode() 来解析它
然而我发现无论如何我也无法解析这段处理后出来的json

我的php代码是这样的:

<?php
function getSubstr($str, $leftStr, $rightStr){
$left = strpos($str, $leftStr);
$right = strpos($str, $rightStr,$left);
if($left < 0 or $right < $left) return '';
return substr($str, $left + strlen($leftStr), $right-$left-strlen($leftStr));
}

//这是单次执行结果
$jsonp = file_get_contents("http://bestflight.top/getflight.php?from=HGH&to=NNG&date=2015-05-29");
$json = '{"error"'.getSubstr($jsonp,'{"error"',');');
//这样转化成json再解析好了
$json = trim($json);
$json = iconv('gbk', 'utf8', $json);
$flightData = json_decode($json);
switch (json_last_error()) {
case JSON_ERROR_NONE:
echo ' - No errors';
break;
case JSON_ERROR_DEPTH:
echo ' - Maximum stack depth exceeded';
break;
case JSON_ERROR_STATE_MISMATCH:
echo ' - Underflow or the modes mismatch';
break;
case JSON_ERROR_CTRL_CHAR:
echo ' - Unexpected control character found';
break;
case JSON_ERROR_SYNTAX:
echo ' - Syntax error, malformed JSON';
break;
case JSON_ERROR_UTF8:
echo ' - Malformed UTF-8 characters, possibly incorrectly encoded';
break;
default:
echo ' - Unknown error';
break;
}
print_r($flightData);
if ($flightData["error"] == -1) {
//把错误信息发短信过去
echo $flightData["errorMsg"];
exit;
}
for ($i=0; $i < sizeof($flightData["data"]["flight"]); $i++) {
echo $flightData["data"]["flight"][$i]["flightNo"];
}
?>

明明是 no error, 却还是无法解析json,这究竟是什么原因呢?我和小伙伴们讨论了很久,但是都不明白。想问问v2ex的大牛们了,在线等。

4721 次点击
所在节点    问与答
10 条回复
kslr
2015-05-28 20:44:12 +08:00
我用手机试了试。。。 掐掉头尾直接解析就行了,也不用转编码 头尾就是()为限
kslr
2015-05-28 20:46:57 +08:00
手快了,不用这么复杂解析,前面后面都是固定的,按位删掉就行了,然后JSONdecode
feiyuanqiu
2015-05-28 20:48:56 +08:00
$json = '{"error"'.getSubstr($jsonp,'{"error"',');');
你这里截错了...这个链接返回的是这样的: flightjson({"error":0,"HOST":"atx010179212115.s.et2",...
所以应该是这样:getSubstr($jsonp, 'flightjson(', ')')

其实我觉得还是用正则更简单点
zhujinliang
2015-05-28 20:54:27 +08:00
json_decode后是object,不是php数组,读取结果中的子项要用->操作符

最后几行这样写:

if ($flightData->error == -1) {
//把错误信息发短信过去
echo $flightData->errorMsg;
exit;
}

for ($i=0; $i < count($flightData->data->flight); $i++) {
echo $flightData->data->flight[$i]->flightNo;
}
zhujinliang
2015-05-28 20:59:01 +08:00
顺便,最后那个for循环写成foreach不是更好么?

foreach ($flightData->data->flight as $flight) {
echo $flight->flightNo;
}
airbasic
2015-05-28 21:14:36 +08:00
@feiyuanqiu 这个结果应该是一样的啊,
可是我还是没法 json_decode 错误是
- Malformed UTF-8 characters, possibly incorrectly encoded
@kslr
airbasic
2015-05-28 21:18:37 +08:00
谢谢哦 这我还真没注意,但是在json_decode的时候似乎失败了,错误是: Malformed UTF-8 characters, possibly incorrectly encoded 。这是要转换成utf8吗?怎么转换呢?
@zhujinliang
airbasic
2015-05-28 21:20:20 +08:00
@feiyuanqiu
因为返回的是


flightjson(

{"error":0,"HOST":"atx010179212116.s.et2","processTime":"2015-05-28

这样 中间有个莫名其妙的换行和空格什么的 为了省力我就直接从 error开始截起然后补回去。
然而并不能 json_decode 难道是中文的原因?
airbasic
2015-05-28 21:31:30 +08:00
解决了,
$json = getSubstr($jsonp,'flightjson(',');');
//这样转化成json再解析好了
$json = trim($json);
$json = iconv("GB2312","UTF-8",$json);
把编码转换成utf-8就好了
谢谢各位 我太菜了
feiyuanqiu
2015-05-28 21:37:19 +08:00
@airbasic 实际上编码是 GB18030

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/194497

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX