ZF-5570: Flex ArrayCollection only mapping from PHP to Flex not the other way around

Description

Hello, I've tried everything to pass an ArrayCollection from Flex to the PHP side without success.

Step 1 created ArrayCollection vo in php flex/messaging/io/ArrayCollection.php <?php class ArrayCollection{ //public $_explicitType = "mx.collections.ArrayCollection"; var $_explicitType = "flex.messaging.io.ArrayCollection";

var $source = array();

function ArrayCollection()
{
    $this->source = array();
}

}

Step 2 included the ArrayCollection.php file and set the class map in the amf.php gateway $server->setClassMap('flex.messaging.io.ArrayCollection', 'ArrayCollection');

Step 3 created the service class.

Step 4 To test mapping bidirectionally I made a service method called returnIt which takes a object and returns it.

Step 5 create flex app to invoke service method.

I have checked inside the returnIt method with Zend Logger that infact the ArrayCollection was being mapping correctly. But then something happens and the script aborts and the ArrayCollection is never returned to Flex..

I've mapped my other custom classes successfully, just not for the Flex ArrayCollection.

Here are the relevant debugging messages..

From Flex Debugger (using AMF3 NetConnection): AMFPHP.onNetStatus NetConnection.Call.BadVersion

From Flex Debugger (using RemoteObject): [FaultEvent fault=[RPC Fault faultString="Channel disconnected" faultCode="Client.Error.DeliveryInDoubt" faultDetail="Channel disconnected before an acknowledgement was received"] messageId="43D17271-865C-EC1E-E1CB-E1DC89C39167" type="fault" bubbles=false cancelable=true eventPhase=2]

From my PHP error_log:

[16-Jan-2009 18:40:52] PHP Warning: Invalid argument supplied for foreach() in /Users/panupan/Zend/workspaces/DefaultWorkspace/bbahh/library/Zend/Amf/Parse/Amf3/Deserializer.php on line 388

The returned error message (as seen from ServiceCapture) when using the Flex RemoteObject and Zend AMF sever set to production false:

extendedData (null): null faultCode (Number): 0 faultDetail (String): #0 /Users/panupan/Zend/workspaces/DefaultWorkspace/bbahh/library/Zend/Amf/Server.php(291): Zend_Amf_Server->_loadCommandMessage(Object(Zend_Amf_Value_Messaging_CommandMessage))

1 /Users/panupan/Zend/workspaces/DefaultWorkspace/bbahh/library/Zend/Amf/Server.php(384): Zend_Amf_Server->_handle(Object(Zend_Amf_Request_Http))

2 /Users/panupan/Zend/workspaces/DefaultWorkspace/bbahh/public/amf.php(28): Zend_Amf_Server->handle()

3 {main}

faultString (String): CommandMessage::12 not implemented rootCause (null): null correlationId (String): 5519AEBD-8877-6AB3-5C38-E1DC89BB3AF1 clientId (String): 393BE507-F7CD-ECC8-C360-0000301BD7EA destination (null): null messageId (String): 47D34E84-7B65-E269-4A28-00006AA3EDD4 timestamp (String): 123214997300 timeToLive (Number): 0 headers (Object):

body (null): null

Comments

PHP side source code.

Flex side source code

I've came upon the very same issue using ZF 1.7.0 and 1.7.7.

I've just found a workaround for this issue.

Here is the corresponding code:

start: library/Zend/Amf/Parse/Amf3/Deserializer.php:388

// Add properties back to the return object. foreach($properties as $key=>$value) { if($key) { $returnObject->$key = $value; } }

end: library/Zend/Amf/Parse/Amf3/Deserializer.php:388

It seems at some point $properties is left to a value of NULL, thus foreach() fails. To workaround the issue you can simply set one line before the foreach() like that:

if (!is_array($properties)) $properties = array();

Another solutions might be to use something similar:

// Check for any properties defined if (is_array($properties)) { // Add properties back to the return object. foreach($properties as $key=>$value) { if($key) { $returnObject->$key = $value; } } }

There is no notable difference in using any of the methods.

Please note that this is a workaround! An official fix for the issue still has to be released.

Best regards,

Nikola Petkanski PHP Developer http://www.e-man.co.uk/

Hi,

The $properties array is not defined for externalizable objects such as {ArrayCollection} and {ObjectProxy}. Look at switch/case starting on 335.

My solution was to insert (on row 346): $properties = array();

Fixed in r24385 using suggested workaround (seem fine to cast $properties to an array if not already in that form).