
Originally Posted by
mwmitchell
Hey, would you mind posting your active record class?
After spending alot of time implementing Row and Table data gateways very much like Jason does in his patterns book and trying other implementations, I eventually settled for an implementation I saw at
daholygoat.
What I currently have must be accredited to the implementation on the site above. It suites me as I can create CRUD stuff quickly with a base class like this. I gladly include my revised version. I changed the mysql stuff to support adodb and therefor prepared queries. I must still include things like orderby for queries and would like to include a static array to support locator functionality. I will also take the abuse of things done incorrectly or that could be implemented better 
The abstract class:
PHP Code:
abstract class ActiveRecord
{
protected $conn;
protected $data = array();
protected $fields = array();
protected $primary = array();
protected $queryPrepaired = array();
protected $queryPairs = array();
protected $queryValues = array();
protected $table = '';
public function __construct()
{
$this->conn = DB::conn();
$this->initFields();
$this->initTable();
$this->initPrimary();
}
public function set($key, $value)
{
$getAccessor = 'get'.ucfirst($key);
if ( method_exists($this, $getAccessor) ) {
return $this->$getAccessor();
} else {
$this->data[$key] = $value;
}
}
public function __set($key, $value)
{
$this->set($key, $value);
}
public function get($key)
{
$getAccessor = 'get'.ucfirst($key);
if ( method_exists($this, $getAccessor) ) {
return $this->$getAccessor();
} else {
if ( isset($this->data[$key]) ) {
return $this->data[$key];
} else {
return false;
}
}
}
public function __get($key)
{
return $this->get($key);
}
public function getAll()
{
$this->setQueryFields();
$sql = 'SELECT * FROM '.$this->table;
if ( count($this->data) > 0 ) {
$sql .= ' WHERE '.implode(' AND ', $this->queryPairs);
}
$rs = $this->conn->execute($sql, $this->queryValues);
$count = $rs->numRows();
foreach ( $rs as $row ) {
$className = get_class($this);
$result = new $className();
$result->load($row);
$results[] = $result;
}
return $results;
}
public function fetch()
{
$this->setQueryFields();
$sql = 'SELECT * FROM '.$this->table;
if ( count($this->data) > 0 ) {
$sql .= ' WHERE '.implode(' AND ', $this->queryPairs);
}
$rs = $this->conn->execute($sql, $this->queryValues);
if ( $rs ) {
$this->load($rs->fields);
}
}
public function unsetAttr($key = '')
{
if ( empty($key) ) {
$this->data = array();
} else {
unset($this->data[$key]);
}
flush();
}
public function insert()
{
$this->setQueryFields();
$sql = 'INSERT INTO '.$this->table.' ('.implode(', ', array_keys($this->queryPairs)).') '.
'VALUES ('.implode(', ', $this->queryPrepaired).')';
$rs = $this->conn->execute($sql, $this->queryValues);
if ( !$rs ) {
trigger_error("Database Query Error: INSERT");
}
}
public function update()
{
$this->setQueryFields();
$sql = 'UPDATE '.$this->table.' SET '.implode(', ', $this->queryPairs).' '.
'WHERE '.implode(', ', $this->setQueryPrimary());
$rs = $this->conn->execute($sql, $this->queryValues);
if ( !$rs ) {
trigger_error("Database Query Error: UPDATE");
}
}
public function delete()
{
$this->setQueryFields();
$sql = 'DELETE FROM '.$this->table.' WHERE '.implode(' AND ', $this->queryPairs);
$rs = $this->conn->execute($sql, $this->queryValues);
if ( !$rs ) {
trigger_error("Database Query Error: DELETE");
}
}
protected function load($data)
{
foreach ( $data as $key => $value ) {
$this->data[$key] = $value;
}
}
protected function setQueryFields()
{
$this->queryPairs = array();
$this->queryValues = array();
foreach ( $this->data as $key => $value ) {
$this->queryPrepaired[] = '?';
$this->queryPairs[$key] = $key .' = ?';
$this->queryValues[] = $value;
}
}
protected function setQueryPrimary()
{
$primary = array();
foreach ( $this->primary as $key ) {
$primary[$key] = $key.' = ?';
$this->queryValues[] = $this->data[$key];
}
return $primary;
}
abstract function initFields();
abstract function initTable();
abstract function initPrimary();
}
A user table class:
PHP Code:
class User extends ActiveRecord
{
public function __construct($id = NULL)
{
parent::__construct();
if ( $id ) {
$this->set($this->primary[0], $id);
$this->fetch();
}
}
public function initFields()
{
$this->fields = array (
'userID',
'title',
'name',
'surname',
'email',
'password',
'active'
);
}
public function initTable()
{
$this->table = 'user';
}
public function initPrimary()
{
$this->primary[] = 'userID';
}
public function getFullname()
{
return $this->data['title'].', '.$this->data['name'].' '.$this->data['surname'];
}
}
Usage of the class:
PHP Code:
$user = new User();
$user->set('title', 'Mr');
$user->set('name', 'Frodo');
$user->set('surname', 'Baggins');
$user->set('email', 'frodo@the-shire.com');
$user->insert();
$user->unsetAttr();
$rs = $user->getAll();
foreach ( $rs as $result ) {
echo $result->get('fullname') ."\n";
/* OR */
echo $result->fullname ."\n";
}
$user->unsetAttr();
$user->set('name', 'Frodo');
$user->delete();
$user->unsetAttr();
$user->set('userID', 1);
$user->set('title', 'title');
$user->set('name', 'name');
$user->set('surname', 'surname');
$user->set('email', 'email');
$user->update();
$newUser = new User(1);
echo $newUser->fullname ."\n";
--
lv
Bookmarks