2012-03-21 74 views
1

使用PHP 5.3,我目前正在編寫一個MVC應用程序,並且需要提取傳遞給模型進行驗證的數據,以發送回視圖進行重新驗證一個錯誤的表單。試圖通過__get()方法訪問私有變量返回null

模型中的字段標爲私有,如果它們出現在字段名稱的列表(因此控制器不能試圖改變類中的其他「業務」字段的內容,纔可以訪問。

在下面標記爲'BUG'的控制器區域中,嘗試訪問專用字段只會導致創建數組項,但設置爲null,而不是值。在調試器中,如果檢查源的字段($ templateM- > $場)它顯示正確的值

這是怎麼回事

在模型的基類:?

class model { 

protected $fieldNames; 

public function __get($name) 
{ 
    if ($name === 'fieldNames') 
     return $this->fieldNames; // Special exception for getting the list of fields 
    if ($name === 'errorList') 
     return $this->errorList; // special exception for getting the current errors 
    if (in_array($name, (array)$this->fieldNames)) 
     return $this->$name; 
    else 
     throw new Exception('Invalid access to private model field'); 
} 
} 

在模型:

class template extends model 
{ 
function __construct() 
{ 
    parent::__construct(); 
    $this->fieldNames = new immutableArray(array('id', 'etc')); 
} 

private $id = 0; 
private $etc = 1; 
} 

在控制器:

class templateManager extends controller 
{ 
    function create() 
    { 
     // Validate form data 
    $templateM = getModel('template'); 
    $templates = array(); 
    $bodyData = array(); 
    $bodyData['showSuccess'] = false; 

    $result = $templateM->validate(); 

    if ($result) 
    { 
     if ($templateM->save()) 
     { 
      $bodyData['showSuccess'] = true; 
     } 
    } 

    // Load present data (post insert) 
    $templates = $templateM->getAllAsArray(); 

    $bodyData['errorMessages'] = (array)$templateM->errorList; 

    $formData = array(); 
    if (count($bodyData['errorMessages']) > 0) 
    { 
     foreach($templateM->fieldNames as $field) 
      { 
       $formData[$field] = $templateM->$field; // <- BUG 
      } 
    } 

    $bodyData['formData'] = $formData; 

    $bodyData['templateData'] = $templates; 
    $this->_drawPage($bodyData); 
} 

回答

2

其實我會建議你停止濫用__get()。你已經有了太多的if,而且這個列表只會變得越來越長。更好地制定適當的吸氣和吸氣方法。

由於您的問題原因:Model::__get()無法訪問私有變量。如果將它們定義爲protected,它將起作用。

此外,您可能會發現this rant有用。至少「邊注」是它的一部分。

+0

謝謝你的答案。這是原型系統的一部分,所以我會着手尋找更好的解決方案來解決訪問問題。 – Nidonocu 2012-03-21 11:45:25

+0

@Nidonocu,OOP中最常見的建議是:支持合成而不是繼承。可能也適用於你的情況.. – 2012-03-21 11:48:10