AMFPHP $_explicitType understood

I've been using AMFPHP for a while now. Up until recently I have been using dumb objects and simple NetConnections to pass things back and forth between Flex and PHP. Over time, the objects I was passing back and forth got more complex and strong typing of the objects looked like a better way to go, but there was a lot of code that would have to change in my libraries to make it happen so I kept putting it off. ...

Recently, a couple projects I was working on had me take a look at the Cairngorm micro-architecture to help speed up (re)development. After finding some great tutorials on getting starting with Cairngorm I decided it fit the bill for my needs.

Cairngorm would allow me to refactor some basic frameworks I was going to use for these and future projects while allowing for easier customization and modification. The architecture makes use of RemoteObjects to pass data back and forth instead of raw NetConnection objects. Between RemoteObjects and the ValueObject design (anti?)pattern I felt it was time to work on strong typing my variables, specifically the ones traveling from PHP to Flex.

Two important parts to making this work are the RemoteClass meta tag in Flex and the $_explicitType variable in PHP. The RemoteClass meta tag lets your application know the fully qualified name of an alias class on your server. It works the same for AMFPHP, ColdFusion, Java and others. It should look something like this:

package path.to.asClasses
{
  [RemoteClass(alias="path.to.MyAliasClass")]
  public class MyASClass
  {
    public var id:uint;
    public var name:String;
  }
}

My first thought about the $_explicit type variable was that it would be the inverse of the RemoteClass meta tag and point to the actionscript class. With that in mind I wrote something like this:

<?php

class MyAliasClass
{
  var $_explicitType = "path.to.asClasses.MyASClass";

  var $id;
  var $name;

  public function MyAliasClass( ){}
}

?>

Unfortunately, the data that got passed back to Flex was typed as an ObjectProxy object instead of as a MyASClass object as intended. I did all the basic troubleshooting. I made sure everything was spelled the same. I tried to do searches online and got mostly references passing VOs from Flex to PHP and/or Patrick Mineaults opinion that doing so is wasteful. Not many of the search results talked about going from PHP to Flex and those that did just said you needed to use $_explicitType. Unfortunately I can't find the posting again, but I came across a short post that said they had a similar problem and got it to work by changing $_explicitType to a string representing the fully qualified path of the PHP class. He didn't know why it worked, and neither did I, but I tried the following code and class typing occured as expected:

<?php

class MyAliasClass
{
  var $_explicitType = "path.to.MyAliasClass";

  var $id;
  var $name;

  public function MyAliasClass( ){}
}

?>

As usual, I got it working and now I needed to understand why. Not only why did it work but why did they use the term explicit type? It turns out the use of the RemoteClass meta tag takes care of mapping in both directions. When the Flex app encounters an alias object from remoting ( in this case path.to.MyAliasClass ) it knows what AS class is equivalent. As for explicitType, you just have to think about the full notation ( MyAliasClass::_explicitType ). In object oriented languages an object's properties should represent it's state. In this case it represents the explicit type of MyAliasClass. This is required due to the constraints of PHP. PHP is not case sensitive when it comes to class names. Also, PHP doesn't actually use classpaths. When you include a file there is no reference to the directory structure passed along with it. Though one could be derived, it isn't built into AMFPHP natively.

--
Some other good news related to AMFPHP. While looking for answers I see that AMFPHP now has a new lead who is working on getting version 2.0 out and ready to go. Supposedly he already got authentication working again. His name is Wade Arnold from T8Design. This is good news as it once again assured the future of the AMFPHP project.

----
Daryl "Deacon" Ducharme is currently Director of Application Development for the Interactive Agency Provis Media Group, LLC which helps organizations enhance identity, connect with customers and increase productivity.

Headers already sent?!

In my experience, the most annoying and hard to track down bugs are the simplest things. Sometimes you misspell a word. Sometimes you accidentally check for a boolean true when you should be checking for false. The worst are misplaced spaces, tabs, carriage returns and other whitespace that makes an bug hard to track down. ...

What I was trying to do was simple. I just needed to add a class file into my PHP code for an application I am working on. After I added the class file like so:

require_once( "../../../fileDirectory/my_necessary_class.php" );

I started to get errors.

Because this was a Flex application using AMFPHP, my first error popped up in the service browser.

TypeError: Error #1009: Cannot access a property or method of a null object reference.	at RawAmfService/internal::readData()
	at flash.events::EventDispatcher/flash.events:EventDispatcher::dispatchEventFunction()
	at flash.events::EventDispatcher/dispatchEvent()
	at flash.net::URLLoader/flash.net:URLLoader::onComplete()
	at [io]

Ack! Near useless errors, at least it looked like the AMF reading abilities of the flash player were being confounded by whatever they were getting sent. From what eventually came up in the Service Browser's results window I had a bit more information to work with:

(Object)#0
  message = "faultCode:INVALID_AMF_MESSAGE faultString:'Invalid AMF message' faultDetail:'

Warning: Cannot modify header information - headers already sent by (output started at /a/long/path/to/a/site/root/fileDirectory/my_necessary_class.php:464) in /a/long/path/to/a/site/root/amfphp/core/shared/exception/php4Exception.php on line 38
'"
  name = "Error"
  rootCause = (null)

Eureka! proper AMF file headers were not able to be sent because, headers were already sent before the call to send AMF headers.

My deductive process to find the error went like this:
1. Perhaps the file isn't where I think it is. I change the require_once code a little and get an error that tells me that I had it right before.
2. Look for any obvious errors in the class - it works in other programs so I wasn't counting on this to work out for me. It didn't.
3. So that I could edit the class without breaking other applications I made a copy in the same directory and to see if somehow tha was affecting the headers. Still a no go.
4. Finally I decided to comment the entire file out and try it. Success! Slowly I uncommented function by function. In the end I uncommented every function and it still worked.

Not being one to fix a bug without understanding it I did a comparison of the original file and my new version. The only difference was my new version did not have an extra line after the closing ?>. When I saw that I remembered something I read about the PHP include functions( include, include_once, require and require_once ).

When a file is included, parsing drops out of PHP mode and into HTML mode at the beginning of the target file, and resumes again at the end. For this reason, any code inside the target file which should be executed as PHP code must be enclosed within valid PHP start and end tags.

What was happening was that the last line of that file was being sent as HTML, so PHP sent regular HTML headers when the file was included and before the AMF headers were sent. So if you are trying to output non-HTML and your run into a problem where the wrong headers are being sent, check to see if you have some extra whitespace outside of your <?php ?> tags.

----
Daryl "Deacon" Ducharme is currently Director of Application Development for the Interactive Agency Provis Media Group, LLC which helps organizations enhance identity, connect with customers and increase productivity.

Uncertain Futures

As much as we hate it, our futures are uncertain. We do our best to figure out ways to keep what we know safe and secure. However some times that security gets shaken and sometimes it gets shattered.

From time to time my boss and I talk about open source software. He doesn't really like to look at it as a solution too often. There are many reasons he states, but one that often comes up is product stability. Will it be supported? Is it still actively developed? Good questions, and unfortunately it looks like some security I envisioned in the open source world is getting shaky around a product I just started using. ...

A little while ago I started a new project for work. In fact it was the first project I got the okay to do in Flex/AS3. While I was at it I thought I would take a look at using AMFPHP remoting for it as well, since it is a very server data centric application framework. I used it and loved it. No more serializing complex data structures into XML. No more deserializing and spending so much time creating specialized parsing engines. There was a small learning curve but otherwise, very easy to integrate and use.

Then I read this article on the 5 et demi blog. It seems Patrick Mineault is retiring from programming and the AMFPHP project. Luckily, he will be finishing AMFPHP 2.0 before he is done. Good luck to him on his new endeavors but what will become of AMFPHP? As far as I can see there is nobody in line to take over the project. Should I do it? I really don't believe that would be beneficial to the community at this juncture in my life. He does make a good point about not getting stuck to one software, and I can easily go back to what I was doing before, but this is a good project.

Here are some answers to my questions, at least for myself. First off, AMFPHP will work for current versions of PHP and the Actionscript Virtual Machine. So no big worries there. It is open source, so any bugs that I do run into after the 2.0 release can still be fixed. If the project does die off, it should still find some usefulness for quite some time. Once it is no longer a viable option, there will obviously be better solutions for me to use anyway. In fact, Flash/Flex/Actionscript may not even be the tool I am using so why sweat it. However, it is a good project and I would like to see it live on and evolve into something greater.

Do you know anyone who could take over this project? Can you? Are you willing to help in some way? If you answered yes to any of these questions it's probably a good idea to contact Patrick at 5 et demi and let him know. I'm sure he would be more than happy to toss you the keys to the project.

----
Daryl "Deacon" Ducharme is currently "Code Czar" for the Interactive Agency Provis Media Group, LLC which helps organizations enhance identity, connect with customers and increase productivity.