1

我正在使用 Zend_Search_Lucene 来索引我的网站。我的网站索引并不完全相似。有的有,很少的领域,有的有很多领域。我试图通过不同类型的表创建一个类似的索引,这就是我遇到这种错误的原因。

现在,当我显示结果时。我调用了一些字段,这些字段并不存在于生成错误的所有结果中。我试图用它来检查它,isset但它似乎完全跳过了这一行。

foreach ($hits as $hit) {
    $content .= '<div class="searchResult">';
      $content .= '<h2>';           
        $title = array();
        if(isset($hit -> name)) $title[] = $hit -> name;
        if(isset($hit -> title)) $title[] = $hit -> title;
            // This is the part where i get fatal error.
        $content .= implode(" &raquo; ",$title);
      $content .= '</h2>';
      $content .= '<p>'.$this->content.'</p>';
    $content .= '</div>';
}

如何检查是否有任何东西$hit -> name存在$hit

4

5 回答 5

5

您遇到的问题非常具体,与Zend_Lucene_Search实施有关,而不是一般的字段/属性存在检查。

在您的循环中,$hit是 class 的对象Zend_Search_Lucene_Search_QueryHit。当您编写表达式$hit->name时,对象会调用魔术__get函数来为您提供一个名为 的“虚拟属性” name。如果要提供的值不存在,正是这个神奇的函数抛出异常。

通常,当一个类实现__get为方便时,它也应该实现__isset为方便(否则您无法真正isset在此类虚拟属性上使用,因为您已经发现了困难的方法)。由于这个特定的类没有像恕我直言它应该实现的那样,如果相关数据不存在__isset,您将永远无法盲目地获取“属性”而不触发异常。name

property_exists并且所有其他形式的反射也无济于事,因为我们在这里不是在谈论不动产。

解决这个问题的正确方法是有点迂回:

$title = array();
$names = $hit->getDocument()->getFieldNames();
if(in_array('name', $names)) $title[] = $hit -> name;
if(in_array('title',$names)) $title[] = $hit -> title;

总而言之,我认为这是 ZF 中的一个错误,并且可能会提交一份报告,要求在__isset它应该是的类型上适当地实现魔术方法。

于 2011-04-11T14:42:17.620 回答
0

你可以试试property_exists

foreach ($hits as $hit) {
    $content .= '<div class="searchResult">';
      $content .= '<h2>';           
        $title = array();
        if(property_exists($hit, 'name')) $title[] = $hit -> name;
        if(property_exists($hit, 'title')) $title[] = $hit -> title;
            // This is the part where i get fatal error.
        $content .= implode(" &raquo; ",$title);
      $content .= '</h2>';
      $content .= '<p>'.$this->content.'</p>';
    $content .= '</div>';
}
于 2011-04-11T14:20:04.127 回答
0

您还可以使用反射来查询对象具有哪些字段,并以更加程序化的方式构建您的内容。如果你有很多字段,这很好。

$reflector = new ReflectionClass( get_class( $hit ) );
foreach( $reflector->getProperties() as $property  ) {
    if( in_array( $property->getName(), $SEARCH_FIELDS )
        $title[] = $property->getValue( $hit );
}

更多信息在这里: http: //php.net/manual/en/book.reflection.php

于 2011-04-11T14:25:29.083 回答
0
# Verify if exists
$hits = $index->find('id_field:100');
if (isset($hits[0])) { echo 'true'; } else { echo 'false'; }
于 2011-09-06T15:18:45.940 回答
0

如果您只是先将对象转换为数组,则 isset 将起作用。

<?php
class Obj {
    public function GetArr() {
        return (array)$this;
    }
    static public function GetObj() {
        $obj = new Obj();
        $obj->{'a'} = 1;
        return $obj;
    }
}

$o = \Obj::GetObj();
$a = $o->GetArr();
echo 'is_array: ' . (\is_array($a) ? 1 : 0) . '<br />';
if (\is_array($a)) {
    echo '<pre>' . \print_r($a, \TRUE) . '</pre><br />';
}
echo '<pre>' . \serialize($o) . '</pre>';
?>
于 2011-12-04T21:11:12.637 回答