我在Mac OS X Lion上使用MAMP 2.0.1运行PHP 5.3.6,我正在使用Kohana 3.1.3.1。
我尝试使用自己的方法覆盖标准Kohana ORM模块的__set()和__get()方法。我的一些模型扩展了我的类,扩展了ORM类。
<?php
class ORM_Localization extends ORM
{
protected static $_language_cache = array();
protected $_languages = array();
public function __construct($id = NULL)
{
parent::__construct($id);
// Load languages which are accepted by the client
$this->_languages = array_keys(Application::languages());
}
public function __get($name)
{
/* Debugging #1 */ echo 'GET'.$name;
/* Debugging #2 */ // exit;
return $this->localization($name);
}
public function __set($name, $value)
{
/* Debugging #3 */ var_dump($this->_table_columns);
/* Debugging #4 */ echo 'SET::'.$name;
/* Debugging #5 */ // exit;
$this->localization($name, $value);
}
public function localization($name, $value = NULL)
{
if (!array_key_exists($name, $this->_table_columns)) {
// Load avaiable languages from database if not already done
if (empty(ORM_Localization::$_language_cache)) {
ORM_Localization::$_language_cache = ORM::factory('languages')
->find_all()
->as_array('id', 'identifier');
}
$languages = array();
// Find the IDs of the languages from the database which match the given language
foreach ($this->languages as $language) {
$parts = explode('-', $language);
do {
$identifier = implode('-', $parts);
if ($id = array_search($identifier, ORM_Localization::$_language_cache)) {
$languages[] = $id;
}
array_pop($parts);
} while($parts);
}
// Find localization
foreach ($languages as $language) {
$localization = $this->localizations->where('language_id', '=', $language)->find();
try {
if ($value === NULL) {
return $localization->$name;
} else {
$localization->$name = $value;
}
} catch (Kohana_Exception $exception) {}
}
}
if ($value === NULL) {
return parent::__get($name);
} else {
parent::__set($name, $value);
}
}
}
但在PHP 5.3.6中,我收到以下错误消息:
异常[0]:无法执行Model_Hotel :: __ construct()
Model_Hotel扩展了这个类,没有自己的构造。 这是Model_Hotel的代码,是标准的Kohana ORM模型:http://pastie.org/private/vuyig90phwqr9f34crwg
使用PHP 5.2.17,我得到另一个:
ErrorException [Warning]:array_key_exists()[function.array-key-exists]:第二个参数应该是数组或对象
在Kohana中,扩展我的类的模型由mysql_fetch_object()调用,位于orm模块代码的深处。
但是,如果我在__set()中回显被调用的属性并在之后退出(#4和#5),它将输出“SET :: id”并且不显示错误消息。
如果我var_dump()$ this-&gt; _table_columns(或此类的任何其他属性,#3),我得到“NULL”,这是该属性在初始化之前的值。 如果我用$ this-&gt; _languages重复相同的操作,我会得到一个空数组,应该用几种语言填充。这就像是从未使用__construct初始化类。这解释了我在PHP 5.2.17中得到的错误,因为$ this-&gt; _table_columns是NULL而不是数组。
我可以取消注释__construct,但我仍然得到同样的错误,错误必须在我的localization()方法中。
我现在搜索了好几天,我完全不知道会出现什么问题。
答案 0 :(得分:3)
ORM::__set()
需要从mysql_fetch_object()
调用加载演员数据。您必须允许它为此原因设置转换值:
public function __set($column, $value)
{
if ( ! isset($this->_object_name))
{
// Object not yet constructed, so we're loading data from a database call cast
$this->_cast_data[$column] = $value;
}
else
{
// Set the model's column to given value
$this->localization($column, $value);
}
}
Altough我也不喜欢这个解决方案,你应该改为覆盖ORM::set()
。
答案 1 :(得分:1)
__construct()
。
$class = new Object;
答案 2 :(得分:0)
我遇到了关于这个问题的更多信息,因为我遇到了同样的问题。
1)我发现了一个PHP错误报告,该报告记录了在__construct()之前调用mysqli和mysql_fetch_object __set()的文件。该报告是从2009年开始的,据说是固定的,但在5.3版本中,我正在运行它似乎仍然存在。这是:https://bugs.php.net/bug.php?id=48487
2)如果在执行__set()
方法的过程中发生异常或发生其他错误,您将得到这个模糊的“无法调用X::__construct()
”消息而不是< em>真正的异常/错误消息。
我可以这样解决我的问题:
public function __set($key, $val){
if($constructor_has_not_run){
$this->__construct();
}
//do stuff
}
我的情况有点幸运,因为我可以让构造函数运行两次没有任何问题,但你可能不会在同一条船上。