我正在使用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(" » ",$title);
$content .= '</h2>';
$content .= '<p>'.$this->content.'</p>';
$content .= '</div>';
}
如何检查$hit -> name
$hit
等内容
答案 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(" » ",$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 );
}
答案 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>';
?>