Проверьте, существует ли поле / Propertry в переменной типа объекта - PullRequest
1 голос
/ 11 апреля 2011

Я использую 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 ]

5 голосов
/ 11 апреля 2011

Проблема, с которой вы столкнулись, очень специфична и связана с реализацией Zend_Lucene_Search, а не с проверкой поля / свойства в целом.

В вашем цикле $hit является объектом класса Zend_Search_Lucene_Search_QueryHit.Когда вы пишете выражение $hit->name, объект вызывает функцию magic __get , чтобы получить «виртуальное свойство» с именем name.Именно эта магическая функция выдает исключение, если значение, которое нужно указать, не существует.

Обычно, когда класс реализует __get для удобства, он также должен реализовывать __isset для удобства (в противном случае выне может реально использовать isset на таких виртуальных свойствах, как вы выяснили, трудный путь).Поскольку данный конкретный класс не реализует __isset, как имхо, вы никогда не сможете получить «свойство» * 1021 вслепую без вызова исключения, если соответствующие данные не существуют.

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 для типов, которые должны быть.

0 голосов
/ 05 декабря 2011

isset будет работать, если вы сначала просто преобразуете свой объект в массив.

<code><?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) . '
«;} echo '
' . \serialize($o) . '
';?>
0 голосов
/ 06 сентября 2011
# Verify if exists
$hits = $index->find('id_field:100');
if (isset($hits[0])) { echo 'true'; } else { echo 'false'; }
0 голосов
/ 11 апреля 2011

Вы также можете использовать отражение, чтобы запросить, какие поля есть у объекта, и создать свой контент более программным способом. это хорошо, если у вас есть тонна полей.

$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

0 голосов
/ 11 апреля 2011

Вы можете попробовать 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>';
}
...