I'm happy to contribute. Thanks for implementing the change so quickly.
Rob Allen wrote:
> Hi,
>
> Thanks very much for the report! I've resolved this on the trunk in
> svn r11113.
>
> Regards,
>
> Rob...
>
>
> On 26 Aug 2008, at 20:25, Daniel Skinner wrote:
>
>> I am getting unexpected behaviour when cloning a Zend_Config object:
>>
>> Example (actual behaviour):
>>
>> $parent = new Zend_Config(array('key' => array('nested' =>
>> 'parent')), true); //allow read-write for merging
>> $newConfig = clone $parent;
>> $newConfig->merge(new Zend_Config(array('key' => array('nested' =>
>> 'override')), true));
>> echo $newConfig->key->nested; // 'override' - as expected
>> echo $parent->key->nested; // 'override' - I was expecting this to be
>> 'parent'
>>
>>
>> Intuitive behaviour (what makes sense):
>>
>> Cloning a Zend_Config object should completely separate the new
>> instance from the original - i.e. there should be no cross-references.
>>
>> $parent = new Zend_Config(array('key' => array('nested' =>
>> 'parent')), true); //allow read-write for merging
>> $newConfig = clone $parent;
>> $newConfig->merge(new Zend_Config(array('key' => array('nested' =>
>> 'override')), true));
>> echo $newConfig->key->nested; // 'override'
>> echo $parent->key->nested; // 'parent'
>>
>>
>> This is occurring because cloning Zend_Config only creates a shallow
>> clone currently.
>>
>> Solution 1: Cast to an array and create a new instance:
>>
>> This can be achieved already and effectively creates a deep clone.
>>
>> $parent = new Zend_Config(array('key' => array('nested' =>
>> 'parent')), true); //allow read-write for merging
>> $newConfig = new Zend_Config($parent->toArray(), true); //cast the
>> parent object to an array and create a new Zend_Config
>> $newConfig->merge(new Zend_Config(array('key' => array('nested' =>
>> 'override')), true));
>> echo $newConfig->key->nested; // 'override' - as expected
>> echo $parent->key->nested; // 'parent' - as expected
>>
>> Solution 2: Fixing Zend_Config to perform a deep clone:
>>
>> /**
>> * Perform a deep clone of this instance to allow side-effect free
>> cloning.
>> * @return void
>> */
>> public function __clone()
>> {
>> $data = array();
>> foreach ($this->_data as $key => $value)
>> {
>> if ($value instanceof Zend_Config)
>> {
>> $data[$key] = clone $value;
>> } else {
>> $data[$key] = $value;
>> }
>> }
>> $this->_data = $data;
>> }
>>
>> Gives:
>>
>> $parent = new Zend_Config(array('key' => array('nested' =>
>> 'parent')), true); //allow read-write for merging
>> $newConfig = clone $parent;
>> $newConfig->merge(new Zend_Config(array('key' => array('nested' =>
>> 'override')), true));
>> echo $newConfig->key->nested; // 'override' - as expected
>> echo $parent->key->nested; // 'parent' - as expected
>>
>> It makes sense to me that this is the expected behaviour when cloning
>> and a deep clone greatly reduces the chance of hard to detect
>> side-effects. Does anybody disagree?
>>
>> A full description of the above can be found at:
>> http://www.daniel-skinner.co.uk/cloning-zend_config-without-side-effects/26/08/2008
>>
>>
>> Test cases and a patch can be found at:
>> http://www.destiny-denied.co.uk/files/ZendConfigClone.zip
>>
>> Kind Regards,
>>
>> *Daniel Skinner*
>> **
>> skinner@destiny-denied.co.uk <mailto:skinner@destiny-denied.co.uk>
>> www.destiny-denied.co.uk <http://www.destiny-denied.co.uk/>
>>
>
没有评论:
发表评论