Skip to content

Instantly share code, notes, and snippets.

@martinbean
Created January 30, 2014 14:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save martinbean/8709547 to your computer and use it in GitHub Desktop.
Save martinbean/8709547 to your computer and use it in GitHub Desktop.
A rough, basic query object implementation
<?php
class Condition
{
protected $field;
protected $comparator;
protected $value;
const EQUALS = '=';
const GREATER_THAN = '>';
const LESS_THAN = '<';
const GREATER_THAN_OR_EQUAL_TO = '>=';
const LESS_THAN_OR_EQUAL_TO = '<=';
public function __construct($field, $comparator, $value)
{
$this->field = $field;
$this->comparator = $comparator;
$this->value = $value;
}
public static function equals($field, $value)
{
return new Condition($field, '=', $value);
}
public static function greaterThan($field, $value)
{
return new Condition($field, '>', $value);
}
public static function lessThan($field, $value)
{
return new Condition($field, '<', $value);
}
public static function greaterThanOrEqualTo($field, $value)
{
return new Condition($field, '>=', $value);
}
public static function lessThanOrEqualTo($field, $value)
{
return new Condition($field, '<=', $value);
}
public function __toString()
{
switch ($this->comparator) {
case self::EQUALS:
return sprintf('%s = %s', $this->field, $this->value);
break;
case self::GREATER_THAN:
return sprintf('%s > %s', $this->field, $this->value);
break;
case self::LESS_THAN:
return sprintf('%s < %s', $this->field, $this->value);
break;
case self::GREATER_THAN_OR_EQUAL_TO:
return sprintf('%s >= %s', $this->field, $this->value);
break;
case self::LESS_THAN_OR_EQUAL_TO:
return sprintf('%s <= %s', $this->field, $this->value);
break;
default:
throw new InvalidArgumentException(sprintf('Invalid comparator: %s', $this->comparator));
}
}
}
<?php
require('src/Query.php');
require('src/Condition.php');
$adapter = new PDO('mysql:host=localhost;dbname=test_db', 'root', '', array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8'));
$query = new Query($adapter);
$query->select('id', 'name');
$query->from('test_tbl');
$query->where(Condition::greaterThan('id', 5));
$query->orderBy('name', 'ASC');
$query->limit(10);
$query->offset(1);
$results = $query->fetchAll();
print '<pre>' . htmlspecialchars(print_r($results, true)); exit;
<?php
class Query
{
protected $adapter;
protected $type;
protected $fields = array();
protected $table;
protected $where = array();
protected $order = array();
protected $limit;
protected $offset;
protected $statement;
const SELECT = 'select';
const INSERT = 'insert';
const UPDATE = 'update';
const DELETE = 'delete';
public function __construct(PDO $adapter)
{
$this->adapter = $adapter;
}
public function select()
{
$fields = func_get_args();
$this->type = self::SELECT;
foreach ($fields as $field) {
if (is_scalar($field)) {
$this->fields[] = $field;
} else {
throw new InvalidArgumentException(sprintf('Expected scalar value; %s passed instead', gettype($field)));
}
}
}
public function selectDistinct($field)
{
$field[] = sprintf('DISTINCT %s', $field);
}
public function selectAverage($field)
{
$field[] = sprintf('AVG(%s)', $field);
}
public function selectCount($field)
{
$field[] = sprintf('COUNT(%s)', $field);
}
public function selectMax($field)
{
$fields[] = sprintf('MAX(%s)', $field);
}
public function selectMin($field)
{
$fields[] = sprintf('MIN(%s)', $field);
}
public function selectSum($field)
{
$fields[] = sprintf('SUM(%s)', $field);
}
public function from($table)
{
$this->table = $table;
}
public function where(Condition $condition)
{
$this->where[] = $condition;
}
public function orderBy($field, $direction)
{
$direction = strtoupper($direction);
if ($direction == 'ASC' || $direction == 'DESC') {
$this->order[$field] = $direction;
} else {
throw new InvalidArgumentException(sprintf('Invalid order direction specified: %s', $direction));
}
}
public function limit($limit)
{
if (!is_numeric($limit)) {
throw new InvalidArgumentException('Limit should be a numerical value');
}
$this->limit = (int)$limit;
}
public function offset($offset)
{
if (!is_numeric($offset)) {
throw new InvalidArgumentException('Offset should be a numerical value');
}
$this->offset = (int)$offset;
}
protected function execute()
{
$this->statement = $this->adapter->prepare($this);
$this->statement->execute();
}
public function fetchAll()
{
$this->execute();
$results = array();
while ($row = $this->statement->fetchAll(PDO::FETCH_ASSOC)) {
$results[] = $row;
}
return $results;
}
public function __toString()
{
switch ($this->type) {
case self::SELECT:
$sql = 'SELECT ';
$sql.= implode(', ', $this->fields);
$sql.= ' FROM ' . $this->table;
if (!empty($this->where)) {
$sql.= ' WHERE ' . implode(' AND ', $this->where);
}
if (!empty($this->order)) {
$sql.= ' ORDER BY ';
$order = '';
foreach ($this->order as $field => $direction) {
$order[] = sprintf('%s %s', $field, $direction);
}
$sql.= implode(',', $order);
}
if (!empty($this->limit)) {
$sql.= sprintf(' LIMIT %s', $this->limit);
}
if (!empty($this->offset)) {
$sql.= sprintf(' OFFSET %s', $this->offset);
}
break;
case self::INSERT:
// TODO: build INSERT statement
break;
case self::INSERT:
// TODO: build UPDATE statement
break;
case self::DELETE:
// TODO: build DELETE statement
break;
}
return $sql;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment