使用PHP 5.3,我目前正在编写一个MVC应用程序,需要提取传递给模型进行验证的数据,以便在出现错误时发送回视图以重新生成表单。
模型中的字段被标记为私有字段,只有当它们出现在字段名称列表中时才能访问(因此控制器不能试图更改类中其他"业务"字段的内容。
在下面标记为"BUG"的控制器区域中,尝试访问专用字段只会导致创建数组项,但设置为null,而不是值。在调试器中,如果我检查源的字段($templateM->$field),它会显示正确的值。
怎么回事?
在模型基类中:
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);
}
实际上,我建议您停止滥用__get()
。你已经有太多的if了,而且这个列表只会越来越长。最好制作适当的getter和setter方法。
至于问题的原因:Model::__get()
无法访问私有变量。如果您将它们定义为protected
,它将起作用。
此外,你可能会发现这种咆哮很有用。至少它的"旁注"部分。