检查对象类型的变量中是否存在字段/属性

时间:2011-04-11 13:53:44

标签: php object zend-search-lucene

我正在使用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等内容

5 个答案:

答案 0 :(得分:5)

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

在你的循环中,$hit是类Zend_Search_Lucene_Search_QueryHit的对象。当您编写表达式$hit->name时,对象会调用magic __get function来为您提供名为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魔术方法适当地应用于它应该的类型。

答案 1 :(得分: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>';
}

答案 2 :(得分: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

答案 3 :(得分:0)

# Verify if exists
$hits = $index->find('id_field:100');
if (isset($hits[0])) { echo 'true'; } else { echo 'false'; }

答案 4 :(得分: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>';
?>