Skip to content

Instantly share code, notes, and snippets.

@jmas
Last active August 29, 2015 14:08
Show Gist options
  • Save jmas/ad8cecc8685ccb7c7ea9 to your computer and use it in GitHub Desktop.
Save jmas/ad8cecc8685ccb7c7ea9 to your computer and use it in GitHub Desktop.
<?php
namespace Db;
class Db {
private $connection;
public function __construct(\PDO $connection) {
$connection->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
$this->connection = $connection;
}
public function create(DbModel $model) {
if (! $model->isNew()) {
throw new DbException("Can't create NOT NEW model.");
}
$data = $model->getData();
$columns = [];
$params = [];
$defered = [];
foreach ($data as $attr => $value) {
if (is_array($value)) {
foreach ($value as $valueModel) {
$this->save($valueModel);
}
} else if (is_object($value)) {
$defered[] = $value;
} else {
$columns[] = $attr;
$placeholder = ':' . $attr;
$params[$placeholder] = $value;
$placeholders[] = $placeholder;
}
}
$sql = 'INSERT INTO ' . $model->getStoreName() . '(' . implode(', ', $columns) . ') VALUES(' . implode(', ', $placeholders) . ')';
$sth = $this->connection->prepare($sql);
if ($sth->execute($params) === false) {
throw new DbException("Can't create model.");
}
$model->id = $this->connection->lastInsertId();
if (count($defered) > 0) {
foreach ($defered as $deferedModel) {
$this->save($deferedModel);
}
}
return true;
}
public function find($modelName, $sql='', array $params=array()) {
$sql = 'SELECT tbl.* FROM ' . $modelName::getStoreName() . ' AS tbl ' . $sql;
$sth = $this->connection->prepare($sql);
$sth->setFetchMode(\PDO::FETCH_CLASS, $modelName);
if ($sth->execute($params) === false) {
return null;
}
return $sth->fetchAll();
}
public function findOne($modelName, $sql='', array $params=array()) {
$sql = 'SELECT tbl.* FROM ' . $modelName::getStoreName() . ' AS tbl ' . $sql;
$sth = $this->connection->prepare($sql);
$sth->setFetchMode(\PDO::FETCH_CLASS, $modelName);
if ($sth->execute($params) === false) {
return null;
}
return $sth->fetch();
}
public function update(DbModel $model) {
if ($model->isNew()) {
throw new DbException("Can't update NEW model.");
}
$data = $model->getData();
$pairs = [];
$params = [];
$defered = [];
foreach ($data as $attr => $value) {
if ($attr === 'id') {
continue;
}
if (is_array($value)) {
foreach ($value as $valueModel) {
$this->save($valueModel);
}
} else if (is_object($value)) {
$defered[] = $value;
} else {
$placeholder = ':' . $attr;
$params[$placeholder] = $value;
$pairs[] = $attr . '=:' . $attr;
}
}
$sql = 'UPDATE ' . $model->getStoreName() . ' SET ' . implode(', ', $pairs) . ' WHERE id=:id LIMIT 1';
$params[':id'] = $model->id;
$sth = $this->connection->prepare($sql);
if ($sth->execute($params) === false) {
throw new DbException("Can't update model.");
}
if (count($defered) > 0) {
foreach ($defered as $deferedModel) {
$this->save($deferedModel);
}
}
return true;
}
public function save(DbModel $model) {
if ($model->isNew()) {
$this->create($model);
} else {
$this->update($model);
}
}
public function remove(DbModel $model) {
if ($model->isNew()) {
throw new Exception("Can't remove NEW model.");
}
$sql = 'DELETE FROM ' . $model->getStoreName() . ' WHERE id=:id';
$sth = $this->connection->prepare($sql);
$sth->bindValue(':id', $model->id, \PDO::PARAM_INT);
if ($sth->execute() === false) {
throw new DbException("Can't remove model.");
}
unset($model->id);
return true;
}
}
class DbException extends \Exception { }
<?php
namespace Db;
abstract class DbModel {
public $id;
abstract public static function getStoreName();
public function getAttrs() {
return array_keys(get_class_vars(get_class($this)));
}
public function getData() {
$attrs = $this->getAttrs();
$data = [];
foreach ($attrs as $attr) {
if (isset($this->{$attr})) {
$data[$attr] = $this->{$attr};
} else {
$data[$attr] = '';
}
}
return $data;
}
public function setData(array $data) {
$attrs = $this->getAttrs();
foreach ($attrs as $attr) {
if (isset($data[$attr])) {
$this->{$attr} = $data[$attr];
}
}
}
public function isNew() {
return empty($this->id);
}
}
<?php
require_once('Db/Db.php');
require_once('Db/DbModel.php');
require_once('models/Order.php');
require_once('models/Product.php');
$connection = new PDO('mysql:dbname=dbtest;host=localhost', 'root', 'root');
$db = new \Db\Db($connection);
$product = new \models\Product;
$product->setData([
'newAttr' => 'my attr',
'name' => 'Another name',
]);
$order = new \models\Order;
$order->customer_name = 'Ivan';
$order->addProduct($product);
$db->save($order);
<?php
namespace models;
class Order extends \Db\DbModel {
public $customer_name;
public $is_completed;
public $products = array();
public function isCompleted() {
return $this->is_completed === '1' ? true: false;
}
public function addProduct(Product $model) {
$this->products[] = $model;
$model->order = $this;
}
public static function getStoreName() {
return 'user_order';
}
}
<?php
namespace models;
class Product extends \Db\DbModel {
public $name;
public $price;
public $image;
public static function getStoreName() {
return 'product';
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment