Skip to content

Instantly share code, notes, and snippets.

@martinbean
Last active July 9, 2018 08:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save martinbean/8219442 to your computer and use it in GitHub Desktop.
Save martinbean/8219442 to your computer and use it in GitHub Desktop.
Basic ORM sketch that uses value objects, data mappers that persists data to a data source, and adapters for data sources.
<?php
abstract class Adapter
{
protected $config;
protected $connection;
public function __construct($config)
{
$this->config = $config;
$this->connect();
}
public function __destruct()
{
$this->disconnect();
}
abstract public function connect();
abstract public function disconnect();
abstract public function insert($table, Entity $model);
abstract public function update($table, Entity $model);
abstract public function delete($table, Entity $model);
}
<?php
abstract class DataMapper
{
protected $adapter;
public function __construct(Adapter $adapter)
{
$this->adapter = $adapter;
}
public function save(Entity $model)
{
if (isset($model->id)) {
return $this->adapter->update($this->table, $model);
} else {
return $this->adapter->insert($this->table, $model);
}
}
public function delete(Entity $model)
{
return $this->adapter->delete($this->table, $model);
}
}
<?php
abstract class Entity
{
protected $dirtyFields = array();
abstract public function getFields();
public function getDirtyFields()
{
return $this->dirtyFields;
}
public function __set($key, $value)
{
$this->dirtyFields[$key] = $this->$key = $value;
}
}
<?php
require('Entity.php');
require('User.php');
require('Adapter.php');
require('MySqlAdapter.php');
require('DataMapper.php');
require('UserMapper.php');
$user = new User();
$user->first_name = 'Martin';
$user->last_name = 'Bean';
$config = array(
'host' => 'localhost',
'username' => 'root',
'password' => '',
'dbname' => 'test_db'
);
$adapter = new MySqlAdapter($config);
$mapper = new UserMapper($adapter);
echo '<p>Creating user:</p>';
print '<pre>';
var_dump($mapper->save($user));
print '</pre>';
echo '<p>Deleting user:</p>';
print '<pre>';
var_dump($mapper->delete($user));
print '</pre>';
exit;
<?php
class MySqlAdapter extends Adapter
{
public function connect()
{
$dsn = sprintf('mysql:host=%s;dbname=%s', $this->config['host'], $this->config['dbname']);
$driver_options = array(
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8'
);
$this->connection = new PDO($dsn, $this->config['username'], $this->config['password'], $driver_options);
$this->connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
public function disconnect()
{
$this->connection = null;
}
public function insert($table, Entity $model)
{
$columns = implode(',', array_keys($model->getDirtyFields()));
$values = rtrim(str_repeat('?,', count($model->getDirtyFields())), ',');
$sql = "INSERT INTO `$table` ($columns) VALUES ($values)";
$statement = $this->connection->prepare($sql);
if (true === $statement->execute(array_values($model->getDirtyFields()))) {
$model->id = (int) $this->connection->lastInsertId();
return true;
}
return false;
}
public function update($table, Entity $model)
{
$id = (int) $model->id;
$data = array();
foreach ($model->getDirtyFields() as $column => $value) {
$data[] = sprintf('`%s` = ?', $column);
}
$data = implode(',', $data);
$sql = "UPDATE `$table` SET $data WHERE `id` = ? LIMIT 1";
$statement = $this->connection->prepare($sql);
$values = array_values($model->getDirtyFields());
$values[] = $id;
return $statement->execute($values);
}
public function delete($table, Entity $model)
{
$sql = "DELETE FROM `$table` WHERE `id` = ? LIMIT 1";
$statement = $this->connection->prepare($sql);
if (true === $statement->execute(array($model->id))) {
$model->id = null;
return true;
}
return false;
}
}
<?php
class User extends Entity
{
public function getFields()
{
return array(
'id',
'first_name',
'last_name'
);
}
}
<?php
class UserMapper extends DataMapper
{
protected $table = 'users';
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment