What is AMF and a bit of history
Action Message Format (AMF) is a compact binary format that is used to serialize ActionScript object graphs. Once serialized an AMF encoded object graph may be used to persist and retrieve the public state of an application across sessions or allow two endpoints to communicate through the exchange of strongly typed data.
AMF was introduced in Flash Player 6 in 2001 and remained unchanged with the introduction of Actionscript 2.0 in Flash Player 7 and with the release of Flash Player 8. This version of AMF is referred to as AMF 0. In Flash Player 9, Action Script 3.0 was introduced along with a new Actionscript Virtual Machine (AVM+) – the new data types and language features made possible by these improvements prompted AMF to be updated. Given the opportunity to release a new version of AMF, several optimizations were also made to the encoding format to remove redundant information from serialized data.
Why AMF?
- AMF is a compact binary format which means few bits to be transferred from the server to the client.
- Using AMF you can call methods from the server as the method would be in you Actionscript code.
In my opinion these two are the main advantages of AMF. There are others advantages as well that you may find important.
Some stats about AMF and its concurrent protocols available can be seen on James Ward’s Census Application (http://www.jamesward.com/census).
What you need
In order to complete this article you need the following things:
- Flash Builder 4 (http://labs.adobe.com/technologies/flashbuilder4) or other IDE with Flex 4 SDK
- AMFPHP (http://www.amfphp.org)
- Local LAMP server (ex: Zend Server Community Edition, XAMPP, WAMP, etc)
Once you have those requirements satisfied we can go on.
At this moment the last version of AMFPHP is 1.9.
Setting up the server side
First of all create a folder in your htdocs or an alias so the web services, will be made available through your installed web server. In that place create a folder called webservices. Copy everything (but not the .htaccess file) that is in amf folder of the AMFPHP archive downloaded from amfphp.org to webservices folder. All your PHP web services will be in webservices/services folder.
Another thing to know is that you may need to put a crossdomain.xml file so the resulting swf file will be able to connect to the web services.
On same level with the webservices folder create _uploads folder (include the first underline). In this folder we will save our uploaded files.
This should be enough for now and we will go further to the next step.
Creating our upload web service
Create a new php file in webservices/services folder called upload.php. This will be the file that will contain our upload class and its methods and all its methods will be available in our flex upload application.
Create a class called upload as the file’s name. This class will have only one method named uploadFiles.
This method takes an object ($fileData) as parameter. This object contains the filename ($fileData["filename"]) and the file content as byte array ($fileData["filedata"]). The method gets those two and saves the file on the server location. It always returns true if it doesn’t crash. In case of a crash that means the file is not saved or an error is in our web service in which case we assume that the file is not saved. See upload.php bellow.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | class upload { // method saves files on the server function uploadFiles($fileData) { // new file path an name // to not overwrite the files we add the microtime before the file name $myFilePath = '../../_uploads/'. preg_replace("/[^0-9]+/","_",microtime()).'_'.$fileData["filename"]; // writing on the disk file_put_contents($myFilePath, $fileData["filedata"]); // returning response - is not used anywhere return true; } } |
Getting into the client side
We will use the Spark components of the Flex 4 SDK. This will ease up a lot the development needed to finalize our application. The states will help us a lot.
Bellow in you can see the content of my MultipleFileUploadUsingAMFPHP project.

Let’s look at the attributes of declaration which contains the paths and settings to reach to our upload web service. Our web service file is called upload.php and can be found in webservices/services/ folder. The url to our web server location is http://localhost/multiplefileupload/.
- endpoint: this must point to gateway.php; in our case the url is http://localhost/multiplefileupload/webservices/gateway.php
- source: this is the filename of the PHP file containing the web service without the “.php” extension; in our case is upload
- destination: is the method from the file and class defined in source; in our case uploadFiles
These three are the attributes to reach the web service. Of course we set up the result and fault event handlers, the id and the showBusyCursor to true to visually show that the application is working.
Now we will define four states that will display different components depending of the state we are in.
- initUpload: the first state that will be displayed at starting

- beforeUploading: this will show the list with the files chosen and some buttons

- inUploadProcess: this will show the progress and will have a button for canceling the process

- uploadFinalized: this will show all the files and the finalized button

Next we will have a panel that will contain a Spark list and a few buttons that will appear according to the state we are in. I will not stop explaining about the new features of Flex 4 SDK and Flash Builder 4 because that is over our scope for now.
A bit of theory – how the upload process work
Now I want to explain how the upload process will work. The whole process is based on a stack idea. Files are uploaded one at a time. After the current file is uploaded or it has failed the next one will take its place and will be processed.
All files that have been chosen for upload are stored in a FileReferenceList object (_refAddFiles). We will iterate through it and we will add each FileReference object to _arrUploadFiles array collection. This array collection is used to display the files in a list and iterate through it to process each file reference object.
The process is started calling startUpload() method. These are the steps taken for each file reference object from _arrUploadFiles array collection:
- We add a complete event to current file reference
_arrUploadFiles[_numCurrentUpload].data.addEventListener( Event.COMPLETE, handleFileLoadedComplete );
- We instruct it to load the file in the application memory
_arrUploadFiles[_numCurrentUpload].data.load();
- When the file is loaded into the memory
handleFileLoadedCompleteis triggered - After the file is loaded into the memory we can read the content of the file
var tmpFileContent:String = fileRef.data.readUTFBytes(fileRef.data.length);
- We call the upload web service
myUploadService.uploadFiles( {filedata:tmpFileContent, filename:fileRef.name} );
- The upload web service which is defined at the beginning with the
tag will trigger one of its event handlers:- result event if it is a success –
myUploadService_resultHandler - fault event if it is a failure –
myUploadService_faultHandler
- result event if it is a success –
- Result event will show in the list if the upload was successful with a green dot and the fault event will show that it has been an error and a failure with a red dot
- The current file number is incremented and the process is started again with
startUpload()method
These are the steps taken for each file contained in a file reference object from _arrUploadFiles array collection.
You should notice that you need to use readUTFBytes method to get the content of the file and send them through the web service. Also you will be able to read the data of a file reference (fileRef.data) only after the files is loaded. This means that load() method must be called and the when the load is complete a complete event is triggered. After this the fileRef.data is available.
The main application code listing can be seen in the source archive. I will not put the whole code here because has lots of lines.
About the custom list item renderer
In order to display a feedback icon for each file we have to create a custom item renderer for our Spark list control. We tell the list that we are using a custom item renderer by specifying the item renderer attribute like bellow:
itemRenderer="com.flexer.CustomListItemRenderer"We won’t go deep into the inner things of the custom component only just to specify that the icon is added at the end like this:
<s:BitmapImage id="icon" source="{data.ico}" verticalCenter="0" right="3" />
The image is taken from data object which is present in each item of the list, and is horizontally aligned at 3 pixels from right. You can see the whole component code bellow.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | <?xml version="1.0" encoding="utf-8"?> <s:ItemRenderer name="CustomListItemRenderer" xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" focusEnabled="false"> <s:states> <s:State name="normal" /> <s:State name="hovered" /> <s:State name="selected" /> <s:State name="normalAndShowsCaret"/> <s:State name="hoveredAndShowsCaret"/> <s:State name="selectedAndShowsCaret"/> </s:states> <fx:Script> <![CDATA[ override public function set labelText(value:String):void { super.labelText = value; labelDisplay.text = labelText; } ]]> </fx:Script> <s:Rect left="0" right="0" top="0" bottom="0"> <s:stroke.normalAndShowsCaret> <s:SolidColorStroke color="{selectionColor}" weight="1"/> </s:stroke.normalAndShowsCaret> <s:stroke.hoveredAndShowsCaret> <s:SolidColorStroke color="{selectionColor}" weight="1"/> </s:stroke.hoveredAndShowsCaret> <s:stroke.selectedAndShowsCaret> <s:SolidColorStroke color="{selectionColor}" weight="1"/> </s:stroke.selectedAndShowsCaret> <s:fill> <s:SolidColor color.normal="{contentBackgroundColor}" color.normalAndShowsCaret="{contentBackgroundColor}" color.hovered="{rollOverColor}" color.hoveredAndShowsCaret="{rollOverColor}" color.selected="{selectionColor}" color.selectedAndShowsCaret="{selectionColor}" /> </s:fill> </s:Rect> <s:SimpleText id="labelDisplay" verticalCenter="0" left="3" right="3" top="6" bottom="4"/> <!-- our mini dot icon showing the state of the file --> <s:BitmapImage id="icon" source="{data.ico}" verticalCenter="0" right="3" /> </s:ItemRenderer> |
This icon is set from the main application where three dot icons are embedded.
[Embed(source="assets/bullet_empty.png")] private var _icoUploadNotStarted:Class; [Embed(source="assets/bullet_green.png")] private var _icoUploadSucces:Class; [Embed(source="assets/bullet_red.png")] private var _icoUploadFailed:Class;
{data.ico} contains the embedded icon.
Conclusion
AMF is a powerful data protocol and can be used for any kind of transfer. It has lots of advantages and is by far the most parsimonious protocol freely available.
Source files are available at the end of this article. Two zip archives and an fxp file exported from my Flash Builder 4 which contains also the php files (I used Flash Builder 4 with PDT and Zend Debugger).
Resources
http://opensource.adobe.com/wiki/download/attachments/1114283/amf3_spec_05_05_08.pdf
http://www.amfphp.org/
http://www.amfphp.org/docs2/index.html
http://framework.zend.com/manual/en/zend.amf.html
http://www.themidnightcoders.com/products/weborb-for-net/overview.html
http://www.themidnightcoders.com/products/weborb-for-rails/overview.html
http://labs.adobe.com/technologies/flashbuilder4/
http://en.wikipedia.org/wiki/Action_Message_Format
http://www.zend.com/en/products/server-ce/
http://www.apachefriends.org/en/xampp.html
http://www.wampserver.com/en/download.php
http://sourceforge.net/project/showfiles.php?group_id=72483&package_id=257933
http://www.jamesward.com/census/
| ||
| ||
|
Tags: ActionScript, AMF, amfphp, PHP
This post was written by Andrei Ionescu
Views: 5371










Hi,bug found!
About multiupload … see that, loading the contents of several files made with .load is not done properly because the content of a file transfer is incomplete (Transfer value of the fileRef.data is incomplete in your case) … Files with extension .jpg (tested by me) or other extensions may give some bugs.
Please fix it
Hello Mike! Thanks for comment. At this point we are using this “component” in some projects with success. We managed to upload images and other types of files and then display them back. No errors so far found by us. So… we ask you kindly, provide more details on the error: what flex SDK you’re using, what error message it triggers, what back-end you use, version of Apache and PHP and other info you may think it is usable to us in order to replicate your bug. We will try to fix it.
Thanks that helped me on starting a Flash Builder image upload with Zend, thanks.
Flash Builder 4 Premium Beta
Flex 4.0 SDK (that comes with it)
AMFPHP
XAMPP 1.7.2
Windows XP
It should work. This is mainly the same configuration I used to develop the solution, except that I used Windows Vista as OS.
When i open this project with flash builder 4 beta,
then i get a error on line 144
What i do wrong?
Thanks!
What the error says? Which version of Flex SDK 4 do you have? Flex SDK 4 is not yet released so changes do appear all the time to some components.