【问题标题】:Can't use JSON array in a php loop无法在 php 循环中使用 JSON 数组
【发布时间】:2018-01-05 12:32:12
【问题描述】:

我有一个 json 文件,必须循环解析。 我似乎无法成功

JSON:

{"IMD":{"url":"http:\/\/www.google.com","timeOut":1515155361},"cvH":{"url":"http:\/\/www.google.com","timeOut":1515155364}}

PHP:

<?php
$linkyValues="./linky.json";
if (file_exists($linkyValues)) {
    $fileStream = fopen($linkyValues, 'r');
    $fileValue=json_decode(fread($fileStream, filesize($linkyValues)));
    fclose($fileStream);
    echo count($fileValue);//Always 1!
    for($i=0;$i<count($fileValue);$i++){
      $timeout=$fileValue->item($i)->timeOut;
      if(time()>=$timeout){
         unset($fileValue[$i]);
      }
    }
    $fileStream = fopen($linkyValues, 'w');
    fwrite($fileStream, json_encode($fileValue));
    fclose($fileStream);
}
?>

我的问题是count($fileValue) 总是 1。

var_dump($fileValue)的输出:

object(stdClass)#2 (2) {
  ["IMD"]=>
  object(stdClass)#1 (2) {
    ["url"]=>
    string(21) "http://www.google.com"
    ["timeOut"]=>
    int(1515155361)
  }
  ["cvH"]=>
  object(stdClass)#3 (2) {
    ["url"]=>
    string(21) "http://www.google.com"
    ["timeOut"]=>
    int(1515155364)
  }
}

对我来说它看起来像一个数组...

【问题讨论】:

  • var_dump($fileValue) 看看你有什么。这不是一个数组。
  • 你能进入if condition吗?
  • @TarangP 不。它不是。见3v4l.org/Ae9Bq
  • 那里只有 1 个对象 - eval.in/931027
  • 从您最近的编辑中,您说它对您来说看起来像一个数组,但看看它,它不是一个数组,而是一系列对象。

标签: php arrays json decode


【解决方案1】:

JSON 不支持关联数组的概念,而是将此类映射存储为对象。

您的 JSON 文件包含这样的对象。对于 PHP,这意味着它可以将其作为 stdClass ( object ) 或关联数组导入。

这是由json_decode 的第二个参数决定的,即TRUE 将对象作为关联数组读取,或者FALSE 将其作为对象读取。

因此,这将解决您的问题:

$fileValue = json_decode(fread($fileStream, filesize($linkyValues)), TRUE);

json_decode documentation

除此之外,您的代码在迭代数组方面存在问题。你使用$fileValue-&gt;item($i)$fileValue[$i],同时你有一个关联数组。

您可以像使用索引数组一样使用它,而它是一个关联数组,这意味着它具有标识数组中的值的键而不是索引。

迭代关联数组的正确方法是使用 foreach,例如 deomstrated belo:

foreach($fileValue as $key => $value) {
    if (time() >= $value['timeOut']) {
        unset($fileValue[$key]);
    }
}

但是,由于您只想删除特定值,因此您也可以使用 array_filter

$fileValue = array_filter($fileValue, function($value){
    return time() < $value['timeOut'];
});

array_filter 将负责从您的数组中删除指定的字段,因此您不必手动取消设置。

【讨论】:

    【解决方案2】:

    你可以使用:

    count((array)$fileValue);
    

    【讨论】:

      【解决方案3】:

      您在这里混合了数组和对象。

      count() 只能用于数组,但是您可以将对象强制转换为数组以实现相同的目的。

      $fileValue[$i] 是一种访问数组的方法,它不适用于您的 json 对象。

      我已经看到一个解决方案是将您的对象更改为数组,所以如果您想坚持使用对象,我想提供解决方案。

      $linkyValues="./linky.json";
      if (file_exists($linkyValues)) {
          $fileStream = fopen($linkyValues, 'r');
          $fileValue=json_decode($jsonString);
          fclose($fileStream);
          //Cast the object to an array to get the count, but count isn't really requierd
          echo count((array)$fileValue);
      
          //loop through the object
          foreach($fileValue as $key=>$fv){
              //pull the timeout
              $timeout=$fv->timeOut;
              //do the check
              if(time()>=$timeout){
                //remove the timeout from the object
               unset($fileValue->$key);
              }
          }
          $fileStream = fopen($linkyValues, 'w');
          fwrite($fileStream, json_encode($fileValue));
          fclose($fileStream);
      }
      ?>
      

      【讨论】:

        猜你喜欢
        • 2014-05-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-03-14
        • 2011-06-11
        相关资源
        最近更新 更多