json_decode转换json数据为数组出现的问题!
2015-10-16 15:42
681 查看
json_decode这个函数是json_encode的反函数,一般传递数据的时候为了压缩数据,会将数组格式的数据转换成json格式,用到的函数就是json_encode,然后接收到数据之后再用json_decode转换回数组,这里本来应该不会出现什么问题, 但也有意外,这个意外应该可以说也是自己造成,bom头导致的bug,其实准确来说也不算bug,但就是让你的数据无法正确转换回来;
bom头的产生应该是你的文件在windows下用记事本这些东西编辑过之后的后果,可能无意之间就给这个bug的产生带来了隐患;但是就算出现这个问题也不用慌张, 凡是都有解决的办法;
json_decode($json)之后可能出现返回空,null等结果,这个时候一般都是json格式出问题, 可以用json_last_error()来检查,json_last_error()函数的使用方式就是在json_decode之后添加这个函数, 函数会返回值,返回0说明格式没错, 我遇到的事返回4,说明格式错误,之前用json在线检测工具检测数据,显示是正确的,这两个居然矛盾,让我大惑不解,不过如果知道bom头这个概念立马就应该反应过来, bom头是看不见的, 所以转换的时候前面多了三个字节,当然看不见, 在线检测的时候复制这个数据没有bom头的三个字节,当然也就正确了, 所以立马用$json=substr($json,3);这个函数,去掉头部的三个字节, 转换之后ok了;
问题解决之后感概万千, 因为这个问题我找了两天,本来问题影藏的不深,只是代码不是自己写的, 其次本地环境与服务器环境不一致, 反正诸多原因,一直没想到会是这个问题;最后一步一步排查,锁定这个函数;感觉以后编辑文件一定不能图方便, 一个小错误就直接用记事本大概编辑一下就行了, 很容易出现这个bom头问题;而且自己还不知道;
这里贴出一段代码, 可以去除网站所有文件的bom头信息;
这段代码也是网上找来的, 用了觉得还是蛮方便,不过不敢在服务器上用,以免造成位置的别的什么错误;
所以想到一个折中的办法, 现在本地跑了一下,把出现bom的文件全都替换,然后服务器上的问题并没有解决,然后又在转换json的时候添加了一个判断
这样如果检测得到bom头信息去掉就好了;
bom头的产生应该是你的文件在windows下用记事本这些东西编辑过之后的后果,可能无意之间就给这个bug的产生带来了隐患;但是就算出现这个问题也不用慌张, 凡是都有解决的办法;
json_decode($json)之后可能出现返回空,null等结果,这个时候一般都是json格式出问题, 可以用json_last_error()来检查,json_last_error()函数的使用方式就是在json_decode之后添加这个函数, 函数会返回值,返回0说明格式没错, 我遇到的事返回4,说明格式错误,之前用json在线检测工具检测数据,显示是正确的,这两个居然矛盾,让我大惑不解,不过如果知道bom头这个概念立马就应该反应过来, bom头是看不见的, 所以转换的时候前面多了三个字节,当然看不见, 在线检测的时候复制这个数据没有bom头的三个字节,当然也就正确了, 所以立马用$json=substr($json,3);这个函数,去掉头部的三个字节, 转换之后ok了;
问题解决之后感概万千, 因为这个问题我找了两天,本来问题影藏的不深,只是代码不是自己写的, 其次本地环境与服务器环境不一致, 反正诸多原因,一直没想到会是这个问题;最后一步一步排查,锁定这个函数;感觉以后编辑文件一定不能图方便, 一个小错误就直接用记事本大概编辑一下就行了, 很容易出现这个bom头问题;而且自己还不知道;
这里贴出一段代码, 可以去除网站所有文件的bom头信息;
<?php if (isset($_GET['dir'])){ //设置文件目录 $basedir=$_GET['dir']; }else{ $basedir = '.'; } $auto = 1; checkdir($basedir); function checkdir($basedir){ if ($dh = opendir($basedir)) { while (($file = readdir($dh)) !== false) { if ($file != '.' && $file != '..'){ if (!is_dir($basedir."/".$file)) { echo "filename: $basedir/$file ".checkBOM("$basedir/$file")." <br>"; }else{ $dirname = $basedir."/".$file; checkdir($dirname); } } } closedir($dh); } } function checkBOM ($filename) { global $auto; $contents = file_get_contents($filename); $charset[1] = substr($contents, 0, 1); $charset[2] = substr($contents, 1, 1); $charset[3] = substr($contents, 2, 1); if (ord($charset[1]) == 239 && ord($charset[2]) == 187 && ord($charset[3]) == 191) { if ($auto == 1) { $rest = substr($contents, 3); rewrite ($filename, $rest); return ("<font color=red>BOM found, automatically removed._<a href=http://www.k686.com>http://www.k686.com</a></font>"); } else { return ("<font color=red>BOM found.</font>"); } } else return ("BOM Not Found."); } function rewrite ($filename, $data) { $filenum = fopen($filename, "w"); flock($filenum, LOCK_EX); fwrite($filenum, $data); fclose($filenum); }
这段代码也是网上找来的, 用了觉得还是蛮方便,不过不敢在服务器上用,以免造成位置的别的什么错误;
所以想到一个折中的办法, 现在本地跑了一下,把出现bom的文件全都替换,然后服务器上的问题并没有解决,然后又在转换json的时候添加了一个判断
if(preg_match('/^\xEF\xBB\xBF/',$json)) { $json=substr($json,3); }
这样如果检测得到bom头信息去掉就好了;
相关文章推荐
- js提取正则中的字符串
- 正则表达式JS常见验证
- js判断undefined类型
- 分享一个C#通用的json操作类
- Javascript操作剪切板数据(支持IE、Chrome、360、搜狗),亲测!
- bower解决js的依赖管理
- 你不知道的JavaScript--Item5 全局变量
- 你不知道的JavaScript--Item5 全局变量
- 有关Chrome下锚点定位失效的问题
- JS不弹出网页文件下载本地
- 使用json web token
- js 替换字符
- javascript判断复选框是否选中的方法
- sencha cmd 在ExtJS6.0的使用
- 几种常见的JavaScript特效
- JSON例子(一)
- JSON例子(一)
- javascript == 和===
- js数组与字符串的相互转化
- js回网页顶部