Skip to content

Instantly share code, notes, and snippets.

@mmattax
Created February 15, 2013 20:32
Show Gist options
  • Save mmattax/4963321 to your computer and use it in GitHub Desktop.
Save mmattax/4963321 to your computer and use it in GitHub Desktop.
PDO based port of PEAR's DB_DataObject
<?php
namespace Framework;
use \PDO;
use \Exception;
abstract class Model {
private static $_host;
private static $_username;
private static $_password;
private static $_database;
private static $_pdo;
private static $_schema = array();
private $_stmt;
private $_select;
private $_join = array();
private $_where = array();
private $_group_by;
public function __construct() {
$this->_select = array($this->getTable() . '.*');
}
public static function configure($host, $username, $password, $database) {
self::$_host = $host;
self::$_username = $username;
self::$_password = $password;
self::$_database = $database;
// Load the schmea file
$config = CONFIG_DIR . '/' . basename(self::$_database) . '.schema.php';
if (!is_file($config)) {
throw new \Exception("Failed to load schema file: $config");
} else {
require_once $config;
}
}
private function getDSN() {
return 'mysql:host=' . self::$_host . ';dbname=' . self::$_database;
}
protected function getPDO() {
if (empty(self::$_pdo)) {
self::$_pdo = new PDO($this->getDSN(), self::$_username, self::$_password);
//self::$_pdo->beginTransaction();
}
return self::$_pdo;
}
public function getTable() {
$path = explode('\\', get_class($this));
return strtolower(end($path));
}
public function find($params = array()) {
$this->_stmt = $this->getPDO()->prepare($this->buildSelect());
foreach($this->getColumnMap() as $key => $value) {
$params[":$key"] = $value;
}
$res = $this->_stmt->execute($params);
return $this->_stmt->rowCount();
}
public function fetch() {
$row = $this->_stmt->fetch(PDO::FETCH_ASSOC);
if ($row !== false) {
$this->setFrom($row);
}
return $row;
//return $row === false ? false : true;
}
public function setFrom(array $source) {
$cols = self::$_schema[$this->getTable()];
foreach($source as $key => $value) {
if (isset($cols[$key])) {
$this->$key = $value;
}
}
}
public function selectAdd($clause = null) {
if ($clause === null) {
$this->_select = array();
} else {
$this->_select[] = $clause;
}
}
public function joinAdd($join) {
$this->_join[] = $join;
}
public function whereAdd($clause, $conjunction = 'AND') {
$this->_where[] = array($clause, $conjunction);
}
public function groupBy($group_by) {
$this->_group_by = $group_by;
}
public function get($a, $b = null) {
$col = empty($b) ? 'id' : $a;
$val = empty($b) ? $a : $b;
$table = $this->getTable();
$this->_stmt = $this->getPDO()->prepare("SELECT * from $table WHERE $col = :$col");
$this->_stmt->bindParam(":$col", $val, PDO::PARAM_INT);
$this->_stmt->execute();
return $this->fetch();
}
public function delete() {
$table = $this->getTable();
$this->_stmt = $this->getPDO()->prepare("DELETE FROM $table WHERE id = :id");
$this->_stmt->bindParam('id', $this->id, PDO::PARAM_INT);
return $this->_stmt->execute();
}
public function insert() {
$map = $this->getColumnMap();
if (isset($map['id'])) {
unset($map['id']);
}
$cols = array_keys($map);
$vals = array_values($map);
$params = array_map(function($value) { return ":$value"; }, $cols);
$table = $this->getTable();
$sql = "INSERT INTO $table (" . join(',', $cols) . ') VALUES (' . join(',', $params) . ')';
$this->_stmt = $this->getPDO()->prepare($sql);
for ($i = 0; $i < count($params); $i++) {
$this->_stmt->bindValue($params[$i], $vals[$i]);
}
$result = $this->_stmt->execute();
if ($result) {
$this->id = $this->getPDO()->lastInsertId();
}
return $result;
}
public function update() {
$map = $this->getColumnMap();
$values = array();
$sql = 'UPDATE ' . $this->getTable() . ' SET ';
foreach($this->getColumnMap() as $col => $value) {
if ($col == 'id') { continue; }
$sep = empty($values) ? '' : ',';
$sql .= "$sep $col = :$col";
$values[":$col"] = $value;
}
$sql .= " WHERE ID = :id";
$values[':id'] = $this->id;
$this->_stmt = $this->getPDO()->prepare($sql);
$result = $this->_stmt->execute($values);
return $result;
}
public function buildSelect() {
$table = $this->getTable();
$sql = 'SELECT ' . implode(',', $this->_select);
$sql .= ' FROM ' . $this->getTable();
foreach($this->_join as $join) {
$sql .= " $join";
}
/**
* Build where where clauses.
*/
$where = array();
$map = $this->getColumnMap();
foreach($map as $col => $value) {
$where[] = array("$col = :$col", 'AND');
}
$where = array_merge($this->_where, $where);
if (!empty($where)) {
$sql .= ' WHERE';
for($i = 0; $i < count($where); $i++) {
list($clause, $conjunction) = $where[$i];
$sql .= $i == 0 ? " $clause" : " $conjunction $clause";
}
}
if (!empty($this->_group_by)) {
$sql .= " GROUP BY {$this->_group_by}";
}
return $sql;
}
public function commit() {
$this->getPDO()->commit();
}
public function lastError() {
return $this->_stmt->errorInfo();
}
private function getColumnMap() {
$map = array();
$cols = self::$_schema[$this->getTable()];
foreach($cols as $col => $v) {
if (isset($this->$col)) {
$map[$col] = $this->$col;
}
}
return $map;
}
public function __clone() {
if (!empty($this->_stmt)) {
$this->_stmt = null;
}
}
}
@samin
Copy link

samin commented Sep 21, 2013

Nice port. Any chance you can post a simple example of how to use? Specially the schema file.

@geoidesic
Copy link

Ditto

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment