2011-10-12 42 views
2

我想將行對象傳遞給一個函數,該函數使用存儲在行中的配置信息來構建一個Zend Search Lucene Document並將其添加到我的索引。如何按名稱調用方法?

存儲的信息如下所示:

protected $_index = array(
    'url' => array('UnIndexed', 'getUrl()'), 
    'fragment' => array('UnIndexed', 'getFragment()'), 
    'edited' => array('UnIndexed', 'edited'), 
    'title' => array('Text', 'getTitle()'), 
    'summary' => array('Text', 'getSummary()'), 
    'text' => array('UnStored', 'getText()'), 
); 

這是我調用該函數:

public static function addDoc(My_Db_Table_Row_Abstract $row) 
{ 
    $config = $row->getIndexConfig(); 
    if (empty($config)) { 
     return; 
    } 

    // setup the document 
    $document = new Zend_Search_Lucene_Document(); 
    $document->addField(Zend_Search_Lucene_Field::keyword('table_name', $row->getTable()->info('name'))) 
      ->addField(Zend_Search_Lucene_Field::keyword('table_row_key', $row->getIndexRowKey())); 

    // add the configured fields 
    foreach ($config as $name => $opts) { 
     $type = $opts[0]; 
     $value = eval('return $row->' . $opts[1]); 
     switch ($type) { 
      case 'Keyword' : 
       $field = Zend_Search_Lucene_Field::keyword($name, $value); 
       break; 
      case 'UnIndexed' : 
       $field = Zend_Search_Lucene_Field::unIndexed($name, $value); 
       break; 
      case 'Binary' : 
       $field = Zend_Search_Lucene_Field::binary($name, $value); 
       break; 
      case 'Text' : 
       $field = Zend_Search_Lucene_Field::text($name, $value); 
       break; 
      case 'UnStored ' : 
       $field = Zend_Search_Lucene_Field::unStored($name, $value); 
       break; 
     } 
     $document->addField($field); 
    } 

    // add to the index 
    self::getIndex()->addDocument($document); 
} 

正如你所看到的,我需要的信息通過函數調用到文檔中的字段。我很關心使用eval(),但我不知道另一種方式。有沒有更好的方法來完成相同的功能?


SOLUTION

我改變用於所有領域的功能(刪除括號)的配置數據,以及下套管,所述type的第一個字母,所以我可以利用它來進行call_user_func作爲好:

protected $_index = array(
    'url' => array('unIndexed', 'getUrl'), 
    'fragment' => array('unIndexed', 'getFragment'), 
    'edited' => array('unIndexed', 'getEdited'), 
    'active_self' => array('keyword', 'isActive'), 
    'active_block' => array('keyword', 'isActiveBlock'), 
    'active_page' => array('keyword', 'isActiveNav'), 
    'members_only' => array('keyword', 'isMembersOnly'), 
    'title' => array('text', 'getTitle'), 
    'summary' => array('text', 'getSummary'), 
    'text' => array('unStored', 'getText'), 
); 

和函數調用,它結束了簡單得多:

public static function addDoc(My_Db_Table_Row_Abstract $row) 
{ 
    $config = $row->getIndexConfig(); 
    if (empty($config)) { 
     return; 
    } 

    // setup the document 
    $document = new Zend_Search_Lucene_Document(); 
    $document->addField(Zend_Search_Lucene_Field::keyword('table_name', $row->getTable()->info('name'))) 
      ->addField(Zend_Search_Lucene_Field::keyword('table_row_key', $row->getIndexRowKey())); 

    // add the configured fields 
    foreach ($config as $name => $opts) { 
     $value = call_user_func(array($row, $opts[1])); 
     $field = call_user_func(array('Zend_Search_Lucene_Field', $opts[0]), $name, $value); 
     $document->addField($field); 
    } 

    // add to the index 
    self::getIndex()->addDocument($document); 
} 
+0

你試過$ objectInstance - > $方法名()?我知道這適用於實例變量。 –

+0

'$ value = $ row - > {$ opts [1]};' –

回答

2

您還可以使用call_user_func。這裏是PHP doc

實施例:

<?php 
function barber($type) 
{ 
    echo "You wanted a $type haircut, no problem\n"; 
} 
call_user_func('barber', "mushroom"); 
call_user_func('barber', "shave"); 
?> 

輸出:

You wanted a mushroom haircut, no problem 
You wanted a shave haircut, no problem 

對於你例如,你需要改變:

$value = eval('return $row->' . $opts[1]); 

通過

$value = call_user_func($row->' . $opts[1]); 
+0

擊敗我5秒:)。這裏有一個文檔鏈接:http://www.php.net/manual/en/function.call-user-func.php –

+0

從我看到的例子中,'call_user_func'調用靜態函數。你如何改變我的代碼中使用'call_user_func'的行? – Sonny

+0

它可能會調用靜態...並不意味着它也有:) –

2

我想你可以這樣做:

// ... 
$type = $opts[0]; 
$method = $opts[1]; 
$value = $row->$method; 

或者:

// ... 
$type = $opts[0]; 
call_user_func(array($row, $opts[1])); 
2

從你的方法名稱中刪除括號:

protected $_index = array(
    'url' => array('UnIndexed', 'getUrl'), 
    'fragment' => array('UnIndexed', 'getFragment'), 
    ... 

替換此屬性:

'edited' => array('UnIndexed', 'edited'), 

用等價的getter m ethod:

'edited' => array('UnIndexed', 'getEdited'), 

然後只是這樣做:

$method = $opts[1]; 
$value = $row->$method();