Passing typed ActionScript objects to Flex using PHP and a message queue

Last week I wrote up a few blog posts (here, here and here) about creating a Flex based dashboard that utilized message queues to pass data.  It was a really fun example to write but there was one thing I did not get to implement.  What I wanted to do was use the sales notification mechanism to pass PHP objects to Flex using the message queue.  But I could not get the unserialization mechanism to work and so I had to settle for passing a simple message that a sale had been made.

However, because you can pass typed objects back and forth between PHP and ActionScript over HTTP using Zend_Amf_Server I figured that there MUST be a way of doing it automatically.  The first thing I did was create a valueObject class called Boogers (I descend into adolescence while trying new things) and called it in ActionScript so I could see the bytes that were created.  The class Boogers had a property called “nutso” (again, adolescence) to which I assigned the value of “what?”.  The code looked something like this

1
2
3
4
5
6
7
8
9
10
var bgrs : Boogers = new Boogers;
bgrs.nutso = "what?";
var baobj : ByteArray = new ByteArray;
baobj.writeObject(bgrs);
var ints2 : String = new String();
baobj.position = 0;
for (var i : uint = 0; i < baobj.length; i++) {
  var b : uint = baobj.readByte();
  ints2 +=  b + " " ;
}

This resulted in the bytes

1
10 19 41 118 97 108 117 101 79 98 106 101 99 116 115 46 66 111 111 103 101 114 115 11 110 117 116 115 111 6 11 119 104 97 116 63

Then I wrote some PHP code that created a PHP object called valueObjects\Boogers, serialize it and then output the bytes so I could compare it with the ActionScript output.  Note  that the class name follows the same namespace definition as the ActionScript class.  I wanted to have direct 1:1 relationships between PHP and ActionScript.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
namespace valueObjects;
$b = new Boogers();
$b->nutso = "what?";
 
$stream = new \Zend_Amf_Parse_OutputStream();
$ser = new \Zend_Amf_Parse_Amf3_Serializer($stream);
$ser->writeObject($b);
$output = (string)$stream->getStream();
 
$a = '';
for ($i = 0; $i < strlen($output); $i++) {
  $a .= ord($output[$i]) . ' ';
}
echo $a;

 

The end result were the bytes

1
19 41 118 97 108 117 101 79 98 106 101 99 116 115 92 66 111 111 103 101 114 115 11 110 117 116 115 111 6 11 119 104 97 116 63

It was missing char 10.  But I found out that you needed to do a newline character for AMF to work properly, so I just prepended it to my output

1
$output = "\n" . (string)$stream->getStream();

So the next thing I wanted to do was send it to a message queue where ActionScript could read it using Stomp.

1
2
3
$stomp = new \Zend_Queue_Adapter_Activemq(array());
$stomp->setQueue(new \Zend_Queue(array('name' => '/queue/data')));
$stomp->send($output);

I ran the code and it sent the message to the message queue.  On the ActionScript side I set up a Stomp handler like I did in my webinar demo and was able to receive the message.  Reading the message is done by creating a method that responds to a message event generated by the Stomp library.

1
2
3
public function processMessage(msg : MessageEvent) : void {
  var obj : * = msg.message.body.readObject();
}

But the problem I ran into was that the typing of obj was always a generic Object.  So I proceeded to try and figure out how to get a properly typed object passed into ActionScript.  I tried several different methods but the craziest was that I tried was trying to implement a sort of null RPC call that would call com.adobe.serializers.utility.TypeUtility.convertResultHandler to do the unserializing.  But no matter what, none of the methods I tried would yield a properly type ActionScript object.  So I looked at the text output of the PHP output.

1
)valueObjects\Boogersnutsowhat?

Oh.

Notice anything?

Yep.  PHP namespace separator.  What did ActionScript use?  Yep, a period.

To solve it I added one line to the ActionScript processMessage() method.

1
2
3
4
public function processMessage(msg : MessageEvent) : void {
  flash.net.registerClassAlias("valueObjects\\Boogers", valueObjects.Boogers);
  var obj : * = msg.message.body.readObject();
}

Now when it is run I get a properly typed ActionScript object that I can work on in my Flex application.

3 comments
rawcookies
rawcookies

I enjoy reading your blog. You've helped tremendously as I've been exploring Zend + Flex 4.5... Anyway, you're not the only one that reverts to being 12 when you're just coding to yourself, don't worry. ;)

Roznama
Roznama

I want to know that what is the way to decode ( dezend ) coded files in zend. I purchased phpcow software but owners of phpcow.com ran away. I want to decode a file named: form.class.php.
Kindly guide me if you know about it.
Thanks
[email protected]

Kevin Schroeder
Kevin Schroeder

Are you looking to run encoded files or decode them? If the former you can use Zend Guard and Zend Guard Loader. If you are looking on how to break the obfuscation you are asking the wrong person

Trackbacks

  1. […] on in his Flex and PHP series Kevin Schroeder has a new post to his blog today looking at how to send typed ActionScript objects to Flex so he could pass PHP objects and their structure directly back to the waiting frontend. […]

Post Navigation

Web Analytics