for循环导致无限加载等待

时间:2013-03-04 23:29:51

标签: php xml xml-parsing simplexml infinite-loop

我正在编写一个PHP脚本,其中包含以下for循环:

for($x=count($content->data->parameters[0]->weather->children());$content->data->weather->{"weather-conditions"}[$x]['weather-type']==NULL;--$x){
    echo $x."\n";
}

其中$ content是SimpleXMLElement的一个实例,它解析了XML,如下所示:

<dwml xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.0" xsi:noNamespaceSchemaLocation="http://graphical.weather.gov/xml/DWMLgen/schema/DWML.xsd">
<data>
<parameters applicable-location="point1">
<location>
<weather time-layout="k-p3h-n41-3">
<name>Weather Type, Coverage, and Intensity</name>
<weather-conditions>
<value coverage="slight chance" intensity="light" weather-type="snow" qualifier="none">
<visibility xsi:nil="true"/>
</value>
</weather-conditions>
<weather-conditions>
<value coverage="slight chance" intensity="light" weather-type="snow" qualifier="none">
<visibility xsi:nil="true"/>
</value>
</weather-conditions>
<weather-conditions>
<value coverage="chance" intensity="light" weather-type="snow" qualifier="none">
<visibility xsi:nil="true"/>
</value>
</weather-conditions>
<weather-conditions>
<value coverage="likely" intensity="light" weather-type="snow" qualifier="none">
<visibility xsi:nil="true"/>
</value>
</weather-conditions>
<weather-conditions>
<value coverage="definitely" intensity="light" weather-type="snow" qualifier="none">
<visibility xsi:nil="true"/>
</value>
</weather-conditions>
<weather-conditions>
<value coverage="definitely" intensity="light" weather-type="snow" qualifier="none">
<visibility xsi:nil="true"/>
</value>
</weather-conditions>
<weather-conditions>
<value coverage="definitely" intensity="moderate" weather-type="snow" qualifier="none">
<visibility xsi:nil="true"/>
</value>
<value coverage="areas" intensity="none" additive="and" weather-type="blowing snow" qualifier="none">
<visibility xsi:nil="true"/>
</value>
</weather-conditions>
<weather-conditions>
<value coverage="definitely" intensity="moderate" weather-type="snow" qualifier="none">
<visibility xsi:nil="true"/>
</value>
<value coverage="areas" intensity="none" additive="and" weather-type="blowing snow" qualifier="none">
<visibility xsi:nil="true"/>
</value>
</weather-conditions>
<weather-conditions>
<value coverage="definitely" intensity="moderate" weather-type="snow" qualifier="none">
<visibility xsi:nil="true"/>
</value>
<value coverage="areas" intensity="none" additive="and" weather-type="blowing snow" qualifier="none">
<visibility xsi:nil="true"/>
</value>
</weather-conditions>
<weather-conditions>
<value coverage="definitely" intensity="moderate" weather-type="snow" qualifier="none">
<visibility xsi:nil="true"/>
</value>
<value coverage="areas" intensity="none" additive="and" weather-type="blowing snow" qualifier="none">
<visibility xsi:nil="true"/>
</value>
</weather-conditions>
<weather-conditions>
<value coverage="chance" intensity="light" weather-type="snow" qualifier="none">
<visibility xsi:nil="true"/>
</value>
<value coverage="areas" intensity="none" additive="and" weather-type="blowing snow" qualifier="none">
<visibility xsi:nil="true"/>
</value>
</weather-conditions>
<weather-conditions>
<value coverage="chance" intensity="light" weather-type="snow" qualifier="none">
<visibility xsi:nil="true"/>
</value>
<value coverage="areas" intensity="none" additive="and" weather-type="blowing snow" qualifier="none">
<visibility xsi:nil="true"/>
</value>
</weather-conditions>
<weather-conditions>
<value coverage="slight chance" intensity="light" weather-type="snow showers" qualifier="none">
<visibility xsi:nil="true"/>
</value>
</weather-conditions>
<weather-conditions>
<value coverage="slight chance" intensity="light" weather-type="snow showers" qualifier="none">
<visibility xsi:nil="true"/>
</value>
</weather-conditions>
<weather-conditions>
<value coverage="slight chance" intensity="light" weather-type="snow showers" qualifier="none">
<visibility xsi:nil="true"/>
</value>
</weather-conditions>
<weather-conditions>
<value coverage="slight chance" intensity="light" weather-type="snow showers" qualifier="none">
<visibility xsi:nil="true"/>
</value>
</weather-conditions>
<weather-conditions/>
<weather-conditions/>
<weather-conditions/>
<weather-conditions/>
<weather-conditions/>
<weather-conditions/>
<weather-conditions/>
<weather-conditions/>
<weather-conditions/>
<weather-conditions/>
<weather-conditions/>
<weather-conditions/>
<weather-conditions/>
<weather-conditions/>
<weather-conditions>
<value coverage="slight chance" intensity="light" weather-type="rain" qualifier="none">
<visibility xsi:nil="true"/>
</value>
</weather-conditions>
<weather-conditions>
<value coverage="slight chance" intensity="light" weather-type="rain" qualifier="none">
<visibility xsi:nil="true"/>
</value>
</weather-conditions>
<weather-conditions>
<value coverage="slight chance" intensity="light" weather-type="rain" qualifier="none">
<visibility xsi:nil="true"/>
</value>
<value coverage="slight chance" intensity="light" additive="and" weather-type="snow" qualifier="none">
<visibility xsi:nil="true"/>
</value>
</weather-conditions>
<weather-conditions>
<value coverage="slight chance" intensity="light" weather-type="rain" qualifier="none">
<visibility xsi:nil="true"/>
</value>
<value coverage="slight chance" intensity="light" additive="and" weather-type="snow" qualifier="none">
<visibility xsi:nil="true"/>
</value>
</weather-conditions>
<weather-conditions>
<value coverage="slight chance" intensity="light" weather-type="rain" qualifier="none">
<visibility xsi:nil="true"/>
</value>
</weather-conditions>
<weather-conditions>
<value coverage="slight chance" intensity="light" weather-type="rain" qualifier="none">
<visibility xsi:nil="true"/>
</value>
</weather-conditions>
<weather-conditions>
<value coverage="chance" intensity="light" weather-type="rain" qualifier="none">
<visibility xsi:nil="true"/>
</value>
<value coverage="chance" intensity="light" additive="and" weather-type="snow" qualifier="none">
<visibility xsi:nil="true"/>
</value>
</weather-conditions>
<weather-conditions>
<value coverage="chance" intensity="light" weather-type="rain" qualifier="none">
<visibility xsi:nil="true"/>
</value>
<value coverage="chance" intensity="light" additive="and" weather-type="snow" qualifier="none">
<visibility xsi:nil="true"/>
</value>
</weather-conditions>
<weather-conditions>
<value coverage="chance" intensity="light" weather-type="rain" qualifier="none">
<visibility xsi:nil="true"/>
</value>
</weather-conditions>
<weather-conditions>
<value coverage="chance" intensity="light" weather-type="rain" qualifier="none">
<visibility xsi:nil="true"/>
</value>
</weather-conditions>
<weather-conditions>
<value coverage="chance" intensity="light" weather-type="rain" qualifier="none">
<visibility xsi:nil="true"/>
</value>
<value coverage="chance" intensity="light" additive="and" weather-type="snow" qualifier="none">
<visibility xsi:nil="true"/>
</value>
</weather-conditions>
</weather>
</parameters>
</data>
</dwml>

编辑:解析此文件后,这就是var_dump($content->data->parameters[0]->weather);产生的结果:

object(SimpleXMLElement)#4 (3) {
  ["@attributes"]=>
  array(1) {
    ["time-layout"]=>
    string(11) "k-p3h-n41-3"
  }
  ["name"]=>
  string(37) "Weather Type, Coverage, and Intensity"
  ["weather-conditions"]=>
  array(41) {
    [0]=>
    object(SimpleXMLElement)#2 (1) {
      ["value"]=>
      object(SimpleXMLElement)#45 (2) {
        ["@attributes"]=>
        array(4) {
          ["coverage"]=>
          string(13) "slight chance"
          ["intensity"]=>
          string(5) "light"
          ["weather-type"]=>
          string(4) "snow"
          ["qualifier"]=>
          string(4) "none"
        }
        ["visibility"]=>
        object(SimpleXMLElement)#46 (0) {
        }
      }
    }
    [1]=>
    object(SimpleXMLElement)#5 (1) {
      ["value"]=>
      object(SimpleXMLElement)#45 (2) {
        ["@attributes"]=>
        array(4) {
          ["coverage"]=>
          string(13) "slight chance"
          ["intensity"]=>
          string(5) "light"
          ["weather-type"]=>
          string(4) "snow"
          ["qualifier"]=>
          string(4) "none"
        }
        ["visibility"]=>
        object(SimpleXMLElement)#46 (0) {
        }
      }
    }
    [2]=>
    object(SimpleXMLElement)#6 (1) {
      ["value"]=>
      object(SimpleXMLElement)#45 (2) {
        ["@attributes"]=>
        array(4) {
          ["coverage"]=>
          string(6) "chance"
          ["intensity"]=>
          string(5) "light"
          ["weather-type"]=>
          string(4) "snow"
          ["qualifier"]=>
          string(4) "none"
        }
        ["visibility"]=>
        object(SimpleXMLElement)#46 (0) {
        }
      }
    }
    [3]=>
    object(SimpleXMLElement)#7 (1) {
      ["value"]=>
      object(SimpleXMLElement)#45 (2) {
        ["@attributes"]=>
        array(4) {
          ["coverage"]=>
          string(6) "likely"
          ["intensity"]=>
          string(5) "light"
          ["weather-type"]=>
          string(4) "snow"
          ["qualifier"]=>
          string(4) "none"
        }
        ["visibility"]=>
        object(SimpleXMLElement)#46 (0) {
        }
      }
    }
    [4]=>
    object(SimpleXMLElement)#8 (1) {
      ["value"]=>
      object(SimpleXMLElement)#45 (2) {
        ["@attributes"]=>
        array(4) {
          ["coverage"]=>
          string(10) "definitely"
          ["intensity"]=>
          string(5) "light"
          ["weather-type"]=>
          string(4) "snow"
          ["qualifier"]=>
          string(4) "none"
        }
        ["visibility"]=>
        object(SimpleXMLElement)#46 (0) {
        }
      }
    }
    [5]=>
    object(SimpleXMLElement)#9 (1) {
      ["value"]=>
      object(SimpleXMLElement)#45 (2) {
        ["@attributes"]=>
        array(4) {
          ["coverage"]=>
          string(10) "definitely"
          ["intensity"]=>
          string(5) "light"
          ["weather-type"]=>
          string(4) "snow"
          ["qualifier"]=>
          string(4) "none"
        }
        ["visibility"]=>
        object(SimpleXMLElement)#46 (0) {
        }
      }
    }
    [6]=>
    object(SimpleXMLElement)#10 (1) {
      ["value"]=>
      array(2) {
        [0]=>
        object(SimpleXMLElement)#45 (2) {
          ["@attributes"]=>
          array(4) {
            ["coverage"]=>
            string(10) "definitely"
            ["intensity"]=>
            string(8) "moderate"
            ["weather-type"]=>
            string(4) "snow"
            ["qualifier"]=>
            string(4) "none"
          }
          ["visibility"]=>
          object(SimpleXMLElement)#47 (0) {
          }
        }
        [1]=>
        object(SimpleXMLElement)#46 (2) {
          ["@attributes"]=>
          array(5) {
            ["coverage"]=>
            string(5) "areas"
            ["intensity"]=>
            string(4) "none"
            ["additive"]=>
            string(3) "and"
            ["weather-type"]=>
            string(12) "blowing snow"
            ["qualifier"]=>
            string(4) "none"
          }
          ["visibility"]=>
          object(SimpleXMLElement)#47 (0) {
          }
        }
      }
    }
    [7]=>
    object(SimpleXMLElement)#11 (1) {
      ["value"]=>
      array(2) {
        [0]=>
        object(SimpleXMLElement)#46 (2) {
          ["@attributes"]=>
          array(4) {
            ["coverage"]=>
            string(10) "definitely"
            ["intensity"]=>
            string(8) "moderate"
            ["weather-type"]=>
            string(4) "snow"
            ["qualifier"]=>
            string(4) "none"
          }
          ["visibility"]=>
          object(SimpleXMLElement)#47 (0) {
          }
        }
        [1]=>
        object(SimpleXMLElement)#45 (2) {
          ["@attributes"]=>
          array(5) {
            ["coverage"]=>
            string(5) "areas"
            ["intensity"]=>
            string(4) "none"
            ["additive"]=>
            string(3) "and"
            ["weather-type"]=>
            string(12) "blowing snow"
            ["qualifier"]=>
            string(4) "none"
          }
          ["visibility"]=>
          object(SimpleXMLElement)#47 (0) {
          }
        }
      }
    }
    [8]=>
    object(SimpleXMLElement)#12 (1) {
      ["value"]=>
      array(2) {
        [0]=>
        object(SimpleXMLElement)#45 (2) {
          ["@attributes"]=>
          array(4) {
            ["coverage"]=>
            string(10) "definitely"
            ["intensity"]=>
            string(8) "moderate"
            ["weather-type"]=>
            string(4) "snow"
            ["qualifier"]=>
            string(4) "none"
          }
          ["visibility"]=>
          object(SimpleXMLElement)#47 (0) {
          }
        }
        [1]=>
        object(SimpleXMLElement)#46 (2) {
          ["@attributes"]=>
          array(5) {
            ["coverage"]=>
            string(5) "areas"
            ["intensity"]=>
            string(4) "none"
            ["additive"]=>
            string(3) "and"
            ["weather-type"]=>
            string(12) "blowing snow"
            ["qualifier"]=>
            string(4) "none"
          }
          ["visibility"]=>
          object(SimpleXMLElement)#47 (0) {
          }
        }
      }
    }
    [9]=>
    object(SimpleXMLElement)#13 (1) {
      ["value"]=>
      array(2) {
        [0]=>
        object(SimpleXMLElement)#46 (2) {
          ["@attributes"]=>
          array(4) {
            ["coverage"]=>
            string(10) "definitely"
            ["intensity"]=>
            string(8) "moderate"
            ["weather-type"]=>
            string(4) "snow"
            ["qualifier"]=>
            string(4) "none"
          }
          ["visibility"]=>
          object(SimpleXMLElement)#47 (0) {
          }
        }
        [1]=>
        object(SimpleXMLElement)#45 (2) {
          ["@attributes"]=>
          array(5) {
            ["coverage"]=>
            string(5) "areas"
            ["intensity"]=>
            string(4) "none"
            ["additive"]=>
            string(3) "and"
            ["weather-type"]=>
            string(12) "blowing snow"
            ["qualifier"]=>
            string(4) "none"
          }
          ["visibility"]=>
          object(SimpleXMLElement)#47 (0) {
          }
        }
      }
    }
    [10]=>
    object(SimpleXMLElement)#14 (1) {
      ["value"]=>
      array(2) {
        [0]=>
        object(SimpleXMLElement)#45 (2) {
          ["@attributes"]=>
          array(4) {
            ["coverage"]=>
            string(6) "chance"
            ["intensity"]=>
            string(5) "light"
            ["weather-type"]=>
            string(4) "snow"
            ["qualifier"]=>
            string(4) "none"
          }
          ["visibility"]=>
          object(SimpleXMLElement)#47 (0) {
          }
        }
        [1]=>
        object(SimpleXMLElement)#46 (2) {
          ["@attributes"]=>
          array(5) {
            ["coverage"]=>
            string(5) "areas"
            ["intensity"]=>
            string(4) "none"
            ["additive"]=>
            string(3) "and"
            ["weather-type"]=>
            string(12) "blowing snow"
            ["qualifier"]=>
            string(4) "none"
          }
          ["visibility"]=>
          object(SimpleXMLElement)#47 (0) {
          }
        }
      }
    }
...//More in here, trivial.
    [40]=>
    object(SimpleXMLElement)#44 (1) {
      ["value"]=>
      array(2) {
        [0]=>
        object(SimpleXMLElement)#45 (2) {
          ["@attributes"]=>
          array(4) {
            ["coverage"]=>
            string(6) "chance"
            ["intensity"]=>
            string(5) "light"
            ["weather-type"]=>
            string(4) "rain"
            ["qualifier"]=>
            string(4) "none"
          }
          ["visibility"]=>
          object(SimpleXMLElement)#47 (0) {
          }
        }
        [1]=>
        object(SimpleXMLElement)#46 (2) {
          ["@attributes"]=>
          array(5) {
            ["coverage"]=>
            string(6) "chance"
            ["intensity"]=>
            string(5) "light"
            ["additive"]=>
            string(3) "and"
            ["weather-type"]=>
            string(4) "snow"
            ["qualifier"]=>
            string(4) "none"
          }
          ["visibility"]=>
          object(SimpleXMLElement)#47 (0) {
          }
        }
      }
    }
  }
}

由于末尾的元素有时会为空,我想要最新的非空天气项,我将x设置为天气数组中最后一项的索引,并尝试向后工作,但页面只是不加载,错误日志中没有任何内容。 编辑:我已经改变了方法,试图让它更容易理解:

for($x=0; $content->data->parameters[0]->weather->{"weather-conditions"}[count($content->data->parameters[0]->weather->children())-$x]['weather-type']==NULL; $x++){
    echo $x."\n";
}

编辑:如果不清楚,我需要通过一系列儿童而不是前锋来向后递归。

2 个答案:

答案 0 :(得分:1)

我可以在你的问题中找到一些不同的问题:

XML无效。请在提问时提供工作数据,此处<location>元素已打开且从未关闭。我的其余部分的前提是这个开始标记已被删除

不会阻止无限循环。 $x低于0是没有意义的,但是你没有检查。你应该添加这样一个检查,这样你就不会因为你在中断决策逻辑的另一部分犯了一些错误而创建了无限循环:

for (
    $x = count($content->data->parameters[0]->weather->children());
    $x >= 0 && $content->data->weather->{"weather-conditions"}[$x]['weather-type'] == NULL;
    --$x
) {
    echo $x . "\n";
}

使用(固定)示例数据,现在将从42减少到0但不低于0.至少已删除无限循环。清除这些技术问题后,您可以关注问题域:

  

由于末尾的元素有时会为空,我想要最新的非空天气项目

嗯,您的实际示例XML不包含任何<weather>元素(<weather>元素没有任何子元素。所以不清楚您要问的是什么约。

然而,它包含空的<weather-conditions/>元素,因此作为其余答案的先决条件,我采用了它。

XML没有特定的顺序 - 至少不是设计 - 并且正如您的示例XML所示,空的<weather-conditions/>元素更多地位于文档的中间而不是最后。您真正想要的是包含子元素的所有<weather-conditions>元素(此处为<value>)。使用xpath查询可以做到最好。

因此,您首先查询拥有 <value>子元素的所有元素,然后获取最后一个元素(按文档顺序)。所以我们走了:

list($lastCondition) = $content->xpath('
    (
        /*/data/parameters/weather/weather-conditions[value]
    )[position() = last()]
');

变量$lastCondition然后包含最后一个非空元素,这里是基于示例XML的XML输出:

<weather-conditions>
                    <value coverage="chance" intensity="light" weather-type="rain" qualifier="none">
                        <visibility xsi:nil="true"/>
                    </value>
                    <value coverage="chance" intensity="light" additive="and" weather-type="snow" qualifier="none">
                        <visibility xsi:nil="true"/>
                    </value>
                </weather-conditions>

正如你所看到的,你的问题有很多不清楚的地方,这使得回答更难。最后,我希望这仍然有用。

使用的方法是SimpleXMLElement::xpath(),在W3C网站XML Path Language (XPath) Version 1.0上指定了Xpath 1.0(由该方法使用),Stackoverflow本身包含很多示例,因此在这里搜索总是一个不错的选择第一

答案 1 :(得分:0)

事实证明我在层次结构中跳过了几个级别,这就是为什么检查字符串是否为NULL的条件总是返回TRUE(因此是无限循环)。最终代码:

for($x=count($content->data->parameters[0]->weather->children()); $x>0; $x--){
    if($content->data->parameters[0]->weather->{"weather-conditions"}[$x]!=NULL){
        return $content->data->parameters[0]->weather->{"weather-conditions"}[$x][0]->value['weather-type'];
    }
}