Вы находитесь на странице: 1из 12

Installing AMFPHP on WAMP server

Introduction

The AMFPHP project is designed to be a resource for Flash, Flex, and Air developers. The
documentation for this project assumes that you have an understanding of object oriented
programming in PHP and Action Script. Please read through all of the documentation
thoroughly. If you still need help please comment on the mailing list or through the forms. The
previous documentation for the AMFPHP 1.2 release is still available on this site.
http://www.amfphp.org/docs/

Requirements

You will need a web server and PHP4 ( > 4.3.0 ) or PHP5 installed. We recommend that you test
and develop on a local test server.

A fast way to set up your server is to use WampServer if you’re on a Windows machine. Check
this blog post for installation guidelines. It also covers running Apache and IIS at the same time.

Installing AMFPHP on your server

Download AMFPHP here . Drop all of the files into a folder in your document root. Many
examples and tutorials on the web use the /flashservices folder, so that can be a good choice.

gateway.php

There is a top-level file called gateway.php that you will need to modify in order to get your
installation working. This file will set the location of the services you wish to expose, the charset
handling (make sure to set it for the appropriate language), the library used for web services, and
other very important data. Please follow the instructions inside the file for using these settings
and the allowed parameters.

debuggateway.php

The debuggateway.php file is where you will want your services to point to during development.
The debug gateway calls the original gateway as though it were Flash itself (that is, using
cURL), passes through results or catches any fatal errors and wraps them in an error that is
readable to the NetConnection debugger. Note that debuggateway.php will not work without
gateway.php: one just calls the other.

The bottom line is that the debug gateway catches fatal errors, solving the godforsaken
NetConnection.Call.BadVersion issue that would make it hard to debug errors without access to
the error log. There a few caveats though:
• Sessions won’t work properly under the debug gateway. Using the error log is still
necessary whenever sessions are critically involved.
• cURL must be enabled
• There is a performance hit associated with using the debug gateway. You should always
point to gateway.php for production use.

Testing the installation

Load the gateway.php file through your server; for example, if you are developing locally, you
can load http://localhost/flashservices/gateway.php. If you see a prompt asking you to download
a file, the installation went well. Otherwise, PHP should output error messages that will help you
track down the actual error.

Enabling error logging for Apache and PHP

Fatal errors can be logged in a server log file. This can help you track down hard-to-debug errors
when all else fails. Open your php.ini file and search for ‘log_errors’. Set to On. Restart Apache.
From now on PHP errors will be logged in the server log file (ie. errors.log). This will aid you
tremendously as fatal PHP errors will throw random garbage in the output stream, meaning that
you will get a NetConnection.Call.BadVersion error in the NetConnection debugger. When that
happens all you will need to do is open the server error log, look at the last error, and fix it.

If you were not able to complete the steps above for enabling error logging because you don't
have access to php.ini, you may still be able to get error logging working. In the gateway.php
file, before the first include, write ini_set('log_errors', 1);. This may or may not work
properly depending on your php installation.

Installing the HTML service browser

Open the browser/config.inc.php file to make the service browser work. From then on you can
load it in your browser at the /flashservices/browser/ address. The service browser is useful as a
development tool, but you should probably keep it off the server, as it exposes your services.

Useful links:

http://www.herrodius.com/blog/category/amfphp/page/2

http://amfphp.sourceforge.net/docs/index.html

http://amfphp.sourceforge.net/docs2/index.html

http://amfphp.sourceforge.net/docs/
Flex and PHP: remoting with AMFPHP
Since I recently received some requests for a simple example on getting up to speed with Flex,
PHP, and AMF, I decided to write a tutorial on this topic. I will show you how to do remote
procedure calls from Flex to PHP classes using AMFPHP. Soon I will post an article on how to
do RPC using the Zend Framework and ZendAMF.

What is AMFPHP and why should you use remoting?

If you already know these answers, you may want to skip to the next section.
Let’s start by understanding of remote procedure calls. Remote procedure calls let Flex
applications make direct calls on the methods of your server side classes. Using BlazeDS or
LCDS 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 ZendAMF, WebOrb, and AMFPHP. This article focuses on remoting with
AMFPHP, which uses a binary protocol (AMF) to serialize 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, James Ward has put together a nice benchmark.

AMFPHP is a PHP open source library that knows how to serialize and deserialize the AMF
protocol, 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 said earlier, AMFPHP remoting uses AMF for serializing messages between the server and
Flex client. And it offers a nice feature 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 model classes. This is what you need to do. And in Flex you
will get an array of ActionScript objects. All the conversions from PHP to AMF format and from
AMF format to ActionScript objects are done automatically for you by Flex and AMFPHP.

When you use XML or JSON for remoting, usually you need extra steps in Flex to process the
data in order to display or store it.
Let’s look at a working example.

Step 1: Install the AMFPHP and understand its structure

While it is not hard to create a Flex application that makes RPCs using AMFPHP, I found some
possible glitches when you do it for the first time. If you missed something, you will end up with
errors such as:

• the array you retrieve in Flex is not of your type, but a generic object
• in PHP you don’t get a PHP VO class as an argument when you call a method,
but an associative array

It is my intention to explain all the small things you need to take care of, so you can get it right.
First grab the AMFPHP library archive, unzip it somewhere on your machine and then copy the
amfphp folder on your PHP webserver. From now on, I will refer to this folder as the installation
folder. On my machine this folder is c:/htdocs/amfphp and the URL is http://localhost/amfphp.

If you open this folder you will notice a folder named “browser”. When you open this folder in
your browser (on my machine http://localhost/amfphp/browser) you will get a Flex application
that lets you test all the exposed PHP classes:
Beside this folder, there is “services” folder. This is very important. In the “services” folder you
need to place all the PHP classes you want to expose to Flex code. Also, all the PHP Value
Object classes you want to use for modeling the data must be inside the folder “services/vo/” +
<the package name as folders> For example if you have the ActionScript class
org.corlan.VOAuthor and you want to map to a PHP class with the same name, then the PHP
class should be in “services/vo/org/corlan/VOAuthor.php”.

These are the default configurations for AMFPHP. If you don’t like them you can open the
globals.php file from inside of the installation folder and make changes.

Step 2: Create the PHP code

Let’s create a small PHP class that does two things:

1. Reads and returns all the records from a table


2. Offers a method to update one record

I use MySQL, and the table creation SQL is as follows:


CREATE TABLE `authors_aut` (
`id_aut` int(11) NOT NULL auto_increment,
`fname_aut` varchar(255) NOT NULL,
`lname_aut` varchar(255) default NULL,
PRIMARY KEY (`id_aut`),
UNIQUE KEY `fname_aut` (`fname_aut`,`lname_aut`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=5 ;

--
-- Dumping data for table `authors_aut`
--

INSERT INTO `authors_aut` VALUES (1, 'Dantes', 'Alighierie');


INSERT INTO `authors_aut` VALUES (4, 'Niccolo', 'Machiavelli');
INSERT INTO `authors_aut` VALUES (3, 'Umberto', 'Eco');
INSERT INTO `authors_aut` VALUES (2, 'William', 'Shakespeare');

So I create a PHP file inside the amf/service/ folder called MyService.php. Inside of this file I
create a PHP class with two methods: getData() and saveData(). The complete code is here:

<?php
require_once ('./vo/org/corlan/VOAuthor.php');

//conection info
define( "DATABASE_SERVER", "localhost");
define( "DATABASE_USERNAME", "mihai");
define( "DATABASE_PASSWORD", "mihai");
define( "DATABASE_NAME", "flex360");

class MyService {

public function getData() {


//connect to the database.
$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;
}

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;
}
}
?>

The code is pretty simple. No abstract database layer, just the simplest PHP code to make
something useful.

As you can see in the above code, I used the VOAuthor PHP class. So, now it’s time to create
this class (this class models one row from the table). Basically this class will have one field for
each row of the table (I will keep the name of the fields similar to the table fields) and an extra
field that tells AMFPHP how to serialize the class when sending back the message. Let’s see the
code and then I will explain a little more about this field:

<?php
class VOAuthor {

public $id_aut;
public $fname_aut;
public $lname_aut;

// explicit actionscript class


var $_explicitType = "org.corlan.VOAuthor";
}
?>

The extra field is $_explicitType, and its value is the fully qualified ActionScript Value Object I
intend to use in the Flex application to model the data. If you don’t configure this field correctly,
then in the Flex app you will not get your strongly typed ActionScript class, but a dynamic
object.

Important! Make sure you do not add empty spaces or other chars after the PHP closing tag. If
you leave extra chars, the output buffer will be flushed and the message that AMFPHP sends to
the Flex client will not be correctly formatted.

If you go back to the browser service of AMFPHP, you can try the code — select the getData
method and click the Call button. You should get an array of objects.
Step 3: Create the Flex project

We have all the PHP code in place, it is time to create the Flex application. First step is to create
a Flex project using the PHP server type (you can read here an article I wrote on how to create
Flex and PHP projects if you want to find more tips and tricks). This is the first page of the
wizard:
Click “Next” and then “Finish”.

Step 4: Create the ActionScript code

Now let’s create the ActionScript value object class, VOAuthor. Right click on the “src” folder
and choose New > ActionScript class (make sure you enter the package name):
The code for this class is:

package org.corlan {

[RemoteClass(alias="org.corlan.VOAuthor")]
[Bindable]
public class VOAuthor {

public var id_aut:int;


public var fname_aut:String;
public var lname_aut:String;
}
}

How does Flex know to serialize the ActionScript VOAuthor class to the PHP VOAuthor?
Because of the tag RemoteClass. Here you enter the name of the PHP class you want to use and
the path from the “amfphp/vo/” to the class as the package name. Thus I end up with
“org.corlan.VOAuthor”.
It is time to put all these together and create the ActionScript code that makes the call to the PHP
class and displays the info. For this, open the php_amf.mxlm file if it isn’t already open and add
this code:

<?xml version="1.0" encoding="utf-8"?>


<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<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;

/**
* This function is called when an item was edited in the data grid.
* Calls the saveData() method on the PHP server
*/
private function save(event:DataGridEvent):void {
var dataGrid:DataGrid = event.target as DataGrid;
var dsColumnIndex:Number = event.columnIndex;
var col:DataGridColumn = dataGrid.columns[dsColumnIndex];
var newValue:String = dataGrid.itemEditorInstance[col.editorDataField];
var dsFieldName:String = event.dataField;
var author:VOAuthor = event.itemRenderer.data as VOAuthor;
if (newValue == author[dsFieldName])
return;
//get the new value for the first name or last name
author[dsFieldName] = newValue;
myRemote.saveData(author);
}
]]>
</mx:Script>
<!-- this is the RemoteObject used to make the RPC calls -->
<mx:RemoteObject id="myRemote" destination="MyService" source="MyService"
endpoint="http://localhost/amfphp/gateway.php" showBusyCursor="true"/>

<mx:VBox top="30" left="100">


<mx:Button label="Get data" click="{myRemote.getData()}" />
<mx:DataGrid id="myGrid" dataProvider="{myRemote.getData.lastResult}" editable="true"
itemEditEnd="save(event)">
<mx:columns>
<mx:DataGridColumn dataField="id_aut" editable="false"/>
<mx:DataGridColumn dataField="fname_aut"/>
<mx:DataGridColumn dataField="lname_aut"/>
</mx:columns>
</mx:DataGrid>
</mx:VBox>
</mx:Application>
For remoting, Flex uses RemoteObject. As you can see in my code, I create one instance of this
object. Then I configure the endpoint to work with AMFPHP and the PHP class (MyService).
For this I add the URL to the gateway.php file as the value of the attribute endpoint, and I set
MyService as the value of the destination and source attributes.

The UI of the application is very simple: a button to call the getData() method from the server
and a data grid for displaying and editing the data. The binding between the data retrieved from
the server and the data grid is done directly on the data grid using the property lastResult:
dataProvider=”{myRemote.getData.lastResult}”.

There is an event listener registered on the data grid for the event of ending the editing of a cell.
Inside this event listener, I call the saveData() method using the instance of the currently edited
Value Object.

Final words

That’s it folks! If you are too lazy to set up the project and copy and the code, you can download
the project from here. Read the readme.txt after you import the project in Flex Builder using the
Import wizard > Flex Builder. I will post another article on ZendAMF soon. See you!

Link : http://corlan.org/2008/10/10/flex-and-php-remoting-with-amfphp/

For flex examples(how to build) :


http://www.adobe.com/devnet/flex/articles/flex_php.html?devcon=f1

http://www.sephiroth.it/tutorials/flashPHP/flex_remoteobject/index.php

Вам также может понравиться