ZF-2243: Different behavior between Zend_Db_Table::createRow($data) and Zend_Db_Table_Row::setFromArray(array $data)


Zend_Db_Table::createRow($data) is filtering data that are not part of the column table while Zend_Db_Table_Row::setFromArray($data) is not.


$defaults = array_combine($this->_cols, array_fill(0, count($this->_cols), null));
$keys = array_flip($this->_cols);
$data = array_intersect_key($data, $keys);
$data = array_merge($defaults, $data);


foreach ($data as $columnName => $value) {
    $this->$columnName = $value;

I found filtering a nice feature especially when you pass all the data coming from a Form as an argument.


Glad to see this has been reported; I was just about to post it myself.

I think Zend_Form has made this issue quite a bit more important. My Zend_Form objects frequently include submit button elements, which get returned back as part of the result of Zend_Form::getValues(). This makes it impossible to use that returned array as the parameter of setFromArray().

Maybe, however, instead of changing the behavior entirely, we should make this "filtering" optional via a new argument for setFromArray(). The logic would go like this:

[code] public function setFromArray(array $data, $strict = true) { if ($strict === false) { // filter all non-column elements out of the array } // assign column values as at present } [/code]

This would keep things backwards-compatible.

Please categorize/fix as needed.

The codebase has changed a little since the initial report, but this issue remains. I've created this patch that moves array_intersect_key($data, $defaults); out of Zend_Db_Table_Abstract::createRow() and into Zend_Db_Table_Row_Abstract::setFromArray() . setFromArray() is already called by createRow() so moving this line should make the two function consistent.

This patch works in a few of my own test cases.

+1 vote. Stephen's suggestion (moving the logic into Zend_Db_Table_Row) works for me too.

Additionally, setFromArray()'s description is a bit misleading: ??Sets all data in the row from an array.?? It does not set all data (i.e. set unspecified columns to null), but only the given columns.

Fixed in SVN12245

Changing issues in preparation for the 1.7.0 release.