phpobjectzend-search-lucene

Check if a field/propertry exists in a variable of type object


I am using Zend_Search_Lucene, to index my website. My site indexes are not entirely similar. Some have, few fields, and some have many fields. I am trying to create a similar index through different types of table, that's why i am encountering this kind of error.

Now, when I display the result. I call some fields, which are not present in all the result which generates the error. i tried to check it with isset but it seems it totally skips the row.

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>';
}

How to check if there is anything such as $hit -> name is present in $hit


Solution

  • The problem you are experiencing is very very specific and has to do with the Zend_Lucene_Search implementation, not the field/property exist check in general.

    In your loop, $hit is an object of class Zend_Search_Lucene_Search_QueryHit. When you write the expression $hit->name, the object calls the magic __get function to give you a "virtual property" named name. It is this magic function that throws the exception if the value to be supplied does not exist.

    Normally, when a class implements __get as a convenience it should also implement __isset as a convenience (otherwise you cannot really use isset on such virtual properties, as you have found out the hard way). Since this particular class does not implement __isset as IMHO it should, you will never be able to get the name "property" blindly without triggering an exception if the relevant data does not exist.

    property_exists and all other forms of reflection will also not help since we are not talking about a real property here.

    The proper way to solve this is a little roundabout:

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

    All said, I 'd consider this a bug in ZF and probably file a report, asking for the __isset magic method to be implemented appropriately on the types it should be.