Issues

ZF-7634: multiple empty arrays in response not working correctly anymore

Description

UPDATE: the messy thing here is in Parse\Amf3\Serializer.php, line 323 ff. - do you really need those object references for arrays?

If I return e.g. an object with three empty arrays to Flex (3.0.2) using Zend_Amf, there is only one Array-Object allocated and all the three arrays point to the same Array object. This is of course a very unexpected behaviour.


<?xml version="1.0" encoding="utf-8"?>
www.adobe.com/2006/mxml" layout="absolute">

  

  

package vo
{
  [RemoteClass(alias="vo.ArrayHolder")]
  public class ArrayHolder
  {
    public var _explicitType:String;

    public var array1:Array = new Array();
    public var array2:Array = new Array();
    public var array3:Array = new Array();
  }
}

<?php

if(set_include_path('c:/dev/server/vhosts/library/Zend/1_9_1/') === false){
die('Include path failed');
}

require_once 'Zend/Amf/Server.php';

// simple class to be used for amf server
class Foo
{
  public function getData()
  {
    return new ArrayHolder();
  }
}

// simple vo object
class ArrayHolder
{
    public $_explicitType = 'vo.ArrayHolder';

    public $array1 = array();
    public $array2 = array();
    public $array3 = array();  
}

// Instantiate server
$server = new Zend_Amf_Server();
$server->setClass('Foo');
$server->setClassMap('vo.ArrayHolder', 'ArrayHolder');

echo $server->handle();
?>

This did NOT happen with Version 1.8.3 - it's broken since 1.8.4

Comments

Phew, that's a nasty problem. You're right, that this case didn't happen in version 1.8.3, but only because there was no referencing at all. The problem is that even a === comparison of a array compares the values. So array("foo") === array("foo") would return true even though the arrays should be seperate instances.

Currently I see the following possible solution: We could disable referencing of arrays at all. This would solve this problem at the expense of no array referencing (lets hope nobody relies on that feature... ). Additionally we should add support and promote the use of ArrayObjects. Using ArrayObjects would solve the referencing problems, as they can be correctly compared using ===.

Any opinions?

Cheers Stefan Klug

I would second the ArrayObject suggestion. There are similar changes that I need to re-base and commit so that doctrine 2.0 works with zend amf

Would this be the reason why arrays that equal the same value in php are removed?



class Foo
{
  public function getData()
  {
    return new array(
      array('Test Key 1' => '', 'Test Key 2' = ''),
      array('Test Key 1' => 'Hello', 'Test Key 2' = ''),
      array('Test Key 1' => 'Hello', 'Test Key 2' = ''),
      array('Test Key 1' => 'Hello', 'Test Key 2' = 'World') );
  }
}

This returns a blank array for [2] because it matches perfectly with [1].

@Brad Yes, I've hit the same problem with array values being identical.

My object had a number of array properties, each array had upto 20 integer elements.

When two (or more) arrays had the same elements in the same order, they would be deserialised in Flex with the same memory reference. As the data changed, different arrays would reference each other, causing some very weird behaviour on the client!

I can't believe this bug is still open without any indication of a work around. The is a HUGE issue. Has anyone found a way around this? I am trying to get a product out the door and this one has me hamstrung.

Unlike objects array's in PHP do not have identities. Talking with Stas if we were to cast the array into an arrayobject we would loose all reference anyway. We are just going to remove array references from the serialization process.

Expanding on Wade's comment - basically there's no way in PHP to know one array from another (just as two strings saying "a" are the same, so are two arrays array("a")). Since this is not going to change anytime soon, and such behavior apparently leads to confusion (as in AMF/AS arrays are objects and in PHP they are primitive) I think removing array refs would be the best way to proceed.

fixed in trunk and 1.10 branch - no more refs for arrays

hi,

I have a little problem with your solution for this bug. Since your modifications on 'Serializer' returned array in my project are strange and didn't works (deserialization error).

I think their is a link with cyclic reference : when i have cyclic references and array there is a bug.

Maybe another solution can be found ?

Mikael, could you please have some reproducing code?

P.S. looks like there was a bug in the fix, try the trunk now.

Yeah, thanks the fix works fine :)

I haven't a "simple" reproducing code sorry ...

But the idea is to make a complex object with array/date/etc and manny array and cyclic reference and look at if it is correctly serialized/deserialized.