HiveBrain v1.2.0
Get Started
← Back to all entries
patternphpMinor

PHP PDO Database Abstraction Layer

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
layerphpabstractiondatabasepdo

Problem

I'd like to get some feedback on a PHP Database Abstraction Layer I've created. It's a little long, but there really wasn't a way to just post part of it. Here is the base DBObject class for MySQL:

```
db = $db;
$this->prefix = $prefix;
$this->tablePrefix = ($prefix) ? $prefix.$table : $table;
$this->table = $table;
foreach($fields as $key) {
$this->fields[$key] = NULL;
}
return $this;
}

/**
* @param string $key - The table column name to retrieve
* @return mixed - The value of the key, if the key exists, FALSE otherwise
*/
function __get($key){
return (array_key_exists($key, $this->valueStorage)) ? $this->valueStorage[$key] : FALSE;
}

/**
* @param string $key - The table column name to be assigned a value
* @param $value - The value to assign to the key
* @return boolean - TRUE if the key exists, FALSE otherwise
*/
function __set($key, $value){
if (array_key_exists($key, $this->fields)){
$this->valueStorage[$key] = $value;
return TRUE;
} else {
return FALSE;
}
}

/**
* Adds a value to be bound on query execution
* @param mixed $value - The value(s) to be bound
* @return string - The named value placeholder
*/
protected function addBoundValue($value){
if (is_array($value)){
$valueNames = array();
foreach ($value as $val){
$this->numBoundValues += 1;
$valueName = ':'.$this->numBoundValues;
$this->boundValues[$valueName] = $val;
$this->patterns[] = '#(\s'.$valueName.'[\s]?)#';
$valueNames[] = $valueName;
}
return $valueNames;
} else {
$this->numBoundValues += 1;
$valueName = ':'.$this->numBoundValues;
$this->boundValues[$valueName] = $value;

Solution

Ok, it's a huge work, so, I'll try to do this by iteration, adding then when I've a little time.

I'll start with the form.

Iteration 1

Readability:

Thereafter is the code with some improvements about it's readability.

I've limited the width to 78 columns, use 2 spaces soft tabs instead of 4, add a line feed (and indentation) before {, etc.

IMHO, 2 spaces soft tab make easier the target of 78 columns, so I prefer it to the conventional 4 spaces soft tab.

I like to target 78 columns because the target is generally 80. But some repositories with very strict commitment rules can block you when they considers a lf like a character, or a crlf like two.

As you can see, it also bring the advantage to not have an horizontal slider here.

One important thing: I've deleted the ?> at the end of the file, for the same reasons as those of the Zend Framework PHP File Formatting convention:


For files that contain only PHP code, the closing tag ("?>") is never permitted. It is not required by PHP, and omitting it´ prevents the accidental injection of trailing white space into the response.

It's just my vision of a more readable code, and it will help me for further iteration if I found some time for it...

```
db = $db;
$this->prefix = $prefix;
$this->tablePrefix = ($prefix) ? $prefix.$table : $table;
$this->table = $table;
foreach($fields as $key)
{
$this->fields[$key] = NULL;
}
return $this;
}

/**
* @param string $key - The table column name to retrieve
* @return mixed - The value of the key, if the key exists, FALSE otherwise
*/
function __get($key)
{
return (array_key_exists($key, $this->valueStorage)) ?
$this->valueStorage[$key] : FALSE;
}

/**
* @param string $key - The table column name to be assigned a value
* @param $value - The value to assign to the key
* @return boolean - TRUE if the key exists, FALSE otherwise
*/
function __set($key, $value){
if (array_key_exists($key, $this->fields))
{
$this->valueStorage[$key] = $value;
return TRUE;
}
else
{
return FALSE;
}
}

/**
* Adds a value to be bound on query execution
* @param mixed $value - The value(s) to be bound
* @return string - The named value placeholder
*/
protected function addBoundValue($value)
{
if (is_array($value))
{
$valueNames = array();
foreach ($value as $val)
{
$this->numBoundValues += 1;
$valueName = ':'.$this->numBoundValues;
$this->boundValues[$valueName] = $val;
$this->patterns[] = '#(\s'.$valueName.'[\s]?)#';
$valueNames[] = $valueName;
}
return $valueNames;
}
else
{
$this->numBoundValues += 1;
$valueName = ':'.$this->numBoundValues;
$this->boundValues[$valueName] = $value;
$this->patterns[] = '#(\s'.$valueName.'[\s]?)#';
return $valueName;
}
}

/**
* Adds space separators to each bound value
* @return array - The spaced bound values
*/
protected function getSpacedBoundValues()
{
$boundValues = ' '.implode(' | ', $this->boundValues).' ';
return explode('|', $boundValues);
}

/**
* @param string $alias - Sets the alias for the main table. Optional for
* query build.
* @return The object for chaining
*/
public function alias($alias)
{
$this->alias = $alias;
return $this;
}

/**
* @var array $selectList - Used for determining which database fields
* should be selected. Fields from joins may be included, but must include
* either the full table name or alias as a prefix.
* @return The object for chaining
*/
public function selectList(array $selectList)
{
foreach($selectList as $value)
{
$this->selectList[] = $value;
}
return $this;
}

/**
* @param string $quotable - Escapes an input variable for use in an SQL
* query. Returns the escaped string. Optional for query build.
* @return The escaped input
*/
public function quote($quotable)
{
return $this->db->quote($quotable);
}

/**
* Joins will be added to the join array and processed in their array order
* and use the ON syntax rather than USING. Optional for query build.
* @param string $joinType - The type of join to be performed. Acceptable
* values are 'left', 'right', 'inner', and 'full'
* @param string $table - The name of the table to be joined with the
* current table
* @param string $column - The column(s) to be compared to the value
* @param string $operator - The operator to be used in the comparison
* @param string $value - The value to which $column is compared
* @param string $tableAlias - optional - The alias of the joined table. If
* not set, alias defaults to the table name
* @return The object for chaining
*/
public function addJoin(
$joinType,
$table,
$column,
$operator,
$value,
$tab

Code Snippets

<?php
/**
 * Description: The DBObject class is the generic database object. It is not
 * to be used directly, but extended by additional classes, each
 * corresponding to a database table. This particular DBObject is for use
 * with a MySQL PDO driver.
 * Dependencies: A database connection script that uses the MySQL PDO
 * extension
 * Requirements: PHP 5.2 or higher
 */
class DBObject {

  protected $alias = NULL;
  protected $boundValues = array();
  protected $db;
  protected $fields = array();
  protected $groupBy = NULL;
  protected $having = NULL;
  protected $joins = NULL;    
  protected $limit = NULL;
  protected $numBoundValues = 0;
  protected $offset = NULL;
  protected $orderBy = NULL;
  protected $patterns = array();
  protected $prefix;  
  protected $selectList = NULL;
  protected $table;
  protected $tablePrefix = NULL;
  protected $unions = array();
  protected $valueStorage = array();
  protected $where = NULL;

  /**
   * @param object $db - The PDO database connection object
   * @param string $table - The name of the table
   * @param array $fields - The names of each field in the table
   * @param string $schema - The schema
   * @param $prefix - optional - A prefix for the table
   * @return The object for chaining 
   */
  function __construct(
    PDO $db,
    $table,
    array $fields,
    $schema,
    $prefix = NULL)
  {
    $this->db = $db;
    $this->prefix = $prefix;
    $this->tablePrefix = ($prefix) ? $prefix.$table : $table;
    $this->table = $table;      
    foreach($fields as $key)
    {
      $this->fields[$key] = NULL;
    }
    return $this;
  }

  /**
   * @param string $key - The table column name to retrieve 
   * @return mixed - The value of the key, if the key exists, FALSE otherwise
   */
  function __get($key)
  {
    return (array_key_exists($key, $this->valueStorage)) ?
        $this->valueStorage[$key] : FALSE;       
  }

  /**
   * @param string $key - The table column name to be assigned a value
   * @param $value - The value to assign to the key
   * @return boolean - TRUE if the key exists, FALSE otherwise
   */
  function __set($key, $value){
    if (array_key_exists($key, $this->fields))
    {
      $this->valueStorage[$key] = $value;
      return TRUE;
    }
    else
    {
      return FALSE;
    }
  }

  /**
   * Adds a value to be bound on query execution
   * @param mixed $value - The value(s) to be bound
   * @return string - The named value placeholder
   */
  protected function addBoundValue($value)
  {
    if (is_array($value))
    {
      $valueNames = array();
      foreach ($value as $val)
      {
        $this->numBoundValues += 1;
        $valueName = ':'.$this->numBoundValues;
        $this->boundValues[$valueName] = $val;
        $this->patterns[] = '#(\s'.$valueName.'[\s]?)#';
        $valueNames[] = $valueName;
      }
      return $valueNames;         
    }
    else
    {
      $this->numBoundValues += 1;
      $valueName = ':'.$this->numBoundValues;
      $this->bound

Context

StackExchange Code Review Q#5071, answer score: 6

Revisions (0)

No revisions yet.