Rich Rodecker’s blog on flash, flex, actionscript, javascript, and php, with a dash of randomness
Archive for November, 2009
Sending an ArrayCollection – Flex to amfphp
Nov 20th
Here are my tweaks to amfphp for sending an ArrayCollection from Flex to amfphp. May not be the cleanest or most proper but it works. From what I understand, there is an ArrayCollection class included in Zend_AMF, but I haven't looked into that.
I've been sending ArrayCollections from php to Flex for a while, it's pretty simple and info for doing that can be found at Wade Arnold's blog here. The issue going the other direction is that Flex only sends the AC's underlying source array when serializing it for amf. So when amfphp unpacks the data, you're dealing with a normal array.
Obviously, the first thing you'll need is your ArrayCollection class to use (I use the version that extends ArrayObject at the link above), and make sure it is in your include path.
The first tweak to amfphp is to the method AMFBaseDeserializer->mapClass(). In that method, right after the checks looking for CommandMessage and RemotingMessage types, I added a similar check for ArrayCollection:
-
if($typeIdentifier == "flex.messaging.io.ArrayCollection")
-
{
-
return new ArrayCollection();
-
}
Next change is to the AMFDeserializer->readAmf3Object() method. Near the middle of the method, around line 570, there is a check for ArrayCollection, and if found it will call the readAmf3Data() method. I changed it to pass in a value of "true" to the method, you'll see why in a sec:
-
if( $classDefinition['externalizable'] )
-
{
-
if($type == 'flex.messaging.io.ArrayCollection')
-
{
-
$obj = $this->readAmf3Data(true);
-
}
Now just two small tweaks to the readAmf3Data() method. I changed the method signature to add an $isArrayCollection parameter, which just gets forwarded on when calling readAmf3Array. Here's the whole method:
-
function readAmf3Data($isArrayCollection = false)
-
{
-
$type = $this->readByte();
-
-
switch($type)
-
{
-
case 0x00 : return null; //undefined
-
case 0x01 : return null; //null
-
case 0x02 : return false; //boolean false
-
case 0x03 : return true; //boolean true
-
case 0x04 : return $this->readAmf3Int();
-
case 0x05 : return $this->readDouble();
-
case 0x06 : return $this->readAmf3String();
-
case 0x07 : return $this->readAmf3XmlString();
-
case 0x08 : return $this->readAmf3Date();
-
case 0x09 : return $this->readAmf3Array($isArrayCollection);
-
case 0x0A : return $this->readAmf3Object();
-
case 0x0B : return $this->readAmf3XmlString();
-
case 0x0C : return $this->readAmf3ByteArray();
-
}
-
}
Now just another two small tweaks to the readAmf3Array method. As with the readAmf3Data() method, we add the $isArrayCollection parameter. Within the body of the method, I just check if that param is true when creating the $hashtable variable, and if it is, use an ArrayCollection instead of a regular array:
-
function readAmf3Array($isArrayCollection = false)
-
{
-
$handle = $this->readAmf3Int();
-
$inline = (($handle & 1) != 0 ); $handle = $handle>> 1;
-
-
if( $inline )
-
{
-
-
$this->storedObjects[] = & $hashtable;
-
$key = $this->readAmf3String();
-
while( $key != "" )
-
{
-
$value = $this->readAmf3Data();
-
$hashtable[$key] = $value;
-
$key = $this->readAmf3String();
-
}
-
-
for($i = 0; $i <$handle; $i++)
-
{
-
//Grab the type for each element.
-
$value = $this->readAmf3Data();
-
$hashtable[$i] = $value;
-
}
-
return $hashtable;
-
}
-
else
-
{
-
return $this->storedObjects[$handle];
-
}
-
}
That's it. Now I can send the an AC to the server, serialize it, unserialize it and send it back to Flex with no issues. The one thing that may an issue is if one of the items within an AC is also another AC...haven't checked out if that works yet.
Frameworks 2.0
Nov 2nd
Subititled: "The Rise of 'Burger King' frameworks....'have it your way'".
I am loving the new trend I'm seeing in a lot of the frameworks (both client- and server-side) I've been checking out lately. What I'm seeing is a move away from the monolithic, "do it my way or suffer trying to work around it" approach, towards more architectures that provide a more generalized, "less is more" approach, even to the point that some of the functionality and/or features of the "do-it-all" frameworks are being broken out into smaller, specialized bits that allow the developer to pick and choose between whichever approach best suits their style.
To me, the main benefit of the new trend is readily apparent: just as different individuals would write the same story different ways, the same goes for writing code. For one framework to dictate too much influence over too many aspects of an application, or even worse to make it difficult to extend or adapt to suit your needs, provides too much lock-in and and can hinder more than it's trying to help.
On the flash/flex side, frameworks like RobotLegs , Cairngorm 3, Gaia, and even libraries like CasaLib provide example of this (ok, Gaia probably goes a little further as far as initial structure, but once you start developing it stays out of your way). On the backend, for php you have things such as Konstrukt, a "URI-to-controller-mapping" (i.e., REST) framework which handles "routing based on logic rather than rules", and the Outlet and phpDataMapper ORM frameworks.
One thing about the above mentioned frameworks is that most, if not all, can be used in conjunction with each other (like so). If you don't like the way one part does it's job, you can more than likey swap out that part with a similar one without affecting the other parts of an application, provided you we good with encapsulation and keeping things pretty cleanly separated. This is not an insignificant side effect of the "less-is-more" approach, it's the central theme. It's having it your way.