php json解码奇怪的格式

时间:2016-11-19 12:48:06

标签: php json embedded-linux

我试图解码我的IP报警系统中的一些数据。我被告知数据是json,并查看html文件,有json的引用。问题是它看起来有点奇怪: - )

以下是闹钟的原始输出:

/*-secure- {    senrows : [ {no : "1", type : "Door Contact", zone : "1", name : "zone1", attr : "Burglar", cond : "", battery : "", tamp : "", bypass : "No"}, {no : "2", type : "Door Contact", zone : "2", name : "zone2", attr : "Burglar", cond : "", battery : "", tamp : "", bypass : "No"}, {no : "3", type : "Door Contact", zone : "3", name : "zone3", attr : "Burglar", cond : "", battery : "", tamp : "", bypass : "No"}, {no : "4", type : "Door Contact", zone : "4", name : "zone4", attr : "Burglar", cond : "", battery : "Low", tamp : "", bypass : "No"}, {no : "5", type : "Door Contact", zone : "5", name : "zone5", attr : "Burglar", cond : "", battery : "", tamp : "", bypass : "No"}, {no : "6", type : "Door Contact", zone : "6", name : "zone6", attr : "Burglar", cond : "", battery : "", tamp : "", bypass : "No"}, {no : "7", type : "Door Contact", zone : "7", name : "zone7", attr : "Burglar", cond : "", battery : "", tamp : "", bypass : "No"}, {no : "8", type : "Door Contact", zone : "8", name : "zone8", attr : "Burglar", cond : "", battery : "", tamp : "", bypass : "No"}, {no : "9", type : "Door Contact", zone : "9", name : "zone9", attr : "Burglar", cond : "", battery : "", tamp : "", bypass : "No"}, {no : "10", type : "IR Sensor", zone : "10", name : "zone10", attr : "Burglar", cond : "", battery : "Low", tamp : "", bypass : "No"}, {no : "11", type : "Remote Keypad", zone : "11", name : "zone11", attr : "",cond : "", battery : "", tamp : "", bypass : "No"}] } */

如何解码这些数据? : - )

json_decode()不起作用: - /

2 个答案:

答案 0 :(得分:1)

好吧,你仍然应该首先要求那些给你这个输出的人修复他们的代码并实际提供JSON。

仍然,我有几分钟时间,并享受编码练习,为您的数据写一个快速修复 它只适用于你的代码总是以相同的-secure-开头,否则你必须适应它。

如果由于某种原因你有一个带有封装字符串的字段,如a:"text\"moretext\"finaltext",或者如果提供者引入除了显示的那些之外的任何其他错误,那么 失败或产生奇怪的结果你的榜样。

<?php
$data = /*your not-JSON-string*/;

function fix_botched_json($data) {
    //remove comment-section, we don't need it
    $data = substr($data, 10, strlen($data)-12);
    $seek = '/(\w+)/';
    $exploded = explode('"', $data);
    //explode so we only replace *outside* of strings

    $outside = true;
    foreach($exploded as &$item) {
        if($outside) {
            //the regex matches only word characters.
            $item = preg_replace($seek, '"\1"', $item);
        }
        //alternating between inside and outside of strings
        $outside = !$outside;
    }
    //piece it back together
    $imploded = implode('"', $exploded);

    return $imploded;
}


$final = json_decode(fix_botched_json($data), true);

答案 1 :(得分:1)

非常hacky解决方案,并且不保证与您可能拥有的其他字符串一起工作。有很多方法可以处理这种情况,最好的方法可能是让警报系统的创建者开始生成有效的JSON!

<?php

$string = '/*-secure- {    senrows : [ {no : "1", type : "Door Contact", zone : "1", name : "zone1", attr : "Burglar", cond : "", battery : "", tamp : "", bypass : "No"}, {no : "2", type : "Door Contact", zone : "2", name : "zone2", attr : "Burglar", cond : "", battery : "", tamp : "", bypass : "No"}, {no : "3", type : "Door Contact", zone : "3", name : "zone3", attr : "Burglar", cond : "", battery : "", tamp : "", bypass : "No"}, {no : "4", type : "Door Contact", zone : "4", name : "zone4", attr : "Burglar", cond : "", battery : "Low", tamp : "", bypass : "No"}, {no : "5", type : "Door Contact", zone : "5", name : "zone5", attr : "Burglar", cond : "", battery : "", tamp : "", bypass : "No"}, {no : "6", type : "Door Contact", zone : "6", name : "zone6", attr : "Burglar", cond : "", battery : "", tamp : "", bypass : "No"}, {no : "7", type : "Door Contact", zone : "7", name : "zone7", attr : "Burglar", cond : "", battery : "", tamp : "", bypass : "No"}, {no : "8", type : "Door Contact", zone : "8", name : "zone8", attr : "Burglar", cond : "", battery : "", tamp : "", bypass : "No"}, {no : "9", type : "Door Contact", zone : "9", name : "zone9", attr : "Burglar", cond : "", battery : "", tamp : "", bypass : "No"}, {no : "10", type : "IR Sensor", zone : "10", name : "zone10", attr : "Burglar", cond : "", battery : "Low", tamp : "", bypass : "No"}, {no : "11", type : "Remote Keypad", zone : "11", name : "zone11", attr : "",cond : "", battery : "", tamp : "", bypass : "No"}] } */';

function fix_json($st){
    $regex = '/([a-zA-Z0-9_]+)(\s)(?=:)/i';
    return preg_replace($regex, '"$1"', $st);
}

$step1 = strstr($string, '{');
$step2 = rtrim($step1, '*/');


$data = fix_json($step2);

var_dump(json_decode($data, true));