Sunday, 24 September 2017

php - "Could not execute Model_Hotel::__construct()" with mysql_fetch_object, properties remain uninitialized



I'm running PHP 5.3.6 with MAMP 2.0.1 on Mac OS X Lion and I'm using Kohana 3.1.3.1.




I try to override the __set() and __get() methods of the standard Kohana ORM module with my own methods. Some of my models extend my class which extends the ORM class.




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);
}

}

}


But in PHP 5.3.6, I get the following error message:




Exception [ 0 ]: Could not execute Model_Hotel::__construct()





Model_Hotel extends this class and does not have an own construct.
This is the code of Model_Hotel, a standard Kohana ORM model: http://pastie.org/private/vuyig90phwqr9f34crwg



With PHP 5.2.17, I get another one:




ErrorException [ Warning ]: array_key_exists() [function.array-key-exists]: The second argument should be either an array or an object





In Kohana, my model which extends my class is called by mysql_fetch_object(), somewhere deep in the orm modules code.



However, if I echo the called property in __set() and exit (#4 and #5) afterwards, it outputs "SET::id" and doesn't show the error message.



If I var_dump() $this->_table_columns (or any other property of this class, #3), I get "NULL" which is the value that this property has before it's initialized.
If I repeat the same with $this->_languages, I get an empty array which should be filled with several languages. It's like the class was never initialized with the __construct. This explains the error which I get in PHP 5.2.17, because $this->_table_columns is NULL and not an array.



I can uncomment my __construct and I still get the same error, the fault has to be in my localization() method.



I searched for several days now and I have absolutely no idea what could be wrong.



Answer



ORM::__set() is expected to load cast data from mysql_fetch_object() call. You must allow it to set casted value for this cause:



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 I don't like this solution either, you should be overriding ORM::set() instead.


No comments:

Post a Comment

casting - Why wasn't Tobey Maguire in The Amazing Spider-Man? - Movies & TV

In the Spider-Man franchise, Tobey Maguire is an outstanding performer as a Spider-Man and also reprised his role in the sequels Spider-Man...