Issues

ZF-6459: The Array-Union-Operator ignores values of existing keys

Description

The union operator found in


    public function setOptions(array $options)
// ..
        $this->_options = $this->_options + $options;
        return $this;
    }

ignores subkeys, if the key at toplevel already exists.

$a = array ('config'=>array('key1'=>'$a1','key2'=>'$a2'));
$b = array ('config'=>array('key1'=>'$b1','key3'=>'$b2'));
var_dump ($a + $b);

array(1) {
  ["config"]=>
  array(2) {
    ["key1"]=>
    string(3) "$a1"
    ["key2"]=>
    string(3) "$a2"
  }
}

The 'key3' is missing. This behaviour is described in the PHP-Manual [1]

'array_merge' does the same in the other direction, it overwrite the value of a existing key, instead of ignoring it. 'array_merge_recursive' will merge two scalar to one array and so it will destroy the config structure. Zend_Config has a method merge() which act like expected, but its not used here. So the method 'setOptions()' has to convert one config into a 'Zend_Config', merge and deconvert into an array again, or it must implement its own merge-Method.

Version is trunk 15243

[1]http://de.php.net/manual/en/… {quote} The + operator appends elements of remaining keys from the right handed array to the left handed, whereas duplicated keys are NOT overwritten. ```

Comments

Resolved in trunk and 1.8 release branch

As i mentioned 'array_merge_recursive' will lead to another problem

$a = array (
  'config'=>array(
    'db'=>array(
      'dbname'=>'name')));
$b = array (
  'config'=>array(
    'db'=>array(
      'dbname'=>'thisConfigUseAnotherName')));

var_dump (array_merge_recursive($a,$b));

output

array(1) {
  ["config"]=>
  array(1) {
    ["db"]=>
    array(1) {
      ["dbname"]=>
      array(2) {
        [0]=>
        string(4) "name"
        [1]=>
        string(22) "thisConfigUseOtherName"
      }
    }
  }
}

Now "dbname" is not a string anymore and will likely fail.

Another example, which returns a very iteresting result.

class Test_Bootstrap extends Zend_Application_Module_Bootstrap {
    protected function _initOptionDump () {
        $this->setOptions($this->getOptions());
        var_dump ($this->getOptions());
    }
}

All scalar values are doubled.

array(1) { ["somekey"]=> array(2) { [0]=> string(9) "somevalue" [1]=> string(9) "somevalue" } }


Expected: No change.

array(1) { ["somekey"]=> string(9) "somevalue" } ```

Better merging algorithm added in trunk and 1.8 release branch.