在PHP foreach循环中考虑缺少数组键

时间:2012-07-16 19:39:14

标签: php arrays foreach

我正在使用PHP和Xpath解析几个不同值的文档。我将我的Xpath查询的结果/匹配丢弃到一个数组中。例如,我像这样构建我的$prices array

$prices = array();
$result = $xpath->query("//div[@class='the-price']");
foreach ($result as $object) {
$prices[] = $object->nodeValue; }

一旦我构建了数组,我就会遍历并将值抛出到某些HTML中:

$i = 0;
foreach ($links as $link) {
    echo <<<EOF
<div class="the-product">
    <div class="the-name"><a title="{$names[$i]}" href="{$link}" target="blank">{$names[$i]}</a></div>
    <br />
    <div class="the-image"><a title="{$names[$i]}" href="{$link}" target="blank"><img src="{$images[$i]}" /></a></div>
    <br />
    <div class="the-current-price">Price is: <br> {$prices[$i]}</div>
</div>
EOF;
    $i++; }

问题是,我正在解析的原始文档中的某些项目没有价格,因为它们甚至不包含<div class='the-price'>,所以我的Xpath找不到值,并且没有在$prices array中插入值。我最终返回 20 产品,以及一个仅包含 17 键/值的数组,导致整个地方出现Notice: Undefined offset错误。

所以我的问题是,如何解决缺少键值的项目并丢弃我的数组?我可以在这些项目的数组中插入虚拟值吗?我已经尝试了尽可能多的不同解决方案。主要是,我的foreach循环中的IF语句,但似乎没有任何作用。

谢谢

4 个答案:

答案 0 :(得分:0)

我建议您在html中查找一个元素,该元素始终存在于“price”-loop中。找到此对象后,您开始查找“price”元素,如果没有,则在数组中插入空字符串等。

答案 1 :(得分:0)

不要直接查找the-price元素,而是查找包含the-product的内容。循环那些,然后使用这些节点作为起始上下文做一个子查询。通过这种方式,您可以获得所有the-product个节点,以及拥有它们的节点的价格。

e.g。

$products = array();
$products = $xpath->query("//div[@class='the-product']");
$found = 0 ;
foreach ($products as $product) {
   $products[$found] = array();
   $price = $xpath->query("//div[@class='the-price']", $product);
   if ($price->length > 0) {
       $products[$found] = $price->item(0)->nodeValue;
   }
   $found++;
}

答案 2 :(得分:0)

如果您不想展示没有附加价格的产品,您可以检查是否先设置$prices[$i]

foreach($links AS $link){
    if(isset($prices[$i])){
        // echo content
    }
}

或者,如果你想填补它,你可以说虚拟值

$prices = array_merge($prices,
              array_fill(count($prices), count($links)-count($prices),0));

这将插入0作为任何剩余值的虚拟值。 array_fill从数组的第一个索引开始(所以我们在$prices中的键数量之后开始一个),然后我们需要填充多少,所以我们减去{{1}中有多少个1}}来自$prices中的多少,然后我们用虚拟值0填充它。

或者你可以在第一个例子中使用相同的逻辑,然后通过说:

来应用它
$links

答案 3 :(得分:0)

很难理解$ links和$ price与显示的代码之间的关系。由于你构建的$ prices数组与$ links数组没有任何关系,所以我不知道你会怎么做。

$ link也是通过xpath构建的吗?如果是这样,'the-price'div是否总是嵌套在用于填充$ links的DOM元素中?

如果是,您可以嵌套您的xpath查询以查找用于查找链接的查询中的价格,并使用计数器来匹配这两个链接。

$links_result = $xpath->query('path-to-link')
$i = 0
foreach ($links_result as $link_object) {
    $links[$i] = $link_object->nodeValue;
    // pass $link_object as context reference to xpath query looking for price
    $price_result = $xpath->query('path-to-price-within-link-node', $link_object);
    if (false !== $price_result) {
        $prices[$i] = $price_result->nodeValue;
    } else {
        $prices[$i] = 0; // or whatever value you want to show to indicate that no price was available.
    }
    $i++;
}

显然,可以在那里进行额外的处理,以验证每个链接节点只存在一个价格值,等等,但这是基本的想法。