Flex and PHP: remoting with Zend AMF

The latest PHP library to add support for AMF and remoting is Zend Framework. The preview prelease version 1.7 offers a new component Zend_AMF that lets you create Flex applications that talk to PHP backends using remoting. Since I am a big fan of remoting as a way to get data to your Flex/AIR clients, I wanted to add a short post explaining how to use it. Here is another post I wrote on remoting with AMFPHP. Actually this post is a part of a larger article I did for Adobe Developer Connection. I want to keep it more focused, so I wrote this one.

You can download a Flex Builder project that contains the code I explain in this article from here. Inside of the archive you will find a readme.txt file explaining what to do with it.

Installing the Zend Framework

After downloading the Zend Framework 1.7 archive, extract the files. Next, you have to add the library folder to your PHP include path. Open the php.ini file and add the path to the library folder to the include_path; on my machine looks like:
include_path = “c:htdocszend_frameworklibrary”

Next, save the file and restart your web server. You can read more about installing Zend Framework here. With this, you’ve completed the “installation” of Zend Framework.

What is AMF and remoting and why should you use it?

If you already know these answers, you may want to skip to the next section. Let’s start by understanding remote procedure calls. Remote procedure calls let Flex applications  make direct calls on the methods of your server side classes. Using BlazeDS or LiveCycle Data Services you can expose your Java and ColdFusion classes to the Flex application. However, if you use PHP you need a third party library on the server to expose PHP classes directly. Existing solutions include Zend AMF, WebORB, and AMFPHP. This article focuses on remoting with Zend AMF. AMF is a binary protocol for serializing the messages. Because it is binary, it is more efficient in terms of bandwidth and server processing load than JSON or XML methods. If you want to see for yourself how much more efficient it is, James Ward has put together a nice benchmark.

Zend AMF is a PHP library that knows how to serialize and deserialize the AMF protocol (it is part of the Zend Framework starting with version 1.7), and thus lets you expose PHP classes to Flex applications. Another compelling reason for using remoting is code reuse. Because you can call methods on PHP classes and these methods can return PHP objects, you don’t have to modify your existing code to output JSON or XML.

As I noted earlier, Zend AMF remoting uses AMF to serialize messages between the server and Flex client. It also offers the ability to map an ActionScript class to a PHP class. For example, suppose you want to display in Flex the information from a table with the following structure:

contacts
-------------------------------
id      primary key int
name    varchar(255)
email   varchar(255)

When using remoting, you create an ActionScript class to model this data in the client and a PHP class to model the same data on the server. When you create the PHP class that you want to call from Flex, you add a method that, for example, retrieves all the contacts from the table. This method will return an array of PHP VO classes, and in Flex you will get an array of ActionScript objects. All the conversions from PHP objects to AMF to ActionScript objects are done automatically for you by  Flex and Zend AMF.

When you use XML or JSON for remoting, you’ll tipically need extra steps in Flex to process the data in order to display or store it.

Let’s look at a working example.

Create the Flex PHP project

Usually, when I work with Flex and PHP projects, I prefer to use Flex Builder and Zend Studio installed together. It is possible, however, to work with Flex Builder and a PHP plugin to help you with the PHP code. Either way, you should create a Flex project that uses PHP on the server side (if you plan to use Zend Studio and Flex Builder, first create a Zend PHP Project, then use the Add Flex Nature wizard to add Flex PHP nature on the project). This way you streamline the deployment of the SWF file (the compiled result of the Flex project) to the PHP server. I chose to create a new project called “flex_php”.

Next, create a folder inside the PHP server root named “zendamf_remote”, and add this folder to the project. Choose New > Folder, and then click on the Advanced button. If you want to have the source files for the Zend Framework available to your project, and you use Zend Studio too, then open the properties page for the project, go to the PHP Include Path > Libraries tab, and add an External Folder pointing to the place where the Zend Framework is installed.

Create the PHP code

In the “zendamf_remote” folder, create three PHP files: MyService.php, VOAuthor.php, and index.php. Open the MyService.php page and paste the following code (you need to update the connection information for your specific database setup; to do this, look for the four constants at the top of the class):

<?php
require_once('VOAuthor.php');
//connection info
define("DATABASE_SERVER", "localhost");
define("DATABASE_USERNAME", "mihai");
define("DATABASE_PASSWORD", "mihai");
define("DATABASE_NAME", "flex360");

class MyService {
/**
* Retrieve all the records from the table
* @return an array of VOAuthor
*/
public function getData() {
     //connect to the database.
     //we could have used an abstracting layer for connecting to the database.
     //for the sake of simplicity, I choose not to.
     $mysql = mysql_connect(DATABASE_SERVER, DATABASE_USERNAME, DATABASE_PASSWORD);
     mysql_select_db(DATABASE_NAME);
     //retrieve all rows
     $query = "SELECT id_aut, fname_aut, lname_aut FROM authors_aut ORDER BY fname_aut";
     $result = mysql_query($query);

     $ret = array();
     while ($row = mysql_fetch_object($result)) {
     $tmp = new VOAuthor();
     $tmp->id_aut = $row->id_aut;
     $tmp->fname_aut = $row->fname_aut;
     $tmp->lname_aut = $row->lname_aut;
     $ret[] = $tmp;
     }
     mysql_free_result($result);
     return $ret;
}
/**
* Update one item in the table
* @param VOAuthor to be updated 
* @return NULL
*/
public function saveData($author) {
if ($author == NULL)
     return NULL;
     //connect to the database.
     $mysql = mysql_connect(DATABASE_SERVER, DATABASE_USERNAME, DATABASE_PASSWORD);
     mysql_select_db(DATABASE_NAME);
     //save changes
     $query = "UPDATE authors_aut SET fname_aut='".$author->fname_aut."', lname_aut='".$author->lname_aut."' WHERE id_aut=".  $author->id_aut;
     $result = mysql_query($query);
     return NULL;
}
}
?>

This is the class you will call from Flex. It has two methods: one to get all the records from the table, and another to update the values for one record.

Let’s create the code for the Value Object, the data model. This is used by the MyService class to wrap one row from the table. Thus, the method getData() returns an array of VOAuthor, and the method saveData() receives one argument: the VOAuthor of the row that was changed. Open the file VOAuthor.php and add this code:

<?php
class VOAuthor {
     public $id_aut;
     public $fname_aut;
     public $lname_aut;
}
?>

As you can see, this class is very simple; it just provides the same members as the fields from the table. Finally let’s create the code for index.php file. This is the plumbing code that expose the MyService class to Flex clients with the help of the Zend AMF. Add the following code:

<?php
require_once('Zend/Amf/Server.php');
require_once('MyService.php');

$server = new Zend_Amf_Server();
//adding our class to Zend AMF Server
$server->setClass("MyService");
//Mapping the ActionScript VO to the PHP VO
//you don't have to add the package name
$server->setClassMap("VOAuthor", "VOAuthor");
echo($server -> handle());
?>

I use an instance of Zend AMF server to create a PHP end point that can be called from Flex. Then I register the MyService class to the server, thus I can call this class from Flex. And finally I map the ActionScript data model (VOAuthor) to the PHP VOAuthor data model.

When you use remoting, you get the casting of the data to the right type for free. For example, MyService.getData() method returns an array of VOAuthor PHP objects. However, as you will see later, in Flex the result is an array of VOAuthor ActionScript objects.

Creating the Flex application

Now that you have the PHP code in place, you are ready to create the Flex code that will call the PHP class. I want the Flex application to have a button that gets the data from the server, uses a data grid to display the data, and enables the user to edit any cell (except ids) within the data grid. Whenever a cell is edited, the update is sent automatically to the server and saved to the database as well.

First, be sure to select the Flex perspective from the top right icons of Eclipse.

The next thing you need to do is to create a configuration file that Flex can use to reach the PHP service. Create the file services-config.xml in the root of the project. Open the file and add this code:

<?xml version="1.0" encoding="UTF-8"?>
<services-config>
    <services>
        <service id="amfphp-flashremoting-service" class="flex.messaging.services.RemotingService" messageTypes="flex.messaging.messages.RemotingMessage">
            <destination id="zend">
                <channels>
                    <channel ref="my-zend"/>
                </channels>
                <properties>
                    <source>*</source>
                </properties>
            </destination>
        </service>
    </services>
    <channels>
        <channel-definition id="my-zend" class="mx.messaging.channels.AMFChannel">
            <endpoint uri="http://localhost/zendamf_remote/" class="flex.messaging.endpoints.AMFEndpoint"/>
        </channel-definition>
    </channels>
</services-config>

Be sure to check the endpoint node (at the bottom of the file); your URL to the zendamf_remote folder might be different. Set the value appropriately for your setup.

Now you need to tell Flex Builder to use this file when compiling the project. Right click on the project name in the Project Explorer and choose Properties. Select Flex Compiler and add the following to Additional compiler arguments field: -services “absolute_path_to_the_file/services_config.xml”:

Adding services_config to compile arguments

You will use a RemoteObject to communicate with the server, so add a mx:RemoteObject tag. You need to set the source attribute to MyService (this is the PHP class name) and the destination to zend – this is the destination created in the services-config.xml file. Also give a name to this object by adding an id attribute and set it to myRemote. Set the attribute showBusyCursor to true (whenever a call is made this will render the mouse icon as a watch, until a response from the server is received). The code should look like this:

<mx:RemoteObject id="myRemote" destination="zend" source="MyService" showBusyCursor="true">
</mx:RemoteObject>

Now you need to declare the methods you want to call on the PHP class, and add the listeners for fault and result events. The code is:

<mx:RemoteObject id="myRemote" destination="zend" source="MyService" showBusyCursor="true" fault="faultListener(event)">
     <mx:method name="getData" result="getDataListener(event)"/>
     <mx:method name="saveData" result="saveDataListener(event)"/>
</mx:RemoteObject>

Next you need a UI to make the call to the server and display/edit the data. A button and a data grid will do. Add this code above the RemoteObject code:

<mx:VBox top="30" left="100">
           <mx:Button label="Get data" click="{myRemote.getData()}" />
           <mx:DataGrid id="myGrid" editable="true" itemEditEnd="save(event)"/>
</mx:VBox>

As you can see, the button calls the getData() method on the remoteObject. The data grid has an event listener registered for the itemEditEnd event.

The last step is to create the listeners you declared. For this, add an mx:Script tag to your MXML application and define four functions in it:

<mx:Script>
     <![CDATA[
           import mx.controls.dataGridClasses.DataGridColumn;
           import mx.events.DataGridEvent;
           import org.corlan.VOAuthor;
           import mx.controls.Alert;
           import mx.rpc.events.FaultEvent;
           import mx.rpc.events.ResultEvent;
           import mx.collections.ArrayCollection;
           /**
            * listener for the data grid's itemEditEnd event
            */
           privatefunction save(event :D ataGridEvent):void {
                //we don't want to update the id of the item
                if (event.dataField == "id_aut") {
                     event.preventDefault();
                     return;
                }
                //retrieve the new value from the item editor instance
                var dataGrid:DataGrid = event.target as DataGrid;
                var col:DataGridColumn = dataGrid.columns[event.columnIndex];
                var newValue:String = dataGrid.itemEditorInstance[col.editorDataField];
                //retrieve the data model that was edited
                var author:VOAuthor = event.itemRenderer.data as VOAuthor;
                // if the value wasn't change, exit
                if (newValue == author[event.dataField])
                     return;
                //update the model with the new values     
                author[event.dataField] = newValue;
                //call the remote method passing the data we want to be saved
                myRemote.saveData(author);
           }
           /**
            * Result listener for get data operation
            */
           privatefunction getDataListener(event:ResultEvent):void {
                //set the result array as data provider for the data grid         
myGrid.dataProvider = event.result as Array;
           }
           /**
            * Result listener for save data operation
            */
           privatefunction saveDataListener(event:ResultEvent):void {
                Alert.show("The data was saved!");
           }
           /**
            * Fault listener for RemoteObject
            */
           privatefunction faultListener(event:FaultEvent):void {
                Alert.show(event.fault.message, "Error");
           }
]]>
</mx:Script>

Finally, you need to create the ActionScript Value Object that will act as a data model for the data sent from PHP. Right-click on the src folder from Flex Navigator, and choose New > ActionScript class. For the package type org.corlan, and for the name type VOAuthor. Click OK. Now it is time to add the members and some meta-data:

package org.corlan {
     [RemoteClass(alias="VOAuthor")]
     [Bindable]
     publicclass VOAuthor {
           publicvar id_aut:int;
           publicvar fname_aut:String;
           publicvar lname_aut:String;
     }
}

The RemoteClass meta-data is very important. This tells to the ActionScript that the remote class (the one from PHP) that it maps to is called VOAuthor. If you forget this or you misconfigure it, you will get generic objects in ActionScript instead of VOAuthor, and associative arrays in PHP instead of VOAuthor.

You are done. There shouldn’t be any errors.

Now you are ready to test the code. Start the Flex application by clicking Run in the toolbar. When the application opens in your default browser, click the Get data button. You should see the data grid populated with some data:

Testing the application

To edit the items, just double click on any name and change something. When you finish editing, click outside the data grid. The changes will be sent to the server. If you don’t believe me, just go to the database and view the records.

Editing a cell

That’s it people!

Comments

146 Responses to “Flex and PHP: remoting with Zend AMF”

  1. PHP Coding School » Blog Archive » php code [2008-11-13 20:14:46] [http://php.coding-school.com/php-code-2008-11-13-201446/] on November 13th, 2008 11:30 pm

    [...] Flex and PHP: remoting with Zend AMF By Mihai Corlan Usually, when I work with Flex and PHP projects, I prefer to use Flex Builder and Zend Studio installed together. Though you can work with Flex Builder and some PHP plug-in to help you with the PHP code. Either way, you should create a … Mihai CORLAN – http://corlan.org/ [...]

  2. Radu [http://www.cocieru.com] on November 14th, 2008 3:23 pm

    For PHP 5.x and you can try

    while ($row = mysql_fetch_object($result,”VOAuthor”)) {
    $ret[] = $row;
    }

    My 2 cents ;) .

  3. Mihai Corlan on November 14th, 2008 5:28 pm

    @Radu

    Thanks for pointing this!

  4. lcf on November 18th, 2008 2:29 pm

    Just what I was looking for. Thanx a lot.

  5. Nickolay on November 18th, 2008 11:58 pm

    Thanks! It`s great!

  6. joox on November 19th, 2008 1:35 am

    thanks for this good job but i have this error:
    “faultCode:Client.Error.MessageSend faultString:’Send failed’ faultDetail:’Channel.Connect.Failed error NetConnection.Call.BadVersion: : url: ‘http://localhost/zendamf_remote/””
    any idea to fix this?

  7. Jeremy Savoy on November 19th, 2008 3:54 am

    Hi, first off great tutorial. I followed through it on the Adobe Developer Center.

    I am having trouble though, I get the error that services_config.xml cannot be opened. The file is in the root director of the project and this has been correctly added to the flex compiler options per your turorial. My path is correct, and the file does exist in the exact location on the filesystem. This is on Vista. Any ideas?

    One other question – is there a way to update Zend Studio to use ZF 1.7, so that we can just create a “Zend Framework Project” instead of “PHP Project” and still get Zend AMF for Flex?

    Thanks!
    Jeremy

  8. Mihai Corlan on November 19th, 2008 4:23 am

    @joox

    Man, I really couldn’t tell without having access to your server. The only idea I have:
    - see if it is running in the browser http://localhost/zendamf_remote
    if you get errors, then probably you either didn’t configure zend framework or you have some typos in the php

  9. Mihai Corlan on November 19th, 2008 4:25 am

    @Jeremy Savoy

    regarding your first issue, are you on Mac or win; most probably either the path isn’t correct or is some type in the xml file

    regarding the upgrading the zend framework, just go to Window > Preferences, then select from the left tree PHP > PHP variables and then add new framework in the list

  10. Jeremy Savoy on November 19th, 2008 6:51 am

    Mihai, thanks for responding!

    I’m on Vista. The path is correct, the file is absolutely at the path I have set, and I’ve only copied the XML directly from your tutorial.

    I do get an XML warning, but not sure how that would affect it …

    No grammar constraints (DTD or XML schema) detected for the document. services-config.xml

  11. joox on November 19th, 2008 2:35 pm

    @Mihai, thanks for your answer, i’v cheked my server and php and i fixed my problem but now i have this error :(

    “faultCode:Client.Error.DeliveryInDoubt faultString:’Channel disconnected’ faultDetail:’Channel disconnected before an acknowledgement was received’”

  12. Mihai Corlan on November 19th, 2008 6:16 pm

    @joox

    I have a wild quess that maybe some of your PHP still has a problem. Could be a space after the PHP closing tag (?>) or something like this. Other than that I don’t have any idea :)

  13. Mihai Corlan on November 19th, 2008 6:27 pm

    @Jeremy

    I really don’t know what to say :( It should work. Is your PHP method returning something?

  14. Jeremy Savoy on November 19th, 2008 6:48 pm

    Ok, interestingly enough I tried the same example on a different computer today and had no errors, everything works as expected except that I had to manually copy the Zend/ directory to zendamf_remote, otherwise index.php gave errors about not finding Zend/Amf/Server.php …. and I did set up my PHP Includes so not sure what I missed there. Thanks again for the tutorial!

  15. Mihai Corlan on November 19th, 2008 10:11 pm

    @Jeremy

    I think you didn’t install the Zend framework into your php.ini file. maybe the path is wrong, or you forgot to add, or to restart the server.

    that’s really strange with working on one machine and not on another. I suspect is a problem with PHP version or configuration.

  16. farid valipour [http://www.webandishan.com] on November 22nd, 2008 9:52 pm

    Dear joox and Dear Mihai corlan

    I had problem same joox but I founded reason of following Error :
    “faultCode:Client.Error.DeliveryInDoubt faultString:’Channel disconnected’ faultDetail:’Channel disconnected before an acknowledgement was received’”

    it is simple , the connection to mysql failed.
    solution: check the connection parameter in MySrvice.php (define(“DATABASE_SERVER”, “localhost”);
    define(“DATABASE_USERNAME”, “root”);
    define(“DATABASE_PASSWORD”, “”);
    define(“DATABASE_NAME”, “flex_php”);
    for connecting to mysql , also check your database structure such as table name , field name (id_aut, fname_aut, lname_aut )

    to be same in MySrvice.php file.

    it was simple but i have spent 2 days for it.

    in the end I really appreciate for tutorial Mr. Mihai Corlan.

    BR

    farid valipour

  17. Mihai Corlan on November 23rd, 2008 1:49 pm

    @farid valipour

    thank you!

    @all
    generally the first thing you should do when you get errors in Flex, try to execute the PHP files in the browser (executes the methods you are calling from Flex), with show errors on; thus you will find easy trivial errors.

  18. patrick segarel on November 28th, 2008 7:17 am

    hi everyone!

    well, it took me some time :) but i’ve managed to get everything to work locally. i did actually find most of the mistakes by checking the methods in the browser. thanks for a great advice!

    now, i’ve uploaded the site. the server doesn’t return any errors but when i point my browser to mysite.com/zendamf_remote , the browser asks me if i want to download a file which actually contains the following text:
    Zend Amf Endpoint

    if i comment out:
    // echo($server -> handle());

    “Zend Amf Endpoint” is returned in my browser window, the way it does when testing locally!!!

    So, php seems to be fine since all is working locally…

    On the web server, I’m connected to Zend Amf Server, since the browser returns the endpoint address…

    In order to avoid the Security sandbox violation, i have set the endpoint uri in the services-config.xml to zendamf_remote/ and this works fine locally…

    So it seems that all the pieces are in place and yet something’s missing!!! Any ideas???

    Help! :)

    Thanks to all,

    Patrick

    the endpoint uri in th

  19. Mihai Corlan on November 28th, 2008 11:16 am

    @patrick segarel

    If I hit zend_amf in a browser, I am too prompt to save the file. This is not a problem, it is the normal behavior.

    So what is the error you get in Flex?

    I am not sure why should you get a sandbox violation, as the Flex app is loaded from the same domain where RemoteObject is.

  20. patrick segarel on November 28th, 2008 2:28 pm

    thanks for your quick reply ;)

    I don’t get a specific error, but I don’t get any data! If I test my service class directly, by calling it in the browser the data is returned though.

    I got a sandbox violation error when trying to test the services-config.xml, with the web address…but i can’t reproduce this actually.

    So, I guess the real question is, what are the steps to change from a local environment to a web environment?

    As mentioned before, the php code seems fine, as it’s working locally. My database connection is fine, I can test it in the browser and get the data back, the connection to the zend_amf_server is fine too… i’ve now changed the address in the services-config.xml to my site’s endpoint address.

    don’t know what else to do…

    patrick

  21. quantum on November 30th, 2008 4:05 pm

    Hi Mihai,

    First thx for your tutorial !

    after testing successfully your sample, I’m tryin’ now to use the Zend_Mail_Storage_Pop3 class to retrieve some mails from a POP3 server.
    I have some basic and simple classes which work fine in the browser when I test them, but get that “Channel disconnected before an acknowledgement was received” error when I’m testing with Flex…
    I can’t find out where is the problem, cause everything seems right on the php side (so in Flex ).
    Would you have a little bit of time to have a glance on my files, and if so, where could I post them ?
    Thx

  22. Mihai Corlan on December 1st, 2008 11:23 am

    @quantum

    Unfortunately I can’t take a look at your files. If I will do this for every people who ask my help, I wouldn’t be able to right any article :D

    Your error it could be triggered by some output from a file before the AMF stream is output (such as newlines after the closing php tags and so on).

    thank you for your kind words, and sorry I can’t do more for you.

  23. quantum on December 1st, 2008 12:40 pm

    Ok Mihai,

    I understand, thx anyway for responding and have good times at Milan :-)

  24. Kevin [http://www.planetkevin.com] on December 1st, 2008 8:06 pm

    Ditto to Patrick’s comments: I’ve got the BadVersion blues. My analysis:

    With MAMP (as on Lee Brimelow’s excellent gotoandlearn.com tutorial), I have everything fine on the localhost:8888 setting. On my Mac OSX10.5, with Zend 1.7 and CS4, I get exactly what I’m expecting. When I move to the server, I see the Zend Amf Endpoint message; but from with the SWF, I get the BadVersion error. Any ideas? It sounds the same as Patrick’s.

  25. patrick segarel on December 1st, 2008 9:21 pm

    it’s all working fine now! the main problem was with the services-config.xml.

    i can’t remember what steps i took to move my project to the web, but i must have done something in the wrong order… now that all is running fine, it seems that the only thing I needed to do (that is, after setting up the server on my site) was to change the endpoint uri in the services-config file!

    thanks again for your tutorial!

  26. Munich Flex and PHP user group meeting : Mihai CORLAN [http://corlan.org/2008/12/09/munich-flex-and-php-user-group-meeting/] on December 9th, 2008 2:30 pm
  27. Ron Ferguson [http://www.ronaldferguson.net] on December 14th, 2008 5:23 pm

    It’s great that Zend and Adobe have worked together to get an AMF implementation to PHP. However, I can’t find anything on how to secure the remoting services with PHP as you can do with ColdFusion and BlazeDS. Any suggestions?

  28. Mihai Corlan on December 15th, 2008 12:12 pm

    @Ron Ferguson

    You can make the calls over HTTPS. is this enough or your question was different?

  29. Ron Ferguson [http://www.ronaldferguson.net] on December 15th, 2008 3:56 pm

    I was thinking a different kind of security. In ColdFusion, you can secure CFC methods with usernames and passwords. I was looking for this kind of authentication in Zend_Amf but can’t find anything on it. Hope this clears it up a little.

  30. Mihai Corlan on December 15th, 2008 4:32 pm

    @Ron Ferguson

    Zend Framework has support for access control list (ACL). Just have a look at the online documentation:
    http://framework.zend.com/manual/en/zend.acl.html

    I didn’t try to use it with Zend AMF.

  31. Ron Ferguson [http://www.ronaldferguson.net] on December 15th, 2008 6:40 pm

    I just looked over the Zend_ACL docs. This looks comparable to the CFC way of doing it. I’ll give it a try.

  32. Nikos Katsikanis [http://www.ecommercetotal.co.uk] on December 16th, 2008 1:34 am

    Very useful thanks, God bless you

  33. Stefan Schmalhaus [http://blog.log2e.com] on December 16th, 2008 2:32 pm

    As an alternative to setting up the Zend AMF server directly inside the bootstrap file, I’d rather recommend to set it up inside a normal Zend action controller. This gives you the flexibilty of adding an HTML interface to your app if needed. Also, it makes it easier to utilize other features of ZF (like Zend_Db, Zend_Config, etc.). I wrote a mini tutorial on how to do this:
    http://blog.log2e.com/2008/12/14/utilizing-the-zend-amf-server-inside-a-zend-controller/

  34. Oliver’s Yard - Ollie Cronk’s Blog » Blog Archive » Some recent browsing (Green Issues, SOA, Dashboards) [http://blog.cronky.net/blog/?p=160] on December 17th, 2008 12:24 am

    [...] Zend Framework and Adobe Rich Media: http://corlan.org/2008/11/13/flex-and-php-remoting-with-zend-am... [...]

  35. farid valipour [http://www.webandishan.com] on December 17th, 2008 3:11 pm

    Hi guys

    I have extended this sample with cairngorm micro- architecture to be adobe standard and for starting real projests with flex and php based zendamf and cairngorm.

    I’ll prepare the video tutorial for this too.
    you can download the project source in http://www.ria.webandishan.com/Flex-ZendAmf-Cairngorm-Cairngen.rar

    if you had comments pls let me know about it.

  36. david on January 2nd, 2009 2:18 am

    think’s for this it was usefull, I tested with my framework zend with a specific amf view

    would be interesting to see how manage errors of php (exceptions in zend framework) in flex
    and what is the best design with MVC Zend

  37. david on January 2nd, 2009 2:36 am

    your opinion for best design between flex and zend ?

    I used your tutorial (think’s to you ! ^^) with “just” adding specific public directory and index, bootstrap and layout files for for AMF, and a specific AMF view in controller which handle the server

    so I keep the MVC model and I think I have just now to add AMF empty actions to my controllers wich AMF view which put the remoting classes to flex
    and I call components in flex by calling the AMF actions of controllers

    I think it respects the MVC model, but in this case view is not very useful (it just contains the Zend_Amf_Server code)
    do you think it’s good ? or do you advise a best practice ?

    it’s for a professionnal website so I want to make the best design :)

    another question for a professionnal using is how flex can manage the exceptions classes we create un Zend (for example if data zend components create a specific exception because it can’t access datas)

    think’s in advance
    and good christmas from Paris ! :)

  38. Throwing an error when working with PHP and AMF : Mihai CORLAN [http://corlan.org/2009/01/07/throwing-an-error-when-working-with-php-and-amf/] on January 7th, 2009 8:06 pm

    [...] simple. As a starting point you can have a look at the two articles I wrote on PHP and AMF with ZendAMF, and AMFPHP. And use the projects you can find attached [...]

  39. Mihai Corlan on January 7th, 2009 8:12 pm

    @david

    Thank you david, and a Happy New Year!

    Regarding your questions:

    For MVC and Zend, I recommend to have a look at these two posts: http://www.riaspace.net/2009/01/zend_amf-with-full-zend-framework/ and http://blog.log2e.com/2008/12/14/utilizing-the-zend-amf-server-inside-a-zend-controller/

    For handling the errors/exceptions I wrote a small post today: http://corlan.org/2009/01/07/throwing-an-error-when-working-with-php-and-amf/

  40. rne1223 on January 8th, 2009 5:12 pm

    I finally got it working. If you get this error:“faultCode:Client.Error.DeliveryInDoubt faultString:’Channel disconnected’ faultDetail:’Channel disconnected before an acknowledgement was received’”. Make sure to look into MyService.php and the structure of your table. I was getting this error because I created the table and instead of using “id_aut” I used “id”. So I went back and changed my table to use “id_aut” instead of “id” and that solved it.

  41. tiendan [http://blog.flextip.net] on January 19th, 2009 11:24 am

    Good tutorial, it OK with me.

    @joox

    Do you run index.php auto in web browser. If not, you must setting

  42. Steven on January 23rd, 2009 4:00 am

    Hi Mihai,

    Thanks for the tute, it has helped me heaps. Just regarding my own experience with getting it working locally. In my services-config file I had to add ‘index.php’ to the end of my endpoint uri path for it to work. Without doing this I got a channel.connect error. Was wondering if you could shed some light on this for me? Just want to make sure I’m doing everything correctly and as this wasn’t stated above I feel like I’m going wrong somewhere. Thanks in advance.

  43. Mihai Corlan on January 23rd, 2009 10:41 am

    @Steven

    Hi there, I think you didn’t set up in your web server index.php as a default page. But as long as it is working, you are not doing anything wrong.

  44. Tripexito on January 26th, 2009 10:46 pm

    Thanks man! good tutorial… I was trying to get flex and php to work with “WebORB” but I didn´t found a real solution… Now with Zend_AMF it was easier to implement… thanks a lot again!
    greetings from chile!

  45. Mihai Corlan on January 26th, 2009 10:50 pm

    @Tripexito

    Glad that help you. Actually I plan an article on Weborb for PHP, so stay tuned.

  46. Josh Chernoff [http://gfxcomplex.com] on January 27th, 2009 5:05 am

    you guys need to get a web proxy debugger like Charles http://www.charlesproxy.com/

    instead of running the function in your browser you can see the error in Charles, plus see whats getting send with data types.

  47. EC30 on January 27th, 2009 2:13 pm

    Mihai,

    Thank you for this tutorial. I’m currently using AMFPHP for Flex remoting but I’m considering moving to Zend AMF because of the collaboration of Zend with Adobe.

    One question; you say you don’t have to mention the package names, either in the class mapping in de index.php or in de RemoteAlias property in the AS Class. Is this correct?

    And when I decide to move my PHP VOs to a vo subdirectory: VOAuthor is e.g. in vo/VOAuthor, do I need to update the class mapping? eg “vo/VOAuther”, “VOAuthor”?

  48. yemi on January 27th, 2009 6:19 pm

    Thanks, your article has been really helpful. I get an error when sending an object from flex. Getting(getUser) the object into flex works great but sending(addUser) throws an error. This is my service class:
    contact_name = “John Watts”;
    $user->organization = “Visa Central”;
    return $user;
    }

    public function addUser($user)
    {
    echo $user->contact_name;
    return “s”;
    }
    }

    The error I get is this:

    “faultCode:Client.Error.DeliveryInDoubt faultString:’Channel disconnected’ faultDetail:’Channel disconnected before an acknowledgement was received’”

    I don’t think there is any problem with the mapping since getting the object and casting it to it’s type works in flex. Then the service works because the getUser method works. The addUser is a simple method and I don’t think there are any errors in it.
    Any ideas. thanks.

  49. Mihai Corlan on January 27th, 2009 6:54 pm

    @yemi

    The problem is the echo line. You can’t do this with AMF. If you comment that line, it should work.

  50. Mihai Corlan on January 27th, 2009 7:07 pm

    @EC30

    You don’t have to add the folder name there. You need only the class name

  51. yemi on January 27th, 2009 7:11 pm

    Ok. I tried it without the echo but it still doesn’t work. I then removed the parameter $user and called a simple method addUser() from flex without the parameter; and i get know faults/errors. But when I use the method as addUser($user) it doesn’t work. i tried using the variable since i get a warning in Zend Studio for not using it by returning $user back as “return $user” but still not working. Please advise. thanks.

  52. Mihai Corlan on January 27th, 2009 7:30 pm

    @yemi

    Because you say that one method works and another one doesn’t, means that the configuration of the service is OK, and that you don’t have sintax errors. The only thing that can be wrong is haveing some errors in the method that doesn’t work.

    The only thing that it came to me is to try execute the method with problems in the browser.

    Good luck!

  53. yemi on January 27th, 2009 7:45 pm

    Thanks again for your quick reply. one last thing I need you to teach me is how to execute the method of a service in a browser so I can debug the error all the way. I read this in previous posts but could not figure this out. My endpoint uri is http://localhost/mix_demo/gateway/
    I know how to run controller actions as controller/action but for a service…no idea. Thanks.

  54. Mihai Corlan on January 27th, 2009 9:35 pm

    @yemi

    just add some php code to make an instance of your class at the top of the class file, and call the method. Then call the class script in the browser.

  55. yemi on January 29th, 2009 8:12 am

    Mihai, please advise me. I downloaded your sample code and set it up on my system. It worked like a charm and I discovered something interesting:
    Getting the data or updating the dataGrid in your sample takes about 0.6 secs to run (locally using WAMP) on my system. Whereas the one I setup using the Zend Controller with Zend_AMF, Bootstrapper and diabling the ViewRenderer takes about 3.5 secs to pass a single object (without any database connection) on the same system. I am building an application to manage about 10,000 users with about 20 tables in MySQL. I am also using Flex for my client. No HTMLs/PHTMLs.

    So the question is this… should i just use Zend_AMF out of the box like you have in your sample. What do I have to loose if I do it this way? OR how can I optimize the speed of the application using the Zend_Bootstrapper and Contoller with the Singleton Architecture in Zend. Thanks.

  56. Mihai Corlan on January 29th, 2009 12:00 pm

    @yemi

    I am afraid I can give you a solution. However, I think you should consider these two things:
    - Check the PHP community around ZendFramework to see how you can optimize things;
    - Early optimization is the root of all evil. In other words, if you don’t plan to use other services from ZendFramework, why bother?

  57. yemi on January 29th, 2009 4:28 pm

    Thanks for the advice. I guess I would just stick to what I need in the framework. Thanks again.

  58. yemi on January 29th, 2009 9:19 pm

    Mihai.. I figured something out! Rememeber the problem I had in previous posts with a getMethod working and a sendMethod not working in ZEND_AMF..? I tweaked your sample a bit to simulate the problem. I read that there are 3 ways to do class mapping and all the time I had been using the public $_explicitType METHOD. So this is what I did to your sample. I commented out:
    //$server->setClassMap(“VOAuthor”, “VOAuthor”);
    and added:
    //public $_explicitType =’VOAuthor’;
    to the class VOAuthor.

    … and then the datagrid in the sample throws an error when updating… the same problem I had.. can’t send an object to the server. And when I added the $server->setClassMap to mine, it worked fine. Please check this out. Maybe I am missing something out using this method or my system has gone crazy. Thanks.

  59. ash on January 30th, 2009 2:33 am

    Thanks for the code.

    How can I change the code so I can run different query each time (a.k.a different SELECT statement).

    Thanks again.

  60. Mihai Corlan on January 30th, 2009 12:13 pm

    @ash
    Lots of options. Send a param and depending on the param executes the query; or create more methods, one for each new statements …

  61. ash on January 30th, 2009 1:17 pm

    Thanks for the help. Since I am a newbie can you please give an example so I will have some start.

    Cheers for all.

  62. yemi on January 30th, 2009 1:40 pm

    hi, have you had a chance to figure out what the problem is with using
    public $_explicitType =’VOAuthor’;
    with the zend amf. Please refer to my post above. thanks.

  63. oscaroxy on February 9th, 2009 11:34 am

    I’ve a problem similar to “yemi”:
    I’ve put VOAuthor class into a package “business” (either AS3 and PHP) and if I use “$server->setClassMap(“VOAuthor”, “VOAuthor”);” (without specify package) then Zend work fine, while if I use “var $_explicitType =’VOAuthor’;” (into class) then Zend don’t work fine.

    I receive from PHP (php_error.log):

    PHP Fatal error: Uncaught exception ‘Zend_Amf_Exception’ with message ‘Unable to parse null body data VOAuthor mapped class is not defined’ in C:\wamp\www\provaZendAMF2\Zend\Amf\Request.php:174
    Stack trace:
    #0 C:\wamp\www\provaZendAMF2\Zend\Amf\Request.php(125): Zend_Amf_Request->readBody()
    #1 C:\wamp\www\provaZendAMF2\Zend\Amf\Request.php(93): Zend_Amf_Request->readMessage(Object(Zend_Amf_Parse_InputStream))
    #2 C:\wamp\www\provaZendAMF2\Zend\Amf\Request\Http.php(64): Zend_Amf_Request->initialize(‘????????null??/…’)
    #3 C:\wamp\www\provaZendAMF2\Zend\Amf\Server.php(365): Zend_Amf_Request_Http->__construct()
    #4 C:\wamp\www\provaZendAMF2\Zend\Amf\Server.php(313): Zend_Amf_Server->getRequest()
    #5 C:\wamp\www\provaZendAMF2\ZendAMF\gateway.php(18): Zend_Amf_Server->handle()
    #6 {main}
    thrown in C:\wamp\www\provaZendAMF2\Zend\Amf\Request.php on line 174

    I prefer to write $_explicitType =’VOAuthor’; into every business class! Maybe Do it need the package?

    In add … why I can’t specify a package? So I can’t write 2 class with self name!

    for example I would write business.Utente and transition.Utente in PHP so in RemoteObject into Flex I can write source=”transition.Utente”

    Thanks

  64. Mihai Corlan on February 9th, 2009 2:47 pm

    @oscaroxy

    Because I am not a contributor or developer for Zend AMF, I cannot answer to your questions :D

    I encourage you to give all this feedback on the Zend site, Zend Framework page. I am sure they will take in account.

  65. Gustavo on February 18th, 2009 8:31 pm

    Mihai, great tutorial.. thanks a lot..

    Just little question Mr:

    I modified the services-config.xml file to indicate that the endpoint must be ‘http://localhost/flex_php/one.php’. Also I renamed the index.php to ‘one.php’.

    Now I want to create another application within the same project using another service ‘two.php’ or just another datagrid in the same application that displays other data.

    How to do that ? The ’source’ property of my new RemoteObject is ‘twoService’ but it’s still going by the same endpoint especified in the services-config.xml and it’s not working.

    What are the files should I make changes to work?

    Tnx..

  66. Mihai Corlan on February 18th, 2009 10:41 pm

    @Gustavo

    You register all the PHP classes you want to exposed in the boot strap file, in my example in the index.php file. And the source property should have the value the name of the PHP class you want to call for that RemoteObject. You can use the same destination for any number of PHP classes.

    Good luck!

  67. Flex and PHP: remoting with WebORB : Mihai CORLAN [http://corlan.org/2009/02/18/flex-and-php-remoting-with-weborb/] on February 19th, 2009 12:24 am

    [...] AMFPHP, WebORB for PHP, and SabreAMF. I’ve already written articles on two of them, AMFPHP and ZendAMF. In this post I will focus on WebORB. Next, I will play with SabreAMF, and I will finish this [...]

  68. Bruno [http://www.maxismedia.com.br] on February 21st, 2009 1:20 am

    I have problems.

    When I click the button “Get data” nothing happen. I didnt receive any error message.

    Can you help me?

  69. Mihai Corlan on February 21st, 2009 1:24 am

    @Bruno

    Can you check the other comments? you should find an answer to your problem by doing that. Most probably it is a PHP error or configuration error of the remote in the xml configuration file. Thanks!

  70. quang.pham on March 3rd, 2009 9:14 am

    I’ve used Zend Studio v5.5 and Flex 3.x.
    Following the instructions at ‘CREATE THE FLEX PHP PROJECT’, I can’t see where the Add Flex Nature wizard is.

    Please tell me more clearly. Thanks a lot.

  71. quang.pham on March 3rd, 2009 9:25 am

    More info, I also use XAMPP.

  72. Mihai Corlan on March 3rd, 2009 12:00 pm

    @quang.pham

    Right click on your PHP project, In the contextual menu you will see a entry called Add Flex Nature.
    (As long as your project it doesn’t have Flex nature already)

  73. The Freeman View » Zend AMF [http://dcfreeman.nxtgenmedia.com/?p=67] on March 6th, 2009 1:36 am

    [...] good tutorials out there. Lee Brimelow has a good one on his site that gives a good introduction. Mihai Corlan has a good one as [...]

  74. krikri on March 8th, 2009 2:10 am

    Hi Mihai ,
    Please , can you do a tree with zend_amd where data are in database ?
    AMy is the only one who have done it with amfphp , and i try to do it with zend but i can’t .
    Can you help me please.
    Thank’s

  75. Rob Ganly [http://www.ganly.co.uk] on March 10th, 2009 9:17 pm

    hi there,

    i’ve just started a zend project that needs to talk to flash, (not flex – but my question is relevant here as you’ll see!).

    anyhow, i need to create an end point with services for a flash application to use. i’m not going to be building the flash element but i need to have as much ready as poss. for when the flash developer starts to do his/her thang!

    thus i need to essentially be able to test and emulate how flash/flex would use these services. i understand that amfphp has a browser syntax to allow for testing and aiding the development for such services.

    i’ve had a look but haven’t seen anything for zend-amf, does such a beast exist? if not, does anyone have any suggestions of a sensible way of doing this? ideally i’d like to get some formal/automated testing in there too (although this may be asking a bit much at this stage!).

    help very appreciated, time is of the essence here!

    rob ganly

  76. Mihai Corlan on March 11th, 2009 11:37 am

    @Rob Ganly

    Zend AMF doesn’t have this browser thing. You can go to Zend site an post a feature request.

    I have some hackish solution. If I understood you, you want to test the PHP code, that it will work when called from Flash. In this case you could use AMFPHP browser to test your PHP code.

  77. Jose on March 12th, 2009 7:50 pm

    Hi Mihai, I want to know how to create pdf documents in flex and php with zend AMF urges me, I have previously created pdf with php, but now I am interested to work as generating flex, thanks.

  78. Mihai Corlan on March 12th, 2009 11:48 pm

    Hi Jose,

    You can generate the PDF on the server using any PDF library you used to use, or you can use an ActionScript library for generating the PDF on the Flex side. There is a library, I don’t remember the name, you can search the web for it …

  79. Focus on Flex: Day 01 - Zend AMF | Jesse Brack - Web Design and All Things Random [http://www.jessebrack.com/2009/03/13/focus-on-flex-day-01-zend-amf/] on March 14th, 2009 5:52 am

    [...] Mihai Corlan – Informative tutorial for setting up Zend. [...]

  80. Jose Rodriguez on March 18th, 2009 8:53 am

    Hi Mihai, I have worked with flex and php using zend studio, but now I feel the need to develop a local application using AIR with php, but not as I imagine it is similar to flex, I hope I can help, because the project is about to start, thank you very much for your time.

  81. lazarus on March 19th, 2009 5:18 pm

    Thanks your Tutorial!

    I am Success!

  82. Diego on March 22nd, 2009 5:00 pm

    Zend AMF support authentication?
    i want to authenticate my Flex application because i must write data to Database and i don’t want all user can write on my AMF server.
    Thanks.

  83. Mihai Corlan on March 23rd, 2009 12:37 am

    @Diego

    I’ve been already asked to a similar question :D

    One way is to use:

    Zend Framework has support for access control list (ACL). Just have a look at the online documentation:
    http://framework.zend.com/manual/en/zend.acl.html

    Another way is to authenticate the user first from your Flex application by checking the credentials, if they are ok, just sent an ok answer to the client and set in the PHP a flag in the session. Basically you can use the PHP session to see if the request comes from a client that was authenticated, the same you would do with a HTML website.

    I have a post on authentication:
    http://corlan.org/2008/07/22/flex-air-php-and-user-authentication/

  84. Flex and PHP: remoting with SabreAMF : Mihai CORLAN [http://corlan.org/2009/03/26/flex-and-php-remoting-with-sabreamf/] on March 27th, 2009 10:22 am

    [...] the past months I have written a lot about Flex and PHP remoting using AMFPHP, ZendAMF, and WebORB. However, there is another library, SabreAMF, that can be used to do remoting. This [...]

  85. Patrick [http://patricklemiuex.com] on March 27th, 2009 8:21 pm

    Hi, thanks for the tutorial, I am unable to send a typed object back to the server, i get a fault,

    I have the class mapped to my ArticleVO and still no luck with that any suggestions?

    here’s my code:

    /**
    *
    * @param string $username
    * @param string $email
    * @param ArticleVO $articleVO

    * @return string
    * */

    function updateArticleById($username,$password,$articleVO)

  86. Ryan Canulla [http://--] on March 31st, 2009 12:30 am

    Hi Mihai,

    Thanks for any help in advance!

    A few questions i guess…

    1. How do I test the PHP methods on files in the browser?
    2. How would I debug if I don’t get an error but none of the data is there?

    Note
    - I get an endpoint when running the index in the browser
    - my server is set up as table:authors_aut -> id_aut, fname_aut, lname_aut

  87. Flex and remoting with PHP, which library is the best: Zend AMF, AMFPHP, WebORB for PHP, or SabreAMF? : Mihai CORLAN [http://corlan.org/2009/03/31/flex-and-remoting-with-php-which-library-is-the-best-zend-amf-amfphp-weborb-for-php-or-sabreamf/] on March 31st, 2009 7:30 am

    [...] communicate with your PHP server, and you wonder out of these four libraries which one is the best: Zend AMF, AMFPHP, WebORB for PHP, and [...]

  88. Mihai Corlan on March 31st, 2009 10:18 am

    @Ryan Canulla

    There are some answers to your first questions in the comments.
    Here is an article about debugging remoting:
    http://miti.pricope.com/2008/06/06/debugging-flex-and-php-with-flex-builder-and-zend-studio/

  89. Ryan Canulla [http://--] on March 31st, 2009 9:46 pm

    Thanks Mihai!

    Three additional questions.

    1. Is the services-config.xml in the root of the project (not in the src folder)?

    2. Re: The endpoint URI in the services-config.xml. Should this point to the root directory of the project, and not the src or bin-debug?

    3. It appears that you are not using a DB table like the following:

    contacts
    ——————————-
    id primary key int
    name varchar(255)
    email varchar(255)

    and something more like this within the SQL:

    authors_aut
    ——————————-
    id_aut primary key int
    fname_aut varchar(255)
    lname_aut varchar(255)

    Please confirm/correct me!

    Also, thank you much for the quick response and very helpful tutorial! I really appreciate the help!

    Best,
    Ryan

  90. Martin on April 24th, 2009 2:02 am

    Some concerns about ZendAMF….

    one question about ZendAMF and the integration of Flex (AS3) with PHP5.
    What is the sense of definining Value Objects in PHP and perform all the explicit class mapping with AS3 classes, when type checking is not enforced anyways?

    Example: I create a Contact object in PHP, add some non-member variables and send it via ZendAMF to Flex. There it will still be recognised as a valid Contact object.

    In addition, the setClassMapping method does not care if the Flex and PHP Object actually looks alike.

    Is there a function, which checks if an object really only defines member defined in the class (PHP and AS3)?

    Otherwise I dont understand the whole concept of binding the classes, when I am anyways able to send whatever I want an the serialized object will comply (whatsoever it contains) as a valid object.

    Thanks,
    Martin

  91. Muhammad Wasim [http://www.heady00.com] on May 4th, 2009 10:15 am

    I got this error by running your example project. Please let me know about its solution.

    faultCode:Client.Error.DeliveryInDoubt faultString:’Channel disconnected’ faultDetail:’Channel disconnected before an acknowledgement was received’

    I’ll be very grateful to you.

  92. Muhammad Wasim [http://www.heady00.com] on May 4th, 2009 7:31 pm

    Thanks Mihai for excellent tutorial I am able to resolve my problem nothing bad with the tutorial instead it occurred due to my fault.

    Now please guide me how I can upload it on my domain and how I can set up database for it.

    I’ll be very grateful to you for your help.

    Regards
    chand

  93. Chris on May 6th, 2009 12:38 am

    Thank you for the great tutorial.

    Following the steps you outlined, I set up a RemoteObject with ZendAmf and it works great.

    But, how do I create multiple services? I need multiple remotes. I’ve been working on it, but without and luck.

    Any suggestions?

    All the best,
    Chris

  94. Chris on May 6th, 2009 2:34 am

    I figured out how to do multiple remotes.

    I made a php error.

    Thank you for the excellent tutorial.

    All the best,
    Chris

  95. Muhammad wasim [http://www.heady00.com] on May 11th, 2009 8:54 am

    Hi, My problem is not relevant to this tutorial but it is relevant to zendAMF. I encountered a problem that my DataGrid not shown the data but when I debug I got no problem, data comes from DB but not shown. PLease help. I’ll be very grateful to you.

  96. Working in Flash Builder 4 with Flex and PHP : Mihai CORLAN [http://corlan.org/2009/06/12/working-in-flash-builder-4-with-flex-and-php/] on June 12th, 2009 3:46 pm

    [...] not sure what remoting and Zend Framework are, you can read my post that explains these matters: Flex and PHP: remoting with Zend AMF. This article uses Flex Builder 3 (the previous version of Flash Builder [...]

  97. Zend_AMF and Flex « tonyandcarol.com [http://www.tonyandcarol.com/?p=140] on June 15th, 2009 8:22 am
  98. Smithie [http://n/a] on June 22nd, 2009 11:00 am

    Mihai,

    great article, thanks. im just starting up with Flex and AIR and this got me understanding it better than anything else ive read :)

    a question though; i couldnt figure out how to use getters and private properties on the PHP side. obviously, id rather not have to declare all variables on the model public – is there a workaround for this?

  99. Flex 3 and Zend_Amf Class Mapping Hint « ricombination [http://ricombination.wordpress.com/2009/06/29/flex-3-and-zend_amf-class-mapping-hint/] on June 29th, 2009 1:44 pm

    [...] familiar with amfphp and there are good resources available on the web ( e.g. Zend Amf Wiki and Flex and PHP: remoting with Zend AMF [...]

  100. handoyo on July 10th, 2009 2:36 pm

    Hi Mihai,i want to ask,suppose i create a php flex zendamf application,how do i configure the web hosting server so it works?Or does the web hosting usually have zend framework installed?Thanks…

  101. chand on July 11th, 2009 6:12 am

    @handoyo Hi handoyo, I like to answer this question, according to my knowledge you put all the files as it is, as you work on localhost machine. So that zend amf endpoint’s url is just changed nothing else for example first you have the path to it from your application to the localhost folder now you had to pass the url of your hosting path and try to use relative addressing instead of absolute. Your zend framework library goes along with your application. don’t assume that hosting provider do that for you.You give the path in your php.ini file to where to find the zend framework library.

    I hope that my answer is correct, but if it isn’t then don’t worry we had to wait for Mihai’s reply.

    Bye

  102. Conexão remota com ZendAMF « Leo Cavalcante – Blog [http://blog.leocavalcante.com/conexao-remota-com-zendamf/] on July 15th, 2009 7:33 pm
  103. Olivier on July 25th, 2009 12:51 am

    Just wanted to add a correction to your great article : “The RemoteClass meta-data is very important. This tells to the ActionScript that the remote class (the one from PHP) that it maps to is called VOAuthor”, that’s wrong. It’s not the one from PHP but from ActionScript.

    I had a hard time understanding why the binding wasn’t working for my project, my AS and PHP classes didn’t have the same name and in “alias” I had the PHP class instead of the AS one.

  104. Olivier on July 25th, 2009 12:53 am

    I think I need some sleep, after re-reading your sentence, I see you’re correct. I’m very sorry.

  105. David on July 26th, 2009 5:27 am

    question: ived used zendAMF on a previous project in the exact way as the tutorial above shows and it worked perfect now im working on another project and for some reason when i put the remoteObject method call results in an array it seems to be only putting 1 of the 4 items in each of the objects thats in the array the other 3 come up blank..any clue as to why thats happened? hope that made sense..

  106. Mahesh on July 29th, 2009 5:54 pm

    Hi,

    I was getting the following error.
    “Channel disconnected before an acknowledgement was received”

    I increased the max execution time value and the error is gone.

    I’m interested in knowing the root cause of the issue. I would like to know in which all conditions above issue may appear.
    Thank you

  107. Ryan C on July 29th, 2009 6:17 pm

    How do I test PHP methods in the browser?

    Awesome tutorial! I’m having some issues on the serve side…

  108. Ryan C on July 29th, 2009 11:40 pm

    Can I run my app locally and point to a php endpoint on a live server?

  109. Mihai Corlan on July 30th, 2009 12:58 am

    @Ryan C

    Yes, you can! However when a Flex app connects to another domain than the one from where the Flex app was loaded, you need to have crossdomain.xml set up on the server you want to connect.

    Just search on the net for crossdomain.xml; it is easy to set up the file. Just for the record many sites have such a file (Flickr for example)

  110. Ryan Canulla on July 31st, 2009 9:16 pm

    @Mihai

    Thanks I have one set in place. Do I keep the URI absolute on the final product (on the server)? So it would be calling ryancanulla.com from ryancanulla.com?

    Also, I saw some references to “test your php class methods in the browser”… Can you explain this, or point me in the right direction? Many thanks.

    Thanks for the help!

  111. Ryan Canulla on July 31st, 2009 9:23 pm

    I was getting the following error.
    “Channel disconnected before an acknowledgement was received”

    I increased the max execution time value and the error is gone.

    I’m interested in knowing the root cause of the issue. I would like to know in which all conditions above issue may appear.
    Thank you”

    I was also running into this when I was live (not locally). What did you change your max execution to?

  112. Ryan Canulla on August 1st, 2009 5:48 am
  113. Ryan Canulla on August 1st, 2009 7:51 am

    Just wanted to note a few things that gave me issues for others.

    I found that turning php errors on and watching the logs play a big part in debugging. You can subscribe to the log in ssh using tail -f error_log (on my server) and locally in the MAMP error logs. Here is a cool trick to get MAMP logs in the console.app (http://zroger.com/node/27)

    I just got this working! Great tutorial! Thanks Mihai!

  114. Mihai Corlan on August 1st, 2009 9:24 am

    @Ryan Canulla

    When I saying testing the PHP class methods in browser, what I mean is to write couple of PHP lines that use your class and its methods (of course you have to set the PHP to show at least errors). And if everything works, you know that any problem might be it’s not from the PHP class.

  115. ThibautG on August 1st, 2009 7:19 pm

    Hello Mihai,

    first of all, congratulation for your Tuto !

    My question is : is there a way to have a concurrency call issue on a service (not on a remote object, that can be resolved by the “concurrency” property)?

    I mean : I have 2 components that have their own remote object. But these 2 remote objects call the same service.php.

    It appears that when my 2 remote objects are called sensibly at the same time (on the preinitialize event of each component), the 2 service calls fail, but when one is called on preinitialize, and the second on creationComplete, just the second remote object fails…

    Am I right that there could be a concurrency issue on that call?

    If right, what workaround can I do please ?

    Thx :)

  116. Chris on August 4th, 2009 12:11 am

    Hello Mihai,

    I followed your excellent tutorial and Zend AMF is working perfectly on my localhost. Now I have to deploy my site to the server. What do I need to do in order to deploy it to the server? What needs to be changed? I plan to use Host Gator.

  117. Chris on August 4th, 2009 12:12 am

    Hello Mihai,

    I followed your excellent tutorial and Zend AMF is working perfectly on my localhost. Now I have to deploy my site to the server. What do I need to do in order to deploy it to the server? What needs to be changed? I plan to use Host Gator. Thank you.

    Best regards,
    Chris

  118. Mihai Corlan on August 4th, 2009 2:41 pm

    @Chris

    First of all you need to install Zend Framework on the live server, then you have to check that the URL for the RemoteObject are still OK (if you used absolute URL, you’ll have to change the value and recompile the application).

  119. Chris on August 4th, 2009 6:31 pm

    @Mihai

    Thank you for the info! As I understood it, I need to change the endpoint URL.

    All the best,
    Chris

  120. hanx on September 4th, 2009 7:30 pm

    what if we can access the php.ini to setup Zend?, some hosting don’t provide access to php.ini…

  121. Mihai Corlan on September 6th, 2009 11:03 pm

    @hanx

    Can you use ini_set()?
    or maybe using set_include_path:
    http://ro.php.net/manual/en/function.set-include-path.php

  122. Primeros pasos con Zend AMF y Flex 3 « Xyberia [http://xyrer.wordpress.com/2009/09/07/primeros-pasos-con-zend-amf-y-flex-3/] on September 7th, 2009 8:09 pm

    [...] y Flex 3 Publicado el Septiembre 7, 2009 por xyrer Todo el día de ayer estuve siguiendo el tutorial de Mihai Corlan acerca de como usar Zend Framework y Flex Builder 3, es una aplicación que llama unos datos a un [...]

  123. Boris on September 8th, 2009 10:02 pm

    Hi Mihai,

    first of all thank you for that tutorial. I’m new at FLEX and it was really helpfull when starting to use it.

    However tutorial is great I’m a bit surprised about AMF. Probably I do something wrong or not undersood AMF purpose properly because I have following problem.

    Based on your tutorial I have built simple project to retrieve huge bunch of data (approx. 18000 rows, Zend_AMF in PHP) and provide them into FLEX application. It works but seems to be teribly slow (approx. 2 minutes until completed result set is available in FLEX). So I started to experiment with other options, meaning pure XML, and was surprised that same amount of data are retrived into FLEX within 20 secs.

    As far as I understood AMF should be signficantly faster then XML but it seems it is not in my case. Or, and it is probably the case, I’m using AMF for wrong purpose. I understand that whole serialization proces of object takes some time and probably doesnt make sense to create value objects for 18000 rows just to retrieve them to FLEX. Might be XML should be used for such as purpose. If so what is purpose of AMF then?

    Thank you for opinion.
    Boris

  124. Mihai Corlan on September 8th, 2009 11:02 pm

    @Boris

    To tell you the truth I am surprise by the results. Here is a test created by James Ward where you can test various ways of bringing data. I choose 20.000 rows with AMF and it was faster than Flex XML (E4X) 5.000 rows.
    You can play around with the test here:
    http://www.jamesward.com/census/

    Coming back to your question, there are couple of reasons why AMF is faster than XML:
    - serializing to XML takes more than to AMF
    - the bandwidth could even 10 times less for AMF, because of the binary format and other compressions techniques (the same string is serialized only once, than referenced for example).

    In conclusion, I don’t know what to say about your example. Maybe you could send me the project to have a look at it.

  125. Boris on September 9th, 2009 11:20 am

    Hi Mihai,

    thanks for your answer. Of course I am aware of james ward benchmark from your tutorial and that was my primary reason to start to use AMF. :-)

    Meanwhile I have done some deeper exploration and realized that problem is definitely at client side. I tunded my PHP script by some echo current time instruction on its start and end to see in browser what time is consumed by php. Independently if I return XML string or AMF array time seems to be the same.

    Additionaly I added some Aler.show instructions into FLEX to places where I call remote object method and also into result listener. Time between call a dispatching result handler linearly grows based on amount of returned data. As mentioned before for 18000 rows is 6 times slower than when using HTTPService and XML. Strange of that is that time between remote object call and result listener is out of my control. This time is a black box of AMF implementation in FLEX. Additionaly I have pure testing application which does nothing else just waitng until remote object recieved data.

    I am sending framents of codes to show that I do nothing special.

    in PHP i have class HotlineDS with public function getHotlineData

    services-config.xml looks like

    *

    index.php contains code to manage Zend_AMF server and sets the class HotlineDS. Additinaly maps VO classes between flex and php. Same code you heve in tutorial just own classes.

    It really seems that my FLEX has resource lack to unserialize large AMF data. Is there any parameter at OS, internet explorer, FLASH level which can help? I am using Windows Vista, IE.

    Boris

  126. Boris on September 10th, 2009 5:54 pm

    Hi Mihai,

    some progress here but it drives me crazy.

    I have changed FLEX approach to call Zend_AMF. Instead of RemoteObject I tried to use NetConnection object and its call() method. 18 000 rows are returned within 14 secs. :-) )) 6 times faster than with RemoteObject. Have you any idea what should be the reason for such as difference between RemoteObject and NetConnection when using Zend_AMF?

    Boris

  127. hanx [http://sam1blog.blogspot.com] on September 10th, 2009 6:40 pm

    “Can you use ini_set()?
    or maybe using set_include_path:
    http://ro.php.net/manual/en/function.set-include-path.php

    where should I put the ini_set() function? on my service php file or on my gateway.php?

  128. ThibautG on September 13th, 2009 1:51 am

    Hello Mihai,
    I have a problem that I can’t resolve.
    First I would tell that I have done your tutorial, and it works perfectly with several class in php, as, and several services.
    Everything worked fine until this evening: I want to recover datas with a “SELECT FROM …” query and put them into a datagrid in Flex.
    So I made a new class (VOTrainingRating) in as and php, but when I execute the code I have the error:
    ArgumentError: Error #1063: Argument count mismatch on org.vo::VOTrainingRating(). Expected 8, got 0.

    The function: org.vo::VOTrainingRating() is the constructor of the class VOTrainingRating.as.
    The problem is : I never instanciate this class.
    Just One time : in the php class. But, we agree, the “new VOTrainingRating()” in my php class refers to my php class…. and not to my as class..
    So Why Do I this message please ?
    I would precise that when I broke the alias in my .as file (I remove the line [RemoteClass (alias="VOTrainingRating")]), I have no longer the error, and I recover perfectly the datas..
    So it seems that when I instanciate my class in php, It instanciate the class in .as, and when I remove the alias, it does not, it works fine ….
    I would recall that this code (TrainingRatingService.php, VOTrainingRating.php, VOTrainingRating.as) looks like the code I have already done for all others class /services in my project..

    I don’t know how I can resolve that.
    Do you know how I could please ?
    Thanks.

  129. leef on October 6th, 2009 9:15 pm

    I also found ZendAMF to be extremely slower than other options. I used the exact same code (AS3, and PHP) and compared ZendAMF to AMFPHP; ZendAMF was 5 times slower. I added this issue tot he ZendAMF bug-tracker, and have not seen any progress from the developer.

    http://framework.zend.com/issues/browse/ZF-7493

  130. leef on October 6th, 2009 9:16 pm

    I did my tests in Flash, not Flex.

  131. leef on October 6th, 2009 9:52 pm

    Here’s someone else’s timed results also showing about a 5x duration difference.

    http://gfxcomplex.com/video/zend-amf-vs-amph_amfphp-ftw/

  132. oscaroxy on October 7th, 2009 10:57 am

    I reduce the time comment all “riquire_once” into file of the Zend folder.
    I create the file “init” where into I create the function:

    function __autoload($class_name) {

    if (strpos($class_name,”Zend”) !== false){
    $arr = split(“_”,$class_name);
    $nome_classe_zend =”";
    for ($i=0;$i<count($arr);$i++){
    if ($i == count($arr)-1){
    $nome_classe_zend .= $arr[$i] . ".php";
    }else{
    $nome_classe_zend .= $arr[$i] . "/";
    }
    }
    require($nome_classe_zend);
    }
    }

    that is I load a class only when need.

  133. Ryan C on October 20th, 2009 8:49 pm

    Has anyone had issues where you send in a VO and receive back a generic object typed objectProxy?

  134. Mihai Corlan on October 20th, 2009 8:52 pm

    @Ryan C

    Most likely the mapping of the PHP VO to AS VO is not done correctly.

  135. Ryan C on October 20th, 2009 9:26 pm

    Thanks @Mihai..

    Are there any general rules?
    - AS class has [RemoteClass(alias="LoginVO")];
    - Two VO’s are identical (vars match)
    - method returns a strictly typed VO
    - Bootstrap sets class $server->setClass(“Test”);
    —- Should it call the setCLass method for he VO class?

    - Bootstrap sets classMap
    —- $server->setClassMap(“LoginVO”,”LoginVO”);

    Any thoughts are appreciated. I really want to understand what is going on and not just make it work.

    Can you have multiple setClass methods, and also multiple setClassMap() functions?

  136. Ryan C on October 21st, 2009 6:26 pm

    I figured it out. I had a ; at the end of the remoteClass MetaData

    package com.ryancanulla.dashboard_v2.vo {
    [RemoteClass(alias="LoginVO")] <—-
    [Bindable]
    public class LoginVO {

  137. Ryan C on October 30th, 2009 9:48 pm

    Please let me know if you guys have thourghts. I’ve been trying to debug this thing for days now. I have one VO that will mapp from php to flex, but that’s it. I am sending an array of VO’s back into flex. Two are identical except for the name and alias. I’ve also checked in charles and php is sending VO objects… Please help!

    UserVO.as <– this works
    package com.ryancanulla.dashboard.login.vo {
    [RemoteClass(alias="com.ryancanulla.dashboard.login.vo.UserVO")]
    [Bindable]
    public class UserVO {
    public var userID:uint;
    public var userEmail:String;
    public var userPassword:String;
    public var userFirstName:String;
    public var userLastName:String;

    }
    }

    UserVO.php

    TestVO.as <–not working
    package com.ryancanulla.dashboard.login.vo {
    [RemoteClass(alias="com.ryancanulla.dashboard.login.vo.TestVO")]
    [Bindable]
    public class TestVO {
    public var userID:uint;
    public var userEmail:String;
    public var userPassword:String;
    public var userFirstName:String;
    public var userLastName:String;

    }
    }

    TestVO.php

    Bootstrap…
    $server->setClassMap(‘com.ryancanulla.dashboard.login.vo.UserVO’, ‘UserVO’);
    $server->setClassMap(‘com.ryancanulla.dashboard.login.vo.TestVO’, ‘TestVO’);

  138. Ryan C on November 3rd, 2009 7:44 pm

    Update on my last post. I learned that you must have the VO instantiated somewhere in your code for it to correctly map in Flex. I hope this helps someone along the way…

  139. Shivik on November 5th, 2009 9:17 am

    Hello there

    I made the following change in the index.php file.

    $server = new Zend_Amf_Server();
    $server->addDirectory(APPLICATION_PATH . ‘/services’);
    echo $server->handle();

    Doing this the flex application displays “Channel Disconnected”. What could be going wrong in this?

  140. Introduction to ZendAMF « Flex ActionScript Guide Blog [http://thaiflexdev.wordpress.com/2009/10/04/introduction-to-zendamf/] on November 8th, 2009 12:22 pm
  141. Zach on November 12th, 2009 6:28 am

    Hi,

    Any idea how to push data from server-side to flex client using Zend Framework?

  142. Chris on December 12th, 2009 5:58 am

    In Jan., Steven wrote that he had a problem with the endpoint address. In the services-config file, he had to add ‘index.php’ to the end of the endpoint uri path for it to work.

    Thank you Steven for posting your message, as I had the same problem.

    Also, thanks again to Mihai for the great tutorial.

    -Chris

  143. Whippersnapper on December 21st, 2009 8:26 pm

    One reason for the NetConnection.Call.BadVersion error is PHP files that are encoded in other than ANSI. For example UTF-8 will NOT work. Propably because Zend_AMF is encoded in ANSI.

    So if you can connect to the gateway file but the response’s content-type isn’t application/x-amf, then check the encoding of your PHP files.

  144. mitch on December 29th, 2009 4:03 pm

    Hi. can someone give a suggestion with the follwoing;

    I have a Vo using the above example + $childItems_aut which is an array in the object. I create the Vo in php and it contains the $childItems (in my case relations from another table) as child array items to each vo object.

    Now when i use the follwoing in actionscript….

    var resultVoObject:Array = new Array();
    resultVoObject= event.result as Array;

    The…. id_aut;
    fname_aut;
    lname_aut;

    …are all good but i do not get a child array $childItems_aut that contains the child array items, instead a value of NULL

    what am i doing wrong?

    thanks in advance.

  145. arashaga on January 5th, 2010 1:15 am

    i tried to test my endpoint by browsing to index.php but for some reason it asks me to save the application/x-amf file! the index.php is listed as my directorindex in http.cong.
    any idea?

    thank you very much,

  146. Mihai Corlan on January 5th, 2010 10:59 pm

    @arashaga

    This is normal. It happened to me with some browsers…

Leave a Reply