Pragmatism in the real world


(Putting this here, mainly so that I can reference it!)

There’s a bug in Zend_Db_Adapter_Pdo_Abstract::insert(). I posted in to the mailing list and it’s available here in the archives.

In short, if you use the PDO drivers and have table field names with underscores in them, then you need to delete the insert() function within the class Zend_Db_Adapter_Pdo_Abstract.

Details are:

From: Rob Allen
Date: Tue, 28 Mar 2006 16:19:06 +0100


I’m pretty sure that Zend_Db_Adapter_Pdo_Abstract::insert() (latest svn)
is fundamentally broken.

The code is:

public function insert($table, $bind)
// col names come from the array keys
$cols = array_keys($bind);

// build the statement
$sql = “INSERT INTO $table ”
. ‘(‘ . implode(‘, ‘, $cols) . ‘) ‘
. ‘VALUES (:’ . str_replace(“_”, “”, implode(‘, :’, $cols))
. ‘)’;

// execute the statement and return the number of affected rows
$result = $this->query($sql, $bind);
return $result->rowCount();

The problem is the str_replace() as it changes the expected array key in
the $bind array.

Consider calling the function like this :
< ?php $row['username'] = 'rob'; $row['first_name'] = 'Rob'; $row['last_name'] = 'Allen'; $db->insert(‘users’, $row);

$sql becomes:
INSERT INTO users (username, first_name, last_name)
VALUES (:username, :firstname, :lastname)

$bind is:
array(4) {
[“username”] => string(5) “rob”
[“first_name”] => string(3) “Rob”
[“last_name”] => string(5) “Allen”

And Pdo throws an exception as it’s looking for $bind[“firstname”], not
the correct $bind[“first_name”]…

(Incidentally, the version with underscore is the name of the field in
the table.)

I’ve tested with MS SQL Server and MySQL and get the same result.

To fix, I removed the insert() function completely from
Zend_Db_Adapter_Pdo_Abstract so that it falls back to the inherited
Zend_Db_Adapter_Abstract::insert() which works fine :)

Have I missed something obvious?