2011-10-07 61 views
0

我必须在PHP中解析这个JSON,以便为每个地址获取地址,行和城市信息并将其存储在数据库中。我打算实施的方式是这样的:使用有序密钥后缀的PHP数组遍历

For each key in the json string, check if it begins with address, 
If yes, split the string based on '_' and get the index count. 
Get line1, line2, city for this index count. 

有没有更好的方法来做到这一点?

(注意,索引数可以是随机的)

{ 
    "route": "A", 

    "address_0": "A0", 
    "line1_0": "L1_0", 
    "line2_0": "L2_0", 
    "city_0": "city_0", 

    "address_1": "A1", 
    "line1_1": "L1_1", 
    "line2_1": "L2_1", 
    "city_1": "city_1", 

    "address_2": "A2", 
    "line1_2": "L1_2", 
    "line2_2": "L2_2", 
    "city_2": "city_2", 

} 
+2

的方式诸如PHP的内置[JSON扩展名](HTTP: //php.net/json_decode)? – Wiseguy

回答

0

只需遍历数据和分配给数组:

$route = array(); 
foreach(json_decode($json) as $p => $v) 
{ 
    list($k, $i) = explode('_', $p, 2) + array(NULL, NULL); 
    if (NULL === $i) { 
     $rc =& $route["$k $v"]; 
     continue; 
    } 
    $rc[$i][$k] = $v; 
} 
unset($rc); 

给出:

array(1) { 
    ["route A"]=> 
    array(3) { 
    [0]=> 
    array(4) { 
     ["address"]=> 
     string(2) "A0" 
     ["line1"]=> 
     string(4) "L1_0" 
     ["line2"]=> 
     string(4) "L2_0" 
     ["city"]=> 
     string(6) "city_0" 
    } 
    [1]=> 
    array(4) { 
     ["address"]=> 
     string(2) "A1" 
     ["line1"]=> 
     string(4) "L1_1" 
     ["line2"]=> 
     string(4) "L2_1" 
     ["city"]=> 
     string(6) "city_1" 
    } 
    [2]=> 
    array(4) { 
     ["address"]=> 
     string(2) "A2" 
     ["line1"]=> 
     string(4) "L1_2" 
     ["line2"]=> 
     string(4) "L2_2" 
     ["city"]=> 
     string(6) "city_2" 
    } 
    } 
} 

Demo

0

是。使用这种格式,而不是

{ 
    "route": "A", 
    data : [{ 
     "address": "A0", 
     "line1": "L1_0", 
     "line2": "L2_0", 
     "city": "city_0" 
    },{ 
     "address": "A1", 
     "line1": "L1_1", 
     "line2": "L2_1", 
     "city": "city_1" 
    },{ 
     "address": "A2", 
     "line1": "L1_2", 
     "line2": "L2_2", 
     "city": "city_2" 
    }] 
} 

,并得到像这样

$json = ' { 
     "route": "A", 
     data : [{ 
      "address": "A0", 
      "line1": "L1_0", 
      "line2": "L2_0", 
      "city": "city_0" 
     },{ 
      "address": "A1", 
      "line1": "L1_1", 
      "line2": "L2_1", 
      "city": "city_1" 
     },{ 
      "address": "A2", 
      "line1": "L1_2", 
      "line2": "L2_2", 
      "city": "city_2" 
     }] 
    }'; 
$object = json_decode($json); 
echo $object->data[0]->address; // A0 
echo $object->data[1]->address; // A1 
//and so on... 
+0

我不允许更改传入的JSON,我需要按原样处理它。 – user330973

+0

正是我在做什么,但更彻底。 –

+0

@ user330973:哇。所以请联系api的所有者,告诉他们必须改变它。因为这真的很糟糕 – genesis

0

这是一个棘手的,因为即使是JSON没有形成很好(address_0 VS ADDRESS_1),而不是像

{ 
    "route" : 
     { "address" : "something", "line1": "something else" }, 
     { ... } 
} 

我会做一个json_decode将你已经成为一个数组,然后适当地解析键,并将值传递到DB对象(或循环和保存)。

+0

我认为你必须处理可怜的JSON的计划是最好的方法。 –

+0

我正在寻找一种解决方案,我可能不需要两次遍历JSON,但看起来像我最终可能会这样做。 – user330973

0

你总是可以做到这一点:

$json = { 
    "route": "A", 

    "address_0": "A0", 
    "line1_0": "L1_0", 
    "line2_0": "L2_0", 
    "city_0": "city_0", 

    "address_1": "A1", 
    "line1_1": "L1_1", 
    "line2_1": "L2_1", 
    "city_1": "city_1", 

    "address_2": "A2", 
    "line1_2": "L1_2", 
    "line2_2": "L2_2", 
    "city_2": "city_2", 

} 

$object = json_decode($json); 

$route = array(); 
$currentRoute = ""; 
$addressCounter = 0; 

foreach($object as $key => $value) 
{ 
    if($key == "route"){ 
     $currentRoute = $value; 
    } else { 
     $explode = explode("_",$key); 
     $route[$currentRoute][$addressCounter][$explode[0]] = $value; 
     if($explode[0] == "city"){ 
      $addressCounter++; 
     } 
    } 
} 

print_r($route) 

// Should return something like 
// Array (
// ['A'] => Array (
//    [0] => Array (
//      ['address'] => 'A0', 
//      ['line1'] => 'L1_0' 
// ... 

这是讨厌的,但它的作品。再说一遍......如果你能控制原来的形式,我会重新思考这种方法,以便在这里更好地处理。

祝你好运!