Created
February 5, 2010 11:59
-
-
Save dhotson/295737 to your computer and use it in GitHub Desktop.
A little Object Relational Mapper in PHP
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* A little Object Relational Mapper in PHP | |
* @author [email protected] | |
*/ | |
class Post | |
{ | |
public $title; | |
public $content; | |
} | |
class Comment | |
{ | |
public $post_id; | |
public $name; | |
public $content; | |
} | |
$db = new Db('blog.db', array('Post', 'Comment')); | |
$p1 = new Post(); | |
$p1->title = 'Welcome to my Blog!'; | |
$p1->content = 'This is my first post.. cool'; | |
$db->save($p1); | |
$p2 = new Post(); | |
$p2->title = 'My 2nd post'; | |
$p2->content = '2nd post.. Rad!'; | |
$db->save($p2); | |
$comment = new Comment(); | |
$comment->post = $p2; | |
$comment->name = 'Franklin'; | |
$comment->content = 'Cool blog dude...'; | |
$db->save($comment); | |
$p1->title = 'Welcome to my blaargh!'; | |
$db->save($p1); | |
$posts = $db->table('Post')->all(); | |
foreach ($posts as $post) | |
echo "Post #$post->id : $post->title > $post->content\n"; | |
// ---------- | |
class Db | |
{ | |
const primary_key = 'INTEGER PRIMARY KEY'; | |
const integer = 'INTEGER'; | |
const string = 'STRING'; | |
private $_db; | |
/** | |
* @param $file The sqlite database file to load | |
* @param $classes The classes to create tables for | |
*/ | |
public function __construct($file, $classes = array()) | |
{ | |
$this->_db = new SQLiteDatabase($file); | |
foreach ($classes as $class) | |
$this->_createTable($class); | |
} | |
public function table($class) | |
{ | |
return new Finder($this->_db, $class); | |
} | |
public function save($obj) | |
{ | |
$class = get_class($obj); | |
$values = array(); | |
foreach (get_class_vars($class) as $field => $_) | |
{ | |
if (preg_match('#(.*)_id$#', $field, $matches)) | |
{ | |
$f = $matches[1]; | |
if (isset($obj->$f) && isset($obj->$f->id)) | |
$obj->$field = $obj->$f->id; | |
} | |
$values[$field] = $obj->$field; | |
} | |
if (!isset($obj->id)) // insert | |
{ | |
foreach ($values as $field => $v) | |
$values[$field] = "'".sqlite_escape_string($v)."'"; | |
$sql = sprintf("INSERT INTO %s (%s) VALUES (%s)", | |
$class, | |
implode(array_keys($values), ', '), | |
implode($values, ", ") | |
); | |
$this->_db->queryExec($sql); | |
$obj->id = $this->_db->lastInsertRowid(); | |
} | |
else // update | |
{ | |
foreach ($values as $field => $v) | |
$values[$field] = sprintf( | |
"%s = '%s'", | |
$field, | |
sqlite_escape_string($obj->$field) | |
); | |
$sql = sprintf('UPDATE %s SET %s WHERE id = %d', | |
$class, | |
implode($values, ', '), | |
$obj->id | |
); | |
$this->_db->queryExec($sql); | |
} | |
} | |
private function _createTable($class) | |
{ | |
$fields = array( | |
'id' => array('type' => self::primary_key), | |
); | |
foreach (get_class_vars($class) as $name => $default) | |
{ | |
if (preg_match('#_id$#', $name)) // foreign keys end in '_id' | |
$type = self::integer; | |
elseif(is_integer($default)) | |
$type = self::integer; | |
else | |
$type = self::string; | |
$fields[$name] = array( | |
'type' => $type, | |
'default' => $default | |
); | |
} | |
$columndefs = array(); | |
foreach ($fields as $name => $field) | |
{ | |
$columndefs []= sprintf('%s %s%s', | |
$name, | |
$field['type'], | |
isset($field['default']) | |
? " DEFAULT '".sqlite_escape_string($field['default'])."'" | |
: '' | |
); | |
} | |
$this->_db->queryExec(sprintf('DROP TABLE %s', $class)); | |
$this->_db->queryExec(sprintf('CREATE TABLE %s (%s)', | |
$class, | |
implode($columndefs, ', ') | |
)); | |
} | |
} | |
class Finder | |
{ | |
private $_db; | |
private $_class; | |
public function __construct($db, $class) | |
{ | |
$this->_db = $db; | |
$this->_class = $class; | |
} | |
public function all() | |
{ | |
$set = $this->_db->arrayQuery( | |
sprintf('SELECT * FROM %s', $this->_class), | |
SQLITE_ASSOC); | |
$result = array(); | |
foreach ($set as $record) | |
$result []= $this->_newModel($record); | |
return $result; | |
} | |
public function findById($id) | |
{ | |
$set = $this->_db->arrayQuery( | |
sprintf('SELECT * FROM %s WHERE id = %d', $this->_class, $id), | |
SQLITE_ASSOC); | |
return count($set) > 0 | |
? $this->_newModel($set[0]) | |
: null; | |
} | |
private function _newModel($record) | |
{ | |
$obj = new $this->_class; | |
foreach ($record as $field => $value) | |
$obj->$field = $value; | |
return $obj; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment