Connecting to a Database Using AMFPHP Flex 4 RemoteObject

by David Salahi on May 15, 2010

Here’s a tutorial on how to connect to a MySQL server using AMFPHP. Everything needed to send and receive data is in the sample files including the server-side PHP code. This tutorial is loosely based on Ivan Ilijasic’s Populate components with data using AMFPHP recipe in the Adobe Flex Cookbook. Ivan’s tutorial is nice in that, like this one, it includes everything you need on both the server and client sides. This tutorial is simpler, though, in that it includes only the essentials of setting up the AMFPHP connection. (You do need to manually create the MySQL DB and the EMPLOYEE table in phpMyAdmin though. And, of course, you need to create a DB username/password.)

You can download the tutorial files (updated 6/27/10) and then follow these steps to set up the sample to access a remote DB with AMFPHP:

  1. Create a database on the server.
  2. Install AMFPHP on the server. Visit the AMFPHP website for the latest info and to download the software.
  3. Create PHP scripts to access the DB and install into the AMFPHP amf/services directory. The tutorial files include three PHP files you can copy to your services directory.
  4. Create the Flex application with a RemoteObject service.
  5. Set up the XML file to connect the RemoteObject service to the DB via AMFPHP.
  6. Add a compiler command that references the XML file.

Server Side

Creating a Database

Create a DB (using phpMyAdmin). (This tutorial uses a MySQL DB but you can use another DB. In that case, you’ll need to adjust the provided PHP script accordingly.) Here’s the EMPLOYEE table structure:

Here’s some sample data:

INSERT INTO EMPLOYEE
(EMPLOYEE_ID, FIRST_NAME, LAST_NAME, EMAIL, PHONE_NUMBER, HIRE_DATE, JOB_ID, SALARY, COMMISSION_PCT, MANAGER_ID, DEPARTMENT_ID)
VALUES
(1, 'Jimmy', 'McNulty', 'jmcnulty@bpd.org', '999-999-9999', '2000-01-01', 1, 20000, .05, 10, 12),
(2, 'Bunk', 'Moreland', 'bmoreland@bpd.org', '999-999-9999', '2000-01-01', 1, 20000, .05, 10, 12)

Install AMFPHP on the server

Just download the AMFPHP code and copy it to a directory on your server. To see if it’s working access gateway.php; e.g., http://flexperiential.com/code/…/amf/gateway.php
if it’s installed correctly, you’ll see a confirmation:

amfphp and this gateway are installed correctly. You may now connect to this gateway from Flash.

There will be a link further down the page to the service browser but we’ll come to back to that later.

PHP Code

Copy the three EmployeeService PHP files to the services directory of the AMFPHP installation. Adjust the DB parameters for your DB:

define( "DATABASE_SERVER", "localhost");
define( "DATABASE_USERNAME", "dbusername");
define( "DATABASE_PASSWORD", "dbuserpassword");
define( "DATABASE_NAME", "employee");

At this point, you can run a couple of tests to make sure your DB is working and that the PHP code is set up correctly with AMFPHP. First, invoke EmployeeServiceTest.php (e.g., http://localhost /amf/services/emp/EmployeeServiceTest.php). You should see a display similar to the following:

array(2) {
[0]=>
object(Employee)#3 (12) {
["EmployeeID"]=>
string(1) "1"
["FirstName"]=>
string(5) "Jimmy"
["LastName"]=>
string(7) "McNulty"
["Email"]=>
string(17) "jmcnulty@bpd.org"
...

If this test is working, the next thing to check is the AMFPHP service browser. Return to the AMFPHP gateway.php page and click the service browser link. The first time you run it it will ask for the location of the gateway page. Assuming the default is correct, click Save.

If you’ve installed the EmployeeService into amfphp correctly you’ll see an emp service listed. You should be able to expand it and call the getEmployees function and get back our two friends on the Baltimore P.D. Similarly, you can call the setEmployee function and change their names.

Client Side

At this point, everything is in place on the server and you just need to import the Flex project into your workspace. The code should run, as is, except that you will need to edit the services-config.xml file to point to your server.

To keep things simple there’s no UI for these examples. A call to init() occurs automatically when the app is run and the getEmployees function traces out the information received from the server. To test writing to the remote DB, uncomment the setEmployee function call and then check your DB with phpMyAdmin to confirm that the changes have been made.
Here’s the code to create the RemoteObject service which connects to the DB:

<fx:Declarations>
	
	<!-- NOTE: Compiler switch "-services services-config.xml" is needed to connect EmployeeService 
	           to AMFPHP through the XML file -->
	<mx:RemoteObject id="EmployeeService" source="emp.EmployeeService" destination="EmployeeServer"
					 fault="faultHandler(event)" showBusyCursor="true">
		<mx:method name="getEmployees" result="getEmployees(event)" fault="faultHandler(event)" />
	</mx:RemoteObject>	
	
</fx:Declarations>

Here’s the code calls the methods on the RemoteObject service:

import mx.collections.ArrayCollection;
import mx.managers.CursorManager;
import mx.rpc.events.FaultEvent;
import mx.rpc.events.ResultEvent;
import mx.utils.ArrayUtil;
import Project.Employee;
 
[Bindable]
private var _employees:ArrayCollection;
 
private function init():void
{
	EmployeeService.getEmployees();
	trace("called getEmployees");
 
	//setEmployee();
}
private function faultHandler(fault:FaultEvent):void
{
	CursorManager.removeBusyCursor();
	var errorMessage:String = "code:\n" + fault.fault.faultCode + "\n\nMessage:\n" 
		+ fault.fault.faultString + "\n\nDetail:\n" + fault.fault.faultDetail;
	trace(errorMessage);
}
 
private function getEmployees(e:ResultEvent):void
{
	trace('Employees are loaded.');
	_employees = new ArrayCollection(ArrayUtil.toArray(e.result) );
	for each(var employee:Employee in _employees)
	{
		trace(employee.FirstName+ " " + employee.LastName);
	}
}
 
private function setEmployee():void
{
	EmployeeService.setEmployee(1, "Cedric", "Daniels");
	trace("Called EmployeeService.setEmployee"); 
}

AMFPHP Configuration File (services-config.xml)

You’ll need to modify the services-config.xml file to point to your server. Just change the endpoint uri in the channel definition.

That’s it! You can now send employees back and forth from the Flex app to your server.

{ 29 comments… read them below or add one }

Gastón June 27, 2010 at 6:46 am

Hey there,
Why would the Flex project show me an error that it can’t find Employee class at compile time? Where is the Employee. as class supposed to be or how does it work? I’m new at Flex and even more at php on Flex.

Thanks

David Salahi June 27, 2010 at 4:01 pm

Gastón,
I looked at the files I made available for download just now and realized there may have been a problem with the ZIP file I posted previously. I’ve fixed that error and posted an updated set of files (a Flex fxp file this time). You may want to download the update and try again.

However, I’m not sure if that bug was related to your problem. In any case, the Employee class was, and still is, in a package called Project. This package resides in a subdirectory of the same name (as all named packages must). You’ll notice that in the latest code I posted the Employee class is imported into AMFPHPTest.mxml:

import Project.Employee;

That tells the compiler where it can find the class and should allow you to compile without error.

Dave

Andrew July 8, 2010 at 3:48 am

Got this error message on import of fxp file

Description Resource Path Location Type
Could not resolve to a component implementation. AMFPHPTest.mxml AMFPHPTest/src line 17 Flex Problem

Thanks for your efforts,
Andrew

David Salahi July 8, 2010 at 4:45 am

Hi Andrew,
I’m not sure why you’re getting that error. I just downloaded the file and imported it into a new workspace in Flash Builder and it worked fine. Tried the same thing on my laptop also and that went fine too. Was able to run the app on both.

Bad download maybe? Try again.

FYI, this is intended for Flash Builder 4.

Dave

Destra July 9, 2010 at 5:24 pm

Hello,

I just download your project and I’m getting an error :
Channel.Connect.Failed error NetConnection.Call.BadVersion: : url: ‘http://flexperiential.com/code/AMFPHP/Tutorial/amf/gateway.php’

I’m working on FB 4 :(

David Salahi July 10, 2010 at 12:41 am

Hi Destra,
I’m not sure why you’re getting that error. I just tested with a copy of the project that I downloaded yesterday (in reply to Gastón’s comment) and it worked OK for me. When I ran the project in debug mode I got no errors and I saw the following traces in the Console window:
called getEmployees
Called EmployeeService.setEmployee
Employees are loaded.
Cedric Daniels
Marge Simpson

Try entering that URL (http://flexperiential.com/code/AMFPHP/Tutorial/amf/gateway.php) directly into your browser. You should see this message:
amfphp and this gateway are installed correctly. You may now connect to this gateway from Flash.

If you see this, there should also be a link saying “Load the service browser.” If you see that link you should be able to click it and then choose the Emp service. You can then click the EmployeeService to test the get/setEmployee methods. If you can call getEmployee successfully, as I did just now, that indicates that the PHP service is running OK.

If you still have problems I’d Google that error message.

Hope this helps,
Dave

Andrew July 10, 2010 at 7:23 pm

I am encouraged that you got a connection to work.
I am also using Flash Builder 4… but with no success.

an error is trapped at this line :

Andrew July 10, 2010 at 7:28 pm

oops… I’ll try again without the offending xml tags

an error is trapped at this line :

<mx:RemoteObject id=”EmployeeService” source=”emp.EmployeeService” destination=”EmployeeServer” fault=”faultHandler(event)” showBusyCursor=”true”=

David Salahi July 10, 2010 at 8:53 pm

Andrew,
RemoteObject is part of the Flex framework so it’s odd that the compiler doesn’t recognize it. I’ve sometimes run into problems with the mx namespace when trying to compile projects that I’ve downloaded from the web. I’m not sure exactly what causes that but I’ve been able to work around it by deleting and retyping the tag with the problem. In fact, I can usually get it to work just by retyping the namespace (“mx:”). Sometimes the IDE will auto-suggest mx1 and if I accept that it then works.

This is my best guess for what you’re encountering. For more info, see this post on the Adobe Forums:
http://forums.adobe.com/thread/580993?decorator=print&displayFullThread=true
(scroll down a couple of posts to get to the more relevant portion of the thread).

Hope this helps,
Dave

Andrew July 10, 2010 at 11:41 pm

Thanks Dave,
I will check it out.
Like I say… I am encouraged by your posts.
Andrew

Andrew July 20, 2010 at 3:26 am

Hi Dave,
Your example did work for me.
I don’t know why it doesn’t work for me by just unpacking the fxp, but when I started a new project and built it exactly as you have it in the example… it worked.
I’m not going to spend time figuring out the difference.
Just… Thanks!
Andrew

Paul Chavaux July 24, 2010 at 12:05 am

– phpMyAdmin SQL Dump
– version 3.2.0.1
http://www.phpmyadmin.net

– Host: localhost
– Generation Time: Jul 24, 2010 at 12:04 AM
– Server version: 5.1.36
– PHP Version: 5.3.0

SET SQL_MODE=”NO_AUTO_VALUE_ON_ZERO”;


– Database: `employee`

– ——————————————————–


– Table structure for table `employee`

CREATE TABLE IF NOT EXISTS `employee` (
`id` int(4) NOT NULL AUTO_INCREMENT,
`EMPLOYEE_ID` int(11) NOT NULL,
`FIRST_NAME` varchar(20) NOT NULL,
`LAST_NAME` varchar(20) NOT NULL,
`EMAIL` varchar(30) NOT NULL,
`PHONE_NUMBER` varchar(20) NOT NULL,
`HIRE_DATE` date NOT NULL,
`JOB_ID` int(11) NOT NULL,
`SALARY` decimal(10,0) NOT NULL,
`COMMISSION_PCT` decimal(10,0) NOT NULL,
`MANAGER_ID` int(11) NOT NULL,
`DEPARTMENT_ID` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ;


– Dumping data for table `employee`

INSERT INTO `employee` (`id`, `EMPLOYEE_ID`, `FIRST_NAME`, `LAST_NAME`, `EMAIL`, `PHONE_NUMBER`, `HIRE_DATE`, `JOB_ID`, `SALARY`, `COMMISSION_PCT`, `MANAGER_ID`, `DEPARTMENT_ID`) VALUES
(1, 1, ‘Jimmy’, ‘McNulty’, ‘jmcnulty@bpd.org’, ’999-999-9999′, ’2000-01-01′, 1, ’20000′, ’0′, 10, 12),
(2, 2, ‘Bunk’, ‘Moreland’, ‘bmoreland@bpd.org’, ’999-999-9999′, ’2000-01-01′, 1, ’20000′, ’0′, 10, 12);

Paul Chavaux July 24, 2010 at 12:26 am

Absolutely Wonderful! I’ve tried three other demos today,including Mihai Corlan’s and was unable to get them to work, however, yours was seemless and hooked right up, amf browser recognized it, called it and delivered the goods!
Thanks again for a fine tutorial!
Paul

David Salahi July 24, 2010 at 2:05 am

Hey Paul,
Thanks for the feedback!
Regards,
Dave

Gastón July 27, 2010 at 6:31 pm

Hey there,
I was wondering if it’s possible to use a config.php file for the DB connection or does it have to be by constructor in each Service.php for it to work.

Thanks,
Gastón

David Salahi July 27, 2010 at 8:33 pm

Bonjour Gastón,
It would be possible to use a config.php file and that would really be a better way of doing things in a real application. Then you would just include or require config.php in your service file(s).

Of course, you do still need to create the DB connection before you can use it and the constructor is a natural place to do that. But, if for some reason, you prefer to defer creating the connection until later you could certainly do so.

Dave

Alonso September 11, 2010 at 5:48 pm

Hello David :

I am using Flash Builder 4

My error is the following,The page is blank, show data in alert and work, but not view nothing in the web page; assign the arraycollection to datagrid and not show me nothing, only show the number of rows and i can not view nothing in datagrid
I have a week with this problem, I need help

Apologies for my English is not very good

Thank for your answer

Karl Dreis October 1, 2010 at 5:42 am

WHere is the downloadable code. I can create the SQL table etc.. but I don’t know where to download the employeeservicetest.php etc… So if anybody knows where I can download it so that I can finish the tutorial I would appreciate it. Thanks!

David Salahi October 1, 2010 at 2:08 pm

Karl,
The download link is in the second paragraph of the post. Also, the AMFPHP link is in step 2, right below the second paragraph.
Dave

Matbaa October 8, 2010 at 2:17 pm

Is it easier to use Zend’s solution instead of this?

Andrew Fry October 8, 2010 at 4:33 pm

Matbaa,
If easy was always the best choice … ?

At this moment Zend Framework is toooo slow …

Test the difference here :

http://flexperiential.com/2010/05/15/connecting-to-a-database-using-amfphp-flex-4-remoteobject/

Andrew Fry October 8, 2010 at 4:34 pm

Sorry here is the test link … ( sleepy )

http://philflash.inway.fr/flex/xmlperf/index.html

Michael October 15, 2010 at 7:34 pm

David,

Might just be my weird setup but I had to rename services-config.xml (and change the related references) to avoid the use of a dash. But I had this working in just under 5 minutes. Brilliant! Wish I could offer you more than a virtual Guinness.

Murray January 15, 2011 at 9:14 pm

RAD stuff – great read… it works!
I really think zend is still a far way from a easy to use framework …un less you are a networking engineer of sorts.( in fact ZEND is my new four letter word:-) )

Still a novice here but any advice or pointers would be great.
I see the real advantage with FB 4 and amf is clever lazy programming of getting FB to generate CRUD scripts and choosing which services to use when etc etc…

I like generating these amfphp services though the “click here to generate sample” and then copying them over to amfphp to kickstart the project.

I was hoping this article/comments would shed some light on how to dig up and change those auto generated scripts/settings…
In my project at the moment they are tending to include the gateway.php file in the project source … I guess this comes with the custom zend php folders installed.

Compiling with the – service services-config.xml (edited) doesnt seem to do much to change the behavior…
also ????
where would i find this – any ideas?

Murray January 15, 2011 at 9:17 pm

sorry – found i good explination here
http://forums.adobe.com/thread/475579

Mick February 8, 2012 at 11:34 am

Great example. Thanks for the post!

davey October 24, 2012 at 9:43 pm

Thanks for the tutorial, but first of all I can’t see the emp service listed in the AMFPHP service browser. Secondly after I run the application via flex builder I get a white screen in the browser.

Any advice?

David Salahi October 27, 2012 at 2:53 pm

The white screen most likely means that your SWF file is not found at the URL you specified. Check your browser’s developer tools (F12 in most browsers) or an add-on like Firebug to see if you’re getting a 404.

Not sure about your other problem. What have you tried? What exactly do you mean by “can’t see the emp service?” You might want to use a debugger like Fiddler (Google Fiddler and AMFPHP).

Peter January 23, 2013 at 12:37 pm

I love finding these types of good quality articles on Flex, even more so with Remoting. Wondering if you know of any changes that may have occurred with amfPHP because I was always ‘knew’ that objects from Flex to PHP are associative arrays. This article on amfPHP remoting shows the contrary.

http://www.brentknigge.com/?q=node/500

I haven’t tried it out, but I was wondering if this is something new with 2.1.

Leave a Comment

 

Previous post:

Next post: