Welcome, Guest. Please login or register.
Did you miss your activation email?
02/08/12, 14:06
Home Help Search Login Register
News: Parsley Flex framework review featuring quiz application, in our Flex frameworks series
Flex SDK 4.5 mobile roadmap: begin with your mobile development
Swiz Flex framework review featuring quiz application
New homepage we release our new Homepage, take a look ...

+  Flash-db
|-+  Server side Scripting and Database Support
| |-+  Flash Remoting with AMF (Moderators: Flash-db, Musicman, Jorge Solis, papachan, nothingGrinder)
| | |-+  AMF / Flash remoting for PHP (Musicman!)
0 Members and 1 Guest are viewing this topic. « previous next »
Pages: [1] 2 3 ... 6 Print
Author Topic: AMF / Flash remoting for PHP (Musicman!)  (Read 123851 times)
Flash-db
Administrator
Systems Administrator
*****
Posts: 1867



View Profile WWW
« on: 01/10/03, 02:31 »

Update 2.23.2003 - For anyone that is just reading over this thread.  There is a new more refined and complete Flash Remoting toolkit for PHP at http://www.amfphp.org, this should be used in the future.  The following is some really great background info and simple working examples  (Must Read).  Also it is recommended for anyone interested to sign up for the AMF-PHP mailing list to follow along with the development and ask questions.

New 1.23.2003 - A new message board has been added for future questions, discussions, and news on Flash Remoting with PHP.  The link is as follows: http://www.flash-db.com/Board/index.php?board=24  Please post any questions on this Board.

New 27.03.2006 -Just find this thread, the one at the very beginning of the amfphp project when Musicman post the amfphp base class. It's outdated of course, but I sticky it anyway(jorge)

I've been playing around with Musicman's amazing php script which allows you to pass array's/objects directly to and from a PHP script and a Flash movie.  I was hoping to open up a discussion on this topic!

For anyone not familiar with this please read over the great article by Musicman here:
http://www.flash-db.com/Board/index.php?board=19;action=display;threadid=3062  The last part of that thread (amf / flash remoting).

New: - Flash remoting with Web services: http://www.flash-db.com/Board/index.php?board=19;action=display;threadid=3190

What this allows you to do is pass arrays (multidimensional array's!) from a PHP script to a flash movie.  I'm sure that anyone that tries this out will find it extremely useful...

This thread is dedicated to seeing how much we can actually do with this concept and coming up with new use's.

AMF is short for Actionscript Message format.  This is a format that Macromedia developed for their Flash remoting products.  It's a binary format that allows you to pass array's/objects to and from a server. 


I'll start from the beginning for anyone that may not be familiar.

To get this up and running follow the below steps, this will help you become familiar with what we are talking about so we can have a better discussion.

1:  Create a flash movie called "amftest".  (doesn't have to be called that but we'll refer to it by that name).

On the first frame of the movie place the following code:
Quote
var nc = new NetConnection();
nc.connect("amfclient.php");
var reply = {};

reply.onResult = function(result) {
      _root.myresult = "result is "+result[ 0 ];
};

data1 = "test";
data2 = "test2";
nc.call('script1', reply, data1, data2); // here data1 and data2 are arbitrary flash data items

We will be dealing a lot with the line in Red so pay special attention to that for the demonstration.

2:  In the flash movie create a text field and give it a variable (Var:) name of 'myresult'.  Normally we could just put a trace command in their - but since not everyone has php installed on there desktop (and only their server) we'll do it this way.

3:  Create a PHP script with the following code;
<?
include "amfdata.php";  // parse request
$request = new amfdata();  // parse request

switch($request->fn)
{      
       case 
'script1'

        
$sample = array("newTest1"=>"multiTest1","newTest2"=>"someOtherValue");
        
$data = array(0=>23.451=>5.3"test"=>"jeffRemote""multiArray"=>$sample);
            
            
      
$request->sendresult($data);
}
?>

Call the above script "amfclient.php".  Place this in a directory on your server.  Make sure it's the same directory where your flash movie "amftest.swf" is located. 

Finally - download the "amfdata.php" script from http://www.fontimages.org.uk/flash/amfdata_php.html

Copy and paste the code from that file and create a PHP script called "amfdata.php".  This is basically your Remoting server.  It will handle

Place that in the same directory as the others.

That's it!  Now where ready to start experimenting with some really cool amf features.



To start experimenting, Test out the Flash movie you just created in a browser.  You should see the following appear in the text field called 'myresult' (that you created earlier): result is 23.45


That's a very basic example - but should get you started.  Next we'll try something a bit more complicated.

- Find the following lines in the 'amfclient.php' script.

$sample   = array("newTest1"=>"multiTest1","newTest2"=>"someOtherValue");
$data       = array(0=>23.45, 1=>5.3, "test"=>"jeffRemote", "multiArray"=>$sample);


This is a basic PHP array.  We made it a bit more interesting by using an Array inside an array (to test the limits of the script).  (You can obviously change these array's around to anything you want).

In the Flash movie change the line in Red to:
_root.myresult = "result is "+result.test;

This will produce the result: result is jeffRemote.  This is just a different way of accessing an array propery in Flash (ecmascript).  Basically were using the (index) key from the php array and accessing it in Flash ("test"=>"jeffRemote").  This can be a really useful way of passing information in Flash.

Now we get a bit more complicated, change the line in Red to:
_root.myresult = "result is "+result.multiArray.newTest2;

This will produce the result: result is someOtherValue.  Wow now that's useful.  In this case since our PHP array's is using strings as the index keys - we can use the same index key in Flash to access the multi-dimensional array value from a php array inside of Flash.  - (result.multiArray.newTest2)  - multiArray is the index in the first array, newTest2 is the index of the second array.  The value of that cell is - someOtherValue.

- And that's about it.  Hopefully that wasn't to complicated.  Once you start playing around with this you'll find it really useful - I know I will.

Please post any comments, questions, or code snipets so we can all become more familiar with this.  This is really new to everyone - so anything will be possible.

Extra special Thanks to Musicman (Wolfgang) for writing the Code and explaining how this works.
« Last Edit: 03/27/06, 04:05 by Jorge Solis » Logged

-Jeff.
Musicman
Administrator
Systems Administrator
*****
Posts: 2685



View Profile WWW Email
« Reply #1 on: 01/10/03, 04:25 »

Hi,

want to find out what "result" is?

[script]
function showvar(data {
    if(typeof(data) == 'number')
       myresult += data + ' (number)\n';
    else if(typeof(data) == 'string')
       myresult += data + '(string)\n';
    else if(data.length) {
       for(var n = 0 ; n < data.length ; n++)  {
            myresult += n + ':';
            showvar(data[n]);
       }
    }
    else {
        for(var n in data) {
            myresult += n + '=>';
            showvar(data[n]);
         }
     }
}
[/script]

Want to see what data arrives at your server?
check www.php.net/manual/en/function.var-dump.php
(especially the Tip there, since you have to save data to a file or send back a string to your movie with sendresult in order  to see it...

Musicman
     
« Last Edit: 02/14/03, 01:42 by Flash-db » Logged
Jorge Solis
Administrator
Systems Administrator
*****
Posts: 14593


View Profile
« Reply #2 on: 01/10/03, 10:27 »

Really incredible, I never have used it, but just planning to implement in my next job. Could be a BIG solutions for the ones (like me) tryng to parse complex sctructures of variables tryng to figure out the relationship between data.

Thanks Musicman  Grin!!!!!!!!!!!!!!!!!!!

Jorge
Logged

Jorge Solis
Administrator
Systems Administrator
*****
Posts: 14593


View Profile
« Reply #3 on: 01/10/03, 17:29 »

I was playing with this class, focusing on some common situation when buildings sites. Well, in this simply example, my goal is to show the characteristics of a product when the user select his name from a ComboBox.



When user select the name of some product (spanish food yeah), I want to show:

content per box
weigth per unit
price


Here usually we need to load the info from a database, using a script who outputs incremental name/pair values like this:

product1=Jamón&content1=2&weigth1=0.5&price1=15&product2=Lomo .... and so on

Well, now I will use AMF data based on the amfdata.php http://www.fontimages.org.uk/flash/amfdata_php.html class that Musicman has write. Instead of a database, I'll use a txt file with comma separated values and a PHP script who read the file and output the AMF stream.

Now, here's my txt (the ones who want to follow this example, can simply copy and paste) It comes from a really database of one of my clients, but I'm sure that he never will read this Wink

Quote
Chorizo Artesano, 2, 2.00, 5.20
Chorizo Extra "Gran Vela", 6, 9.90, 7.10
Chorizo a la pimienta, 4, 6.40, 7.20
Chorizo Extra Etiqueta Roja, 6, 9.90, 7.60
Choriozo Casero Dulce, 12, 3.00, 5.30
Chorizo Casero Picante, 12, 3.00, 4.50
Chorizo Pamplona, 2, 4.00, 6.00
Chorizo extra 1 Kg, 6, 6.00, 8.20
Salchichon Extra Velita, 12, 3.00, 9.00
Salchichon Extra Cardenal, 4, 6.80, 8.65
Salchichon Oretano 1 kg, 6, 6.00, 8.65
Salchichon Oretano 1,5 kg, 5, 7.50, 9.45
Salami Extra 120, 1, 4.10, 5.60
Salami Extra 90, 1, 4.10, 4.90
Fuet Extra, 25, 4.00, 10.25
Lomo Embuchado, 4, 6.00, 8.80
Lomo Embuchado 1/2, 8, 6.00, 8.80
Lomo Serrano, 6, 6.60, 7.20
Lomo Serrano 1/2, 12, 6.60, 9.20
Lomo Duroc, 4, 6.40, 12.00

Each line finish with an <ENTER> (breakline) and that's important, since my PHP script read line by line. The info in order is: name of product, quantity per box, weigth per unity, price.

Now the Flash scenario. A ComboBox with an instance name of "productsList" and a dinamyc textbox below it with an instance name of "describe". Nothing more, simple!!

The ComboBox will display the names of my products, the textbox his properties.

Ok, we need to setup the PHP file that reads this txt file and outputs the AMF stream. Here's how my PHP script looks:

Quote
<?php
//products.php
   require("amfdata.php"); //amf class
   $rqst = new amfdata();  // parse request
   switch($rqst->fn){
       case 'script1':
             $fp = fopen("products.txt", "r");
             if(!$fp) die("Couldn't open the file");
             $cont = 0;
       while (!feof ($fp)) {
         $string = fgets($fp, 4096);
         $temp = explode(",", $string);
         $properties = array("content"=>trim($temp[1]), "weigth"=>trim($temp[2]), "price"=>trim($temp[3]));
         $item = array("product"=>stripslashes(trim($temp[ 0])), "properties"=>$properties);
         $datos[$cont] = $item;
         $cont++;
      }
      fclose($fp);
      $data = $datos;
      $rqst->sendresult($data);
   }
?>

We explane a little what's going on here. The first two lines create the amfdata Object using the amfdata.php. Then, inside the switch option, we name our call "script1" (could be anything, but you need to call this from inside your flash file) and set the $data variable as the first item in the arguments of the request (rqst Object)
Then we open the above txt file (products.txt) and begin to read line by line, separating the arguments using the comma as delimitator (that's the reason because your txt should be correct: omitting breaklines or comma just fails in parsing)
Then we set an array with the properties of the product (stripslashes and trim just clean our string)  and next a new array with the name of the product and the array of properties (aka multidimensional array) Since we will use AMF data, we know that we can pass complex data structure to Flash.
Finally, we store our each of our $item array in the $data array. Remenber that $data is the AMF object we send to the movie. When we finish, we simply close the file and send the output. Finish of the PHP side

Now again in the Flash side. We have our ComboBox(productsList) and our dinamyc Texbox (describe) Now we need to add some script.



Add a layer and put in it:

Quote
var nc = new NetConnection();
               nc.connect("products.php");
   var reply = {};
   reply.onResult = function(result) {
      for(var i=0; i<result.length; i++)
         productsList.addItem(result.product, result.properties);
   };
   nc.call('script1', reply);
                productsList.setChangeHandler("showPrice");
function showPrice(obj){
   describe.text = "This product comes in boxes with "+obj.getSelectedItem().data.content+" units\n";
   describe.text+="The weigth per unit is "+obj.getSelectedItem().data.weigth+" Kg\n";
   describe.text+="The price in supermarkets is $"+obj.getSelectedItem().data.price;
}


The Netconection is a Flash Remoting feature that enables Flash to call remote functions, methods and applications pages. Was intended prymary for CFM calls, and need some Flash-remoting enabled aplication server. Here we call the products.php script and call the "script1" method and handle the reply in the "reply" object (we can pass parameters if needed)
So when our Object receive an onResult event (the called method is sending info) we use the returned object to setup our ComboBox throug the addItem method: the name of the product as label and an Object as the data. We set the Change Handler of our ComboBox as showPrice function, who simply outputs the properties of the data object to the dynamic Box

And here is our example working
http://www.estudiobaires.com/examples/products.swf

You can download the sources from http://www.estudiobaires.com/examples/products.zip
You can copy&paste the amfdata.php from http://www.fontimages.org.uk/flash/amfdata_php.html

Jorge

« Last Edit: 01/12/03, 12:12 by Jorge Solis » Logged

Flash-db
Administrator
Systems Administrator
*****
Posts: 1867



View Profile WWW
« Reply #4 on: 01/10/03, 20:08 »

Brilliant example Jorge!

I've been thinking about a couple questions on this.

1:  Is this format the exact same as AMF - or are there slight difference's.  If there are slight difference's, maybe we should rename this format to something else.  Such as FMF or something similiar.  I was thinking that maybe this could be sort of like what PNG is to GIF.  GIF is a proprietory format - but PNG is not.  Both have slight differences between them, and both have there own advantages.  Macromedia can charge royalties for there proprietory version and provide special services for it - while this format can be used without restrictions like PNG.  

What do you think of that? - anyone got any idea's on that topic.

2:  If there happens to be any difference's (and only Musicman will really know the answer to this) - what happens if the next player that Macromedia release's makes it impossible to use this?  

3:  Is it possible to do this in reverse - ie send actionscript array's/objects to the PHP script, and how would that be done?

That's about it.  This is a really incredible thing Musicman wrote.
« Last Edit: 01/10/03, 20:09 by Flash-db » Logged

-Jeff.
Musicman
Administrator
Systems Administrator
*****
Posts: 2685



View Profile WWW Email
« Reply #5 on: 01/11/03, 03:56 »

Hi,

the AMF format - as you can see it by checking e.g. the pet  market demo from Macromedia is exactly the format used here - it is just a binary stream of variables. There are a few zero bytes in the header which might be used for extra functionality or for player7 enhancements. Also, there seem to be functions in the player that do not change the data stream at all.
As for compatibility, changing the format would mean that all sites built on flash remoting would have to upgrade their servers as well ... so far Macromedia has tried to avoid that

As far as licensing and GIF ... the art that is licensed is not the gif format but the compression algorithm within. This is a substantial development that was published (probably in scientific journals) and patented.
Now, if someone had the same idea of developing a file compressor, and had not read the relevant description, would they ever arrive at a compatible file format? In contrast, decoding AMF is just guesswork.
BTW - credits go to Ralf Bokelmann for de-mystifying the similar format of shared object files

The data you pass to the server can be arbitrary flash objects. At the moment the hp part does not understand the "special" objects like date, recordset but only standard ones

The other method I wrote is actually sending compiled movies matching the F5 secs as data, but you have to send plain flash variables to it

Musicman
Logged
Musicman
Administrator
Systems Administrator
*****
Posts: 2685



View Profile WWW Email
« Reply #6 on: 01/11/03, 05:06 »

Code:

<?
require "nusoap.php";
require "amfdata.php";

$soap = new soapclient('service.wsdl', 'wsdl');
$rqst = new amfdata();
$reply = $soap->call($rqst->fn, $rqst->fnargs[0]);
$rqst->sendresult($reply);
?>
Logged
Flash-db
Administrator
Systems Administrator
*****
Posts: 1867



View Profile WWW
« Reply #7 on: 01/11/03, 13:14 »

Good idea - I think I'll try this out with the Google web service in a bit.  Before getting into that I was wondering what a good way to organize everything would be.  Macromedia's concept of having everything set up as remote components is actually a decent way of thinking about all of this, but doesn't help us out all that much.

Basically for amfdata - we could use a setup so that:

Code:
var nc = new NetConnection();
nc.connect("theDefaultGateway.php");  
This could be similar to a default gateway, and handle the connections for all of the scripts needed for an application?  


Then we set up various functions to act similar to MM's 'getService'  - ie
Code:
var getParkTypes = {};
getParkTypes.onResult = function(result) {
      trace(result);
};

Code:
var getParksList = {};
getParksList.onResult = function(result) {
      trace(result);
};

Code:
var getParkDetails = {};
getParkDetails.onResult = function(result) {
      trace(result);
};


Then finally we could call any of these service's anywhere in the Movie, ie
Code:
nc.call('getParkTypes', getParkTypes, param1, param1);  // Calls getParkTypes PHP

nc.call('getParksList', getParksList, param1, param1);  // Calls getParksList PHP

nc.call('getParkDetails', getParkDetails, param1, param1);  // Calls getParkDetails PHP

Finally we would have to set up the 'application server' to handle all of these requests.  Which could either be directly inside the 'theDefaultGateway.php' default gateway script - or just includes to different PHP scripts from that file.

So we could have something like:


Code:
<?
include "amfdata.php";  // parse request
$request = new amfdata();  // parse request

switch($request->fn) {      

case 'getParkTypes':

  $data = $request->fnargs[0];

  .....  some code to get park types .... or include other php page.
  request->sendresult($data);
  break;


case 'getParksList':

  $data = request->fnargs[0];

  .....  some code to get park Lists .... or include other php page.
  request->sendresult($data);
  break;

case 'getParkDetails':

  $data = request->fnargs[0];

  .....  some code to get park Details .... or include other php page.
  request->sendresult($data);
  break;

}
?>

Would that work?  

Some other questions:
What is,
request->fn  I assume this is the Method name ie Script1, getParkDetails etc.

What is:
request->fnargs[ 0]  I assume this contains all the parameters/data you sent from the flash movie.

In the above scirpt is it necessar to include the
  request->fnargs[0];
  $data =request->fnargs[0];
part in the Switch case.  I assume we can just call this once - then will not need it for each case.  Also is it necessary to include this at all.

I assume this last part is only necessary if you want to use Data from the Flash movie inside of your PHP functions used to return data?
« Last Edit: 01/12/03, 23:08 by Flash-db » Logged

-Jeff.
Musicman
Administrator
Systems Administrator
*****
Posts: 2685



View Profile WWW Email
« Reply #8 on: 01/11/03, 17:13 »

Hi,

if you do amc.call('scriptname', dta1, data2),
the $rqst->fn will be the scriptname, and the dta1 and data2 will end up as $rqst->fnargs[ 0], $rqst->fnargs[ 1]
So basically you have a choice of whether you want to create a parameter object before sending (as for the soap call) or send multiple parameters

There is no need to seperately list the $rqst->fnargs[ 0] inside the php call - this somehow crept into a posting and got copied over, you really only use the
$data = $rqst->fnargs[ 0];
(if you actually care for the data, that is ... so if you are imlementing an interface to google "find some random site", you do not need data)

Musicman
« Last Edit: 01/11/03, 17:32 by Flash-db » Logged
Flash-db
Administrator
Systems Administrator
*****
Posts: 1867



View Profile WWW
« Reply #9 on: 01/11/03, 18:38 »

Thanks Musicman.

I went and changed my example code to:

Quote

<?
include "amfdata.php";  // parse request
$request = new amfdata();  // parse request

switch($request->fn)
{      
      case 'script1':


       $sample = array("newTest1"=>"multiTest1","newTest2"=>"someOtherValue");
       $data = array(0=>23.45, 1=>5.3, "test"=>"jeffRemote", "multiArray"=>$sample);

           
           
     $request->sendresult($data);
}
?>


I got rid of the:

$rqst->fnargs[ 0];
$data = $rqst->fnargs[ 0];

Part because it is not needed.

I also renamed rqst to request.  I know this is obvisous to most - but when someone is first reading it I think it's easier to understand request then rqstjust helps with reading the code.

Musicman and Jorge - Can you go back through and edit your code to get rid of the extra $rqst->fnargs[ 0] part.  Unless we come up with some examples where it is needed?

And just for everyone else.  I assume that fn - stands for 'Function Name' then fnargs is an array of the parameters that have been passed from the Flash movie.  Is this the naming convention you had in mind musicman?

This is again a really obvious naming convention - but do you think it might be easier for people to understand if they where given more descritive Names? (I'm not sure if you can get any more descritive however.

2:  Musicman - have you thought about submitting this script to PEAR (pear.php.net) or sourceforge?

Thanks.
Logged

-Jeff.
Flash-db
Administrator
Systems Administrator
*****
Posts: 1867



View Profile WWW
« Reply #10 on: 01/11/03, 19:32 »

Musicman,

Would it be possible to modify (or write a script) - that allowed you to set/retrieve Shared Objects from PHP.  I'm not sure what the technical requirements to be able to do this would be - But It could prove useful for a lot of things.

Logged

-Jeff.
Musicman
Administrator
Systems Administrator
*****
Posts: 2685



View Profile WWW Email
« Reply #11 on: 01/11/03, 19:45 »

Hi,

should be possible ... do you consider uploading a shared object to a server and get its content printed in a readable format?

Musicman
Logged
Flash-db
Administrator
Systems Administrator
*****
Posts: 1867



View Profile WWW
« Reply #12 on: 01/11/03, 19:59 »

Yes would there be any security concerns with something like this.  And how would one go about doing this.  it would be nice to read shared Objects that were set with Flash via php/html.  So if you had a Flash and HTML site - you could read/write/use the same shared objects.
Logged

-Jeff.
Musicman
Administrator
Systems Administrator
*****
Posts: 2685



View Profile WWW Email
« Reply #13 on: 01/12/03, 02:20 »

Hi,

you probably would not want  to navigate to wherever flash stores those files to download a new one, so this option may not ne that useful. Maybe there would be just an option to view what the computer saves between visits to the pet market (or whether you think you want to keep or remove such files)

Musicman
Logged
Jorge Solis
Administrator
Systems Administrator
*****
Posts: 14593


View Profile
« Reply #14 on: 01/12/03, 13:25 »

Ok, I have change mi example, removing the

$rqst->fnargs[ 0];
$data = $rqst->fnargs[ 0];

since I'm not using Flash input in this case.

Musicman, another question about accesing Flash objects inside the PHP script. If Flash sends an object, say:

Quote
myObject = new Object();
myObject.prop1 = 10;
myObject.prop2 = 20;

var nc = new NetConnection();
              nc.connect("myScript.php");
   var reply = {};
   reply.onResult = function(result) {
            trace(result);
   };
   nc.call('script1', reply, myObject);

I can acces the properties of the object like this?

Quote
<?
include "amfdata.php";  // parse request
$request = new amfdata();  // parse request
switch($request->fn)
{      
      case 'script1':
      $data = $rqst->fnargs[ 0];
      //As an object ?
      $propertie1 = $data->prop1;
      $propertie2 = $data->prop2;
      //Or as an array ?
      $propertie1 = $data[ 0];
      $propertie2 = $data[1];
}
?>

Both doesn't seem to work to me (or perhaps I can't pass objects?)

About Shared Objects, I'm not sure about a convenience to read/write it on the server. Could be a choice to store data for simple login (all logins are stored in the SO and each client movie takes the info) or users online, anyway we can use a database or simple txt files to do the same. Also I have seem how FlashComm (Flash Communication Server) use the SO to store and manage multiple connections, but the i/o is based on the RTMP (the protocol they use for threads), so only a piece in the all picture.

Jorge
« Last Edit: 01/12/03, 13:26 by Jorge Solis » Logged

Pages: [1] 2 3 ... 6 Print 
« previous next »
Jump to:  


Powered by MySQL Powered by PHP Powered by SMF 1.1.16 | SMF © 2011, Simple Machines Valid XHTML 1.0! Valid CSS!
anything