| Register
Friday, May 09, 2008   

AMFPHP: Flash <–> PHP interaction

Created By  Tibor Gyorgy Ballai, at  6/11/2006 - 19 comments.

Any Flash developer who has worked on RIAs (Rich Internet Applications) that needed to interact with PHP knows that this isn’t a simple process at all. Although AMFPHP has been around for quite a while, I will start with a simple introduction and then build from there in coming articles.


Before AMFPHP was available the only two options to send and load data from PHP were LoadVars and XML. If you wanted to query a database and return a complex data structure then your best option would have been XML since it was more suitable for structuring the data. But even with XML in order to retrieve data from a database you needed the logic that would do the actual query then additional logic that would parse the results of the query and build the xml string and finally parsing the xml on the client side in ActionScript to retrieve the data from the XML object.


You may ask: "So, what’s wrong with that?".


In a complex application debugging and maintenance will become pretty difficult if you have hundreds of PHP scripts just for the sole purpose of generating the xml strings, and several scripts on the client side to parse those xml objects and retrieve the necessary data. Not to mention the waste of time and resources needed to build something on the server side that you will automatically deconstruct on the client side.


Why is AMFPHP better?


Imagine writing a function on the server that queries the database and returns an array i.e.


 return mysql_fetch_array(mysql_query("select * from table LIMIT 1")); 

Then simply calling that function from ActionScript and getting an array with the results. No need to build XML strings on the server, no need to decode/parse data on the client side. If you send a number you will receive a number, if you send a string you will receive a string, if you send an array you will receive an array, even array keys are preserved. The data transfer is done in the binary AMF format rather then text format. The gateway and the ActionScript classes translate the data into this neutral format, thus allowing language specific data to be exchanged transparently.


If you would like to know more about how AMFPHP works you can check out their official website at http://www.amfphp.org/


Hello World!


Let's get started by setting up a classic "Hello World!" example:


First of all in order to use AMFPHP you will need to install the Adobe Remoting components for Action Script 2. You can download them from: http://www.adobe.com/products/flashremoting/downloads/components/


After installing the remoting components you will need to install AMFPHP. You can download the latest version from: http://www.amfphp.org/


In order to install AMFPHP you will need a web server with PHP installed. You can choose between Apache, IIS, or other web servers. For the sake of simplicity I will assume that you are a Windows XP user and will install IIS.

Installing IIS on Windows XP:

Open your Control Panel:

Click on "Add or Remove Programs";

Click on "Add/Remove Windows Components";

Check the box beside "Internet Information Services (IIS)"

Press the "Next" button.

Your system will ask you to insert the windows installation CD, Insert the CD; press the "OK" button.

And finally after the installation completes press the "Finish" button.

Installing PHP on Windows:

You can download PHP 5.1.4 as a windows installer from:

http://php.net/get/php-5.1.4-installer.exe/from/a/mirror

This installer will automatically configure your IIS web server; you just need to follow the steps in the installer.

When the installer prompts you for the installation type select "Standard".

You can choose any directory to install PHP.

You will need to select the version of IIS you installed; if you are a windows XP user your IIS version is 5.1.

If you followed the steps correctly you should have a working web server and PHP installed on your PC.

Let’s set up a test to see if the installations were successful:

Create a new file with the name test.php, open it and add the following code:

 <? phpInfo(); ?> 

Save the file and copy it in your web server’s public directory (C:\Inetpub\wwwroot). Then open your favorite Browser and type the following in the address bar: http://localhost/test.php (or click this link)

If the output you get is similar to the following snapshot your web server and PHP are working properly.

Installing AMFPHP:

Once your web server and PHP are functional you can start installing AMFPHP. Unzip the contents of the zip archive in your web server’s public web directory (C:\Inetpub\wwwroot)

If you check the contents of the amfphp folder you will notice a gatway.php file this is the gateway all AMFPHP requests will be routed through. You will also notice a services folder this is where your services will reside. A service is a PHP Class; each service will contain the methods you will be calling from ActionScript. If you keep the structure of the AMFPHP package unchanged no further configuration will be needed.

I have created a Connector class that should make the use of AMFPHP easier. By using the connector even developers who didn’t use AS2 before will be able to use AMFPHP. The Connector can also be used with Java OPENAMF (which I will cover in another article), or JRun4.

You can download the Connector class here: http://www.actionscript.com/files/tibi/Connector.zip

Once you downloaded the zip file, create a new flash document and unzip the contents of the Connector.zip archive in the same folder where you flash document is. Add the following code to the first frame of your flash document:



import com.actionscript.amfphp.Connector;

var gatewayUrl:String="http://localhost/amfphp/gateway.php";
var con:Connector=new Connector(gatewayUrl);
con._PendingCall=con.setService('HelloWorld').say("Hello World from AMFPHP!");
con.setResponders(this.onResult, this.onFault, this);

function onResult(data){
trace(data.result);
}
function onFault(status){
trace("error "+status.__fault);
}

The gatewayURL is the path to your gateway. I used localhost in this case but you can also use an IP address or domain. The parameter of the con.setService('HelloWorld').say("Hello World from AMFPHP!"); function is the name of the service in which your method is implemented; HelloWorld is the service we will create.

After setting up the service you will call your method, in this case the method name is say con.setService('HelloWorld').say("Hello World from AMFPHP!");

The say method we will implement pings back a message to flash, in this case the message is "Hello World from AMFPHP!"

The onResult and onFault functions are the responders upon a successful AMFPHP call the onResult function will be called upon failure the onFault function will be called. You need to set the responder function in the Connector, in this example the responders are set by con.setResponders(this.onResult, this.onFault, this);

You can give your responder functions any name as long as you pass those names correctly to the connector by using the setResponders function. Now that the client side logic is set up lets create our service.

Create a new PHP file HelloWorld.php and put the following code in it:



<?php
class HelloWorld
{
function HelloWorld()
{
$this->methodTable = array
(
"say" => array
(
"access" => "remote",
"description" => "Pings back a message"
)
);
}

function say($sMessage)
{
return 'You said: ' . $sMessage;
}
}?>

Note that the class name must be the same as the file name.

If you aren’t familiar with OOP the first function in the php file is the constructor the name of this function must be the same as the class name.

The constructor contains a methodTable array, all methods contained by the class must be defined here.

And finally our say function, as you can see it simply returns the received parameter.

Save your php file and copy it in the amfphp/services folder on your web server. (C:\Inetpub\wwwroot\amfphp\services)

Now compile your Flash document, you should get a trace output with the following content: "You said: Hello World from AMFPHP!" (You should get the output instantly if the web server is running locally or in a couple of seconds if you are using a web host.)

I hope this article was comprehensive and it helped in giving you a basic idea of what AMFPHP is capable of. In my next article I will explain how to create a simple text chat application with AMFPHP without the use of a database by using persistent PHP sessions.




You can download a zip file containing all the files used in this "Hello World!" application here: http://www.actionscript.com/files/tibi/files.zip



If you have any questions please feel free to post them in the comments.


Recent Articles by  Tibor Gyorgy Ballai

Need Professional Help For Your ActionScript Project?
ActionScript.com Consulting Services provide top quality professional ActionScript consulting to businesses around the globe. If you have a professional project in need to world-class talent, tell us about your project by requesting a quote today.

Reader Comments

  1. benz dobler  Replied:
    ( 6/20/2006 At 6:57 AM)

    cool article! thanx
    can`t wait for the openamf one as i havent`t found one yet.

  2. Edu Salgado  Replied:
    ( 7/4/2006 At 11:18 PM)

    Would be possible to have any security problems with SWF decompilers?

    Oh... sorry about my english ;)

  3. James Reilly  Replied:
    ( 7/9/2006 At 6:50 PM)

    I get the following error message any ideas?

    **Error** Scene=Scene 1, layer=Layer 1, frame=1:Line 3: The class or interface 'com.actionscript.amfphp.Connector' could not be loaded.
    var con:Connector=new Connector(gatewayUrl);

    Total ActionScript Errors: 1 Reported Errors: 1

  4. Valentin Backofen  Replied:
    ( 7/10/2006 At 3:57 PM)

    looks like you have not installed the required classes...

    I am currently planning to set up a server that will be supplying banners hosted on a multitude of servers with data. The data will be requested millions of times per week. So though the data is minimal, with these ammount of requests the bandwidth will suffer, as will the server processor. I have completed the following comparrisson.

    I requested the same data from the server in two seperate formats:
    First in Text Only comma-seperated variables and second a AMFPHP service. Though the second data was compiled noticably faster as my SWF had to spend no time parsing it, the Text Only variables where at only a quarter of the size of the remoting objects.

    Does anyone else have any experience on this. Or any interesting case studies as to sendAndLoad vs Remoting as to serverload and performance. Thanks. V.

  5. Satori Canton  Replied:
    ( 7/10/2006 At 4:41 PM)

    With minimal data (such as one dimensional data that can be simply comma delimited), then a straight sendAndLoad returning the delimited data is going to be the smallest option. Parsing the data is as simple as splitting the string into an array, so the load on the client is pretty minimal.

    The advantage of AMF is when you are trying to pass complex data in XML. AMF will usually result in better bandwidth performance over XML, and it's much easier to work with in Flash, as the results are native Flash objects.

  6. Valentin Backofen  Replied:
    ( 7/10/2006 At 5:02 PM)

    Yeah, I did notice the difference in parsing speed. It was really the byte size that disturbed me. It did after all turn out to be 5-fold of the flat text only array. So I am assuming that we'll be going with sendAndLoad. Merci beaucoup for your feedback. Keep up your excellent work!

  7. Tibor Gyorgy Ballai  Replied:
    ( 7/10/2006 At 6:41 PM)

    Edu Salgado,

    Swf decompilers are an obvious issue; basically any code you have written can be decompiled easily.

    There are several ways of securing your AMFPHP services; I am considering an article on this topic.

  8. Tibor Gyorgy Ballai  Replied:
    ( 7/10/2006 At 7:02 PM)

    James,

    Valentin was right; you must be missing the Connector class.

    Try downloading http://www.actionscript.com/files/tibi/Connector.zip
    and unzip it's contents in the same folder where your fla file is.

  9. Alberto Paroni  Replied:
    ( 7/17/2006 At 6:15 AM)

    I used amfphp with Apache but now I have to use it with IIS and inexplicably not work for me...

    If I use trace function like:

    trace(con.setResponders(this.onResult, this.onFault, this)); Flash return undefined. The package is under the the service folder, the gatewayUrl is placed in the good directory...I can't understand the problem.

  10. Chris Charlton  Replied:
    ( 8/9/2006 At 12:48 AM)

    I would suggest making a [PHP] connection class for the services to share.

  11. dev  Replied:
    ( 9/9/2006 At 3:52 AM)

    This article happened to be on the front page so I figure i would read it as I am a huge amfphp fan. I have been using it since early 2003 and it has always been a great success. however I am very confused on this statement "Any Flash developer who has worked on RIAs (Rich Internet Applications) that needed to interact with PHP knows that this isn’t a simple process at all."

    Integrating amfphp is probably one of the easiest ways to make flash actulay usefull. Remoting calls to amf works pretty much identical to remoting with coldfusion.

    amf is a very simple to use class based system. Your remoting class can be as simple as less than a dozen lines of code to return a nice sql recordset.

    Upon my travels of amf through the web, I came across this website a few years back: http://www.sephiroth.it/
    There are some VERY good examples on how to use amf, which may perplex most people who claim to be web developers.

    The installation for amf on a windows based machine is great, but it realy holds no real use. The only reason I would ever think of for using a windows web server is for coldfusion, or some weird windows flex something or another. For years, any LAMP web hosting package can get you what you need without all the fuss of NEEDING to have a windows iis server. php its a beautiful language and works on pretty much anything.

    Tibor, thank you for making a tutorial on getting rid of xml files. I think somewhere in the process of the flash installation program it brainwashes all flash developers into thinking xml is gods gift to earth.

    Good luck to anyone using amf, and be sure to donate.

  12. Dilip Gorasia  Replied:
    ( 10/17/2006 At 2:36 AM)

    Hi

    I tried to impliment your code in my application but i am not able to build my project.. The following error is occurred,

    "---->
    A file found in a source-path must have an externally visible definition. If a definition in the file is meant to be externally visible, please put the definition in a package. Connector.as rent

    <---"

    ------------------------------------
    I followed following step to impliment your code,

    1). I Downloaded Connector.zip and unzip that file and I coppied connector.as file on my root path.

    2). I Created new file in adobe flex with name test.mxml and i put your adobe script in this file.

    --------------------------------------

    And now i am not able to build my test.mxml file coz the bellow error is occurred.

    Please send me mail for the solution of this error..

    I want to chat with your technical moderator if the admin don't have any problem, My yahoo email is: dilip_g4u@yahoo.com.

    thank,
    Dilip Gorasia

  13. fgjxwkrtjp fgjxwkrtjp  Replied:
    ( 11/14/2006 At 11:21 PM)

    Ah i really know that there so incredible tecknology like this i am so enjoyed thx all.

  14. albo  Replied:
    ( 12/4/2006 At 4:50 AM)

    Ok guys, this tutorial explain very well how to receive data with amfphp. But how to CALL a php function (that is into the class you want to call) FROM flash passing a param ?

    I tried a lot of time, but the result is always NULL. So, I think the good old way to do it is to use the FlashRemoting MX component and write the query string directly into Flash. Then on php we could receive the query string with all the addicional parameters we want.

    If anyone have another solution about how to SEND params FROM flash TO a php class, please, write here.

    Thanks.

  15. shener shener  Replied:
    ( 12/18/2006 At 4:50 AM)

    hi every body.. i must say that i am almost new in action script at least above this subject.
    I want to ask a question.
    i have installed amfphp in to my web server(apache2)...
    the question is my files (flash + class + HelloWorld.php) must be in the localhost/amfphp/ directory or any files on the desktop..

    another question is which files name will be same

    class file and flash file or what? thanx from now..

  16. Ian B  Replied:
    ( 12/19/2006 At 7:36 AM)

    AMFPHP within an Apache .htaccess protected directory ---
    amfphp services return a '401 Authorization Required' message when running under a directory protected by .htaccess

    is there a way to run amfphp under a protected directory?

    thanks for any help...

  17. analia  Replied:
    ( 1/18/2007 At 7:46 AM)

    excelent article! thanx
    can`t wait for the next...

    Analia
    www.macroweb.ws

  18. Dutu Marian  Replied:
    ( 4/16/2007 At 9:36 PM)

    For those who didn't manage to run the demo because the class was not found, it is important to safe the Connector.as file with all the tree %there is the fla%/com/actionscript/amfphp/Connector.as and not only the as file on the location where you work.

    Nice clean tutorial,
    Dutu

  19. Adrian Reid  Replied:
    ( 4/29/2007 At 11:42 PM)

    Hey, nice tutorial. Taught be a bit, although I had to use a remote server because my PHP is playing up on my Apache server. With a few tweaks I was hoping to get this under way to being a small chat room. But it failed, I don't know what's wrong but I think it's the php file that is handling the calls.
    Here is the code I used in the PHP:

    <?php
    class Chat
    {
    function Chat()
    {
    $this->methodTable = array
    (
    "say" => array
    (
    "access" => "remote",
    "description" => "Pings back a message"
    )
    );
    }

    function say($sUserName, $sMessage)
    {
    return $sUsername . ' said: ' . $sMessage;
    }
    }?>

    I didn't change that much like I said. Here is my actionscript:

    stop()
    import com.actionscript.amfphp.Connector
    var gateway = "http://devilred101.freehostia.com/amfphp/gateway.php";

    SendBtn.addEventListener("click", sendmsg)

    function sendmsg() {
    var con:Connector = new Connector(gateway);
    con._PendingCall = con.setService("Chat").say(username, actmsg.text);
    trace(username + " said: " + actmsg.text)
    con.setResponders(this.onResult,this.onFault,this);
    }

    function onResult(data) {
    recieved.text += data.result + "\n"
    trace(data.result);
    }
    function onFault(status) {
    trace("error "+status.__fault);
    }

    I put the traces in to see if I was actually getting data back but I wasn't. Not even a fault was returned. Can somebody please guide me?

Login to post your comments. If you do not have an account with us please Register.
Copyright 2005 by ActionScript, Inc.   |  Privacy Statement  |  Terms Of Use  |  ActionScript Client Extranet