2

What is the best way to construct an UPDATE statement using associative arrays in PHP?

For example, say I have a function like so:

/**
 * For update queries
 * 
 * @param string $tableName Name of the table we're wanting to update.
 * @param array $values Associative array of columns / values to update. e.g. array('name' => 'John', 'age' => 29)
 * @param array $conditions Associative array of conditions. e.g. array('user_id' => 1) equates to "WHERE user_id = 1"
 */
 public function update($tableName, $values, $conditions = array()){
      //Construct SQL
 }

So far, I've been able to construct simple UPDATE statements such as:

UPDATE `myTableName` SET `name` = :name, `age` = :age WHERE `user_id` = :user_id

Now I'm left wondering: What is the best way to approach constructing the WHERE clause? Are there similar implementations in other libraries and code bases that I can look into? For example: How do I approach the construction of WHERE clauses that have OR and AND and IN() etc?

UPDATE example SET col = :val WHERE user_id = :user_id AND (age = :age OR name = :name)
Wayne Whitty
  • 19,513
  • 7
  • 44
  • 66
  • This might by helpful: [**Can I bind an array to an in condition**](http://stackoverflow.com/questions/920353/php-pdo-can-i-bind-an-array-to-an-in-condition) – Mahmoud Gamal Nov 07 '12 at 11:47

2 Answers2

1
public function update($tableName, $values, $conditions = array()) {
    if (empty($values)) {
        throw new Exception('Nothing to update');
    }
    $valueStrings = array();
    foreach ($values as $name => $value) {
        $valueStrings[] = $name . ' = :' . $name;
    }
    $conditionStrings = array();
    foreach ($conditions as $column => $value) {
        $conditionString = $column;
        $conditionString .= is_array($value)
            ? ('IN ("' . implode('","', $value) . '")')
            : (' = "' . $value . '"')
        ;
        $conditionStrings[] = $conditionString;
    }
    $sql = 'UPDATE ' . $tableName
        . ' SET ' . implode(', ', $valueStrings)
        . ' WHERE ' . implode(' AND ', $conditionStrings)
    ;
    // execute query
}

But actually you should use an ORM for that:

Doctrine 2: Update query with query builder

Community
  • 1
  • 1
Sergey Eremin
  • 10,994
  • 2
  • 38
  • 44
0

I think a simple solution would be to use implode() using 'AND' as the separator:

$columnCArrayValues = array(1, 2, 3, 4);
$conditions = array(
    'column_a = :column_a',
    'column_b <> :column_b',
    'column_c IN (' . implode(',', $columnCArrayValues) . ')'
);

// ..

$where = '(' implode(') AND (', $conditions) . ')';
// result: (column_a = :column_a) AND (column_b <> :column_b) 
// AND (column_c IN (1,2,3,4))

Alternatively, the Zend Framework has a really nice Db component in both versions of the framework.

Yes Barry
  • 9,514
  • 5
  • 50
  • 69