РЕДАКТИРОВАТЬ: Одна вещь, которую я не указал в исходном посте, это то, что я использую представление, чтобы собрать все соответствующие столбцы вместе. Пример кода не особо выделяет его, но если вы создаете представление, которое объединяет все, что вы хотите, то вы можете создать модель, основанную на этом, и запрос, а также модель будут очень простыми.
/ EDIT
Это не так уж сложно. Вы должны убедиться, что ваш класс модели выглядит как строка вашей базы данных, в противном случае вам придется выполнять сопоставление вручную. У меня есть базовый класс для моей модели базы данных, который выглядит следующим образом:
class Ashurex_Model
{
public function __construct($args = null)
{
if(is_array($args))
{
$this->setOptions($args);
}
}
// Magic setter changes user_id to setUserId
public function __set($name, $value)
{
$method = 'set' . Ashurex_Utilities::underscoreToCamelCase($name);
if (method_exists($this, $method))
{
$this->$method($value);
}
}
// Magic getter changes user_id to getUserId
public function __get($name)
{
$method = 'get' . Ashurex_Utilities::underscoreToCamelCase($name);
if (method_exists($this, $method))
{
return $this->$method();
}
}
public function __call($name, $args)
{
if (method_exists($this, $name))
{
return call_user_func_array(array($this, $name), $args);
}
}
// Used for initializing an object off the database row
// transforms all the row names (like user_id to UserId)
// from underscores to camel case
protected function setOptions(array $options)
{
foreach($options as $key => $value)
{
$this->__set($key,$value);
}
return $this;
}
}
Пример пользовательского класса будет выглядеть так:
class Ashurex_Model_User extends Ashurex_Model
{
protected $_id;
protected $_username;
protected $_userpass;
protected $_firstName;
{ ... }
public function getId(){ return $this->_id; }
public function getUsername(){ return $this->_username; }
public function getUserpass(){ return $this->_userpass; }
public function getFirstName(){ return $this->_firstName; }
{ ... }
public function setId($id){ $this->_id = $id; }
public function setUsername($username){ $this->_username = $username; }
public function setUserpass($password){ $this->_userpass = $password; }
public function setFirstName($firstName){ $this->_firstName = $firstName; }
{ ... }
// This function will help when automatically saving the object back to the database
// The array keys must be named exactly what the database columns are called
public function toArray()
{
$data = array(
'id' => $this->getId(),
'username' => $this->getUsername(),
'userpass' => $this->getUserpass(),
'first_name' => $this->getFirstName(),
{ ... }
);
return $data;
}
}
Таблица базы данных выглядит следующим образом:
CREATE TABLE IF NOT EXISTS `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(64) NOT NULL,
`userpass` varchar(160) NOT NULL,
`first_name` varchar(64) NOT NULL,
`last_name` varchar(64) NOT NULL,
`email` varchar(64) NOT NULL,
`role_id` tinyint(4) NOT NULL,
`is_active` tinyint(1) NOT NULL DEFAULT '1',
`force_password_change` tinyint(1) NOT NULL DEFAULT '0',
`creation_datetime` datetime NOT NULL,
`updated_datetime` datetime NOT NULL,
`user_salt` varchar(32) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `username` (`username`),
KEY `role_id` (`role_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
Как видите, наиболее важным аспектом является то, что вы называете столбцы соответствующим образом, чтобы ваш базовый класс модели мог "автоматически" сопоставить имя столбца с методом.
Наконец, вот как будет выглядеть код сохранения ...
public function save(Ashurex_Model $obj)
{
try
{
$data = $obj->toArray();
// If no id is set, we are inserting a new row
if(null === ($id = $data['id']))
{
unset($data['id']);
$this->getDbTable()->insert($data);
return $this->getDb()->lastInsertId();
}
else
{
// We have an Id, do an update
$where = $this->getDbTable()->getAdapter()->quoteInto('id = ?',array($id));
$this->getDbTable()->update($data,$where);
return $id;
}
}
catch(Exception $e)
{
self::logException(__METHOD__,$e);
}
return false;
}
Пример кода поиска выглядит следующим образом, поскольку вы можете видеть, что он инициализирует новый объект прямо из строки результатов базы данных на основе имен столбцов:
public function find($id)
{
try
{
$table = $this->getDbView();
$stmt = $table->select()
->where('id = ?')
->bind(array($id));
$row = $table->fetchRow($stmt);
if(!is_null($row))
{
$r = $row->toArray();
$obj = new Ashurex_Model_User($r);
return $obj;
}
else
{
return null;
}
}
catch(Exception $ex)
{
self::logException(__METHOD__,$ex);
return null;
}
}