AMFPHP class mapping

AMFPHP, Flash, PHP 2 Comments »

Here are some good things to know when using class mapping with AMFPHP. As an example, imagine working on an application that handles users through a UserVO value object. Here's what the PHP and the AS2 class look like.

The UserVO class in PHP

This class is in a "vo" subfolder of the "services" folder (in your AMFPHP installation dir).

PHP:
  1. class UserVO{
  2.   var $firstname;
  3.   var $lastname;
  4.   var $age;
  5.  
  6.   function UserVO(){
  7.   }
  8. }

The UserVO class in AS2

This class is in the namespace "com.domain.vo.UserVO".

Actionscript:
  1. class com.domain.vo.UserVO{
  2.   public var firstname:String;
  3.   public var lastname:String;
  4.   public var age:Number;
  5.  
  6.   function UserVO(){
  7.   }
  8. }

Flash to PHP

Sending VO's from Flash to PHP is quite simple. Just add the parameters in the "arguments" key. Use the fully qualified classpath of the class on the server side and make sure you set "required" to true;

PHP:
  1. "saveUser" => array(
  2.   "description" => "Inserts or updates the user in de database.",
  3.   "access" => "remote",
  4.   "arguments" => array(
  5.     "aboutVO" => array("type" => "vo.UserVO", "required" => true)
  6.   )      
  7. )

PHP to Flash

Watch out here! You can leave out the "returns" key from the method entry in the methodtable. When you do that, AMFPHP will return the name of the class for you. The thing to know here is that in PHP4 the classname will be returned in lowercase, while in PHP5 it will be returned in its original format of lower- and uppercases. Note that this does not return the fully qualified classpath, but just the classname. "uservo" vs. "UserVO".

Here's a quote from the "get_class" function docs.

In PHP 4 get_class() returns a user defined class name in lowercase, but in PHP 5 it will return the class name in it's original notation.
http://be.php.net/manual/en/function.get-class.php

This is not recommended because Object.registerClass() will fail because it is case-sensitive. The best way to get Object.registerClass() to work is to pass in the name of the class in the "returns" key and then use that same name in lowercase to register the class in Flash.

PHP:
  1. "getUserVO" => array(
  2.   "description" => "Returns a user.",
  3.   "access" => "remote",
  4.   "returns" => "vo.UserVO",
  5.   "arguments" => array()
  6. )

And then in Flash...

Actionscript:
  1. Object.registerClass("vo.uservo", com.domain.vo.UserVO);

That's it, cheers!

[Update] I must have missed something here: the "returns" string is always passed to Flash in lowercase. So remember that when you use Object.registerClass().


Add to Bloglines - Digg This! - del.icio.us - Stumble It! - Twit This! - Technorati links - Share on Facebook - Feedburner
 

Set up your AMFPHP environment: running IIS and Apache simultaniously

AMFPHP 20 Comments »

This post will guide you through the steps that are needed to setup your computer as a webserver in order to run PHP. After all, without running PHP, you won't be able to use AMFPHP since it is the language it is written in.

The tools needed are:
- an operating system (Windows in my case)
- a webserver (IIS or Apache for instance)
- PHP (duh!)
- a database system (MySql, probably the most used with PHP)

The setup I use is also called a WAMP setup. WAMP stands for Windows, Apache, MySql and PHP. Note that a LAMP setup (Linux, Apache, MySql and PHP) is probably more used, but WAMP just better suits my needs.

You can start downloading all of the above mentioned tools and then spend a couple of hours (if this is your first time) installing and configuring them untill it drives you nuts and it still doesn't work. Or, you can download WampServer and let the dirty work be done for you. Get WAMPServer here.

The installation

I tried to make as much screenshots as possible that show all the different steps, so this installation should be peanuts for you.

1. Wamp installation welcome screen (screenshot)
2. License agreement (screenshot)
3. Where should WAMP be installed? I left this at the default location. (screenshot)
4. Start menu folder. (screenshot)
5. Start WAMP on startup? Whatever you like best. I checked it because I needed to work with it for the coming 2 weeks and just to make sure everything was running. (screenshot)
6. Settings overview before installation. (screenshot)
7. Select your webroot folder (screenshot). This is the default but I prefer not to have any workfiles on the same drive as my Operating System in case I needed to format. Therefor I change the location to my D-drive. (screenshot)
8. Warning because I changed the webroot folder. You might not get this screen when you stick to the default location. (screenshot)
9. Select you default browser. Click OK to use Internet Explorer (screenshot), or browse to the FireFox executable. (screenshot)
10. Setup done. Let's launch WAMPServer. (screenshot)

After the installation

11. If everything went alright, you should see a new icon in your systemtray. This indicates that WAMP is or is not running and provides some menu options. (screenshot)
12. Test it. Click the tray menu and choose the "localhost" option or open up your browser and point it to http://locahost. You should see a file overview of the files in your webroot. This folder may be blank if you chose another folder than the default webroot folder. (screenshot) If you did choose the default webroot folder you should see the WAMP startscreen. (screenshot)
13. In case you didn't see the WAMP startscreen, copy the files in the default webroot location to the folder you chose as a webroot. (screenshot)
14. Click the PHPMyAdmin link under Tools on the WAMP startscreen to check if MySql is running. (screenshot) PHPMyAdmin is a webinterface to control your MySql databases.

Where's my IIS startscreen on http://localhost?

IIS users (who run ASP for instance) probably noticed that http://localhost normally pointed to the startscreen of IIS. So how can I access my ASP and PHP webapplications on localhost? Simple, you can't. At least not when you are running WAMP without having modified the configuration.

15. Shut down WAMPServer. (screenshot)
16. Point your browser to http://localhost. You should see the IIS startscreen, at least when you are running IIS on your computer. (screenshot)

OK, so do I have to shutdown WAMPServer if I want to work on an ASP application and start it again to work on a PHP application? The answer is no! Fortunately there is a way to run both webservers at the same time. All you need to do is change the port number the webserver is running on.

Port number?

When you type in http://localhost in your browser, it is interpreted as http://localhost:80 by the browser because port 80 is the default http port. A port is just an indication to the computer to start a specific process. By default, on my system, it runs IIS. We will leave port 80 as it is and change WAMP to run on port 81.

17. Click the WAMP systemtray icon and choose "httpd.conf" under "Config files".
18. Do a search for "port 80" in the config file. (screenshot)
19. Change it to "port 81". (screenshot)
20. Restart WAMPServer. (screenshot)
21. Click the "Localhost" option in the WAMP systemtray menu.
22. FireFox opens but you get a security warning. It is trying to open the IIS startscreen. (screenshot) Internet Explorer will show the startscreen without the warning as shown before. The point of this step is to notice that the port 81 we specified in the config isn't shown in the browser's url bar. We need to change the links on the menu options in the WAMPServer systemtray menu.
23. Open the "wampserver.ini" file in the WAMP installation directory. (screenshot)
24. Scroll down to the "Menu.left" settings. (screenshot)
25. Notice that the parameters show http://localhost and not http://localhost:81.
26. Change the settings to point to port 81. (screenshot) You need to do this 3 times. Once for the "localhost" menuitem, once for the "phpMyAdmin" menuitem and once for the "SQLiteManager" menuitem.
27. Exit WAMPServer. (screenshot) Make sure you completely shut down the tool!
28. Start WAMPServer. (screenshot)
29. Click the "localhost" option in the WAMPServer systemtray menu. It should point to http://localhost:81. (screenshot)
30. Open another browser window (Internet Explorer) and point it to http://localhost or http://localhost:80. The IIS startscreen should open. (screenshot)

Now both the IIS and the Apache webserver are running simultaneously. Once this is done, you can start installing and configuring AMFPHP.


Add to Bloglines - Digg This! - del.icio.us - Stumble It! - Twit This! - Technorati links - Share on Facebook - Feedburner
 

AMFPHP v1.0 getting closer: vote for the new logo.

AMFPHP No Comments »

Thanx to Patrick Minault, AMFPHP is getting really close at reaching a 1.0 version. A lot of things have been fixed/improved in this version which is now available for beta-testing.

This release also introduces a new logo. Which one is up to you to decide... Check out the poll here.

Docs are also available on the AMFPHP wiki. If you feel like contributing with an example, go ahead!

Where to go from here?
- AMFPHP homepage: http://www.amfphp.org/
- AMFPHP wiki: http://www.amfphp.org/wiki/
- Logo poll: http://www.fizzingmedia.com/poll
- Beta version: http://www.5etdemi.com/uploads/amfphpbeta.zip


Add to Bloglines - Digg This! - del.icio.us - Stumble It! - Twit This! - Technorati links - Share on Facebook - Feedburner
 

AMFPHP: methodTable automation

AMFPHP 3 Comments »

Problem: The methodTable property can be a real pain to maintain updated throughout the creation of a service class. It's a lot of coding/writing when dealing with big classes. Changes and additions to the service class require you to update the methodTable which can be very time consuming.

Solution: Automate the creation of the methodTable.

Discussion: When you look at the structure of a methodTable, you'll find the different method names, descriptions, access properties, parameters, etc.

PHP:
  1. $this->methodTablearray(
  2.   "getParkTypes" => array(
  3.     "description" => "Returns list of park types",
  4.     "access" => "remote",
  5.     "arguments" => array ("arg1") ),
  6.   "getParksList" => array(
  7.     "description" => "Shows list of parks given a park type",
  8.     "access" => "remote",
  9.     "arguments" => array ("parkType") ),
  10.   "getParkDetails" => array(
  11.     "description" => "Return details on a park give the parkname",
  12.     "access" => "remote",
  13.     "arguments" => array ("parkName")
  14.   )
  15. );

Most of these properties are allready in your code when creating a method. You write down the name of your method and add parameters as your method needs them. So adding them to your methodtable is really double work. In an ideal situation you've also added comments to your code. These can hold a description for the method and, writing a service class, also have its access defined.

PHP 5 now comes with a reflection API which lets you reverse-engineer a class. Using it, we can easily look up the properties we need to add to the methodtable. The method's name and parameters for instance, but also the comment that comes with the method. The description and access property need to be filtered out of the comment.

Putting this all together, we have the ability to create the methodTable in an automated way. After writing a class that does so, the only thing we need to do is call that class in the constructor of our service class.

Following is the source code of the MethodTable class I wrote.
In order to use it, follow these steps.

- include the class in your webservice class

PHP:
  1. require_once("MethodTable.php");

- In your constructor: call the create method and assign its return value to the methodTable property of your class.

PHP:
  1. $this->methodTable = MethodTable::create($this);

Here's the source code:

PHP:
  1. /**
  2. * MethodTable class.
  3. *
  4. * This class uses the Reflection API introduced in PHP 5 to create the methodTable
  5. * property for a service class. In order to create it, the MethodTable::create()
  6. * method must be called in the constructor of the service class.
  7. *
  8. * Example:
  9. *
  10. * require_once("MethodTable.php");
  11. *
  12. * class MyService
  13. * {
  14. * function MyService(){
  15. * $this->methodTable = MethodTable::create($this);
  16. * }
  17. * }
  18. *
  19. * The method's name and parameters will be read from the method signature.
  20. * To add the description and access param to the methodTable, you must write them
  21. * down in the comment of your method using PHPDOC comment syntax.
  22. *
  23. * The description is just plain text.
  24. * The access param uses the @access tag.
  25. *
  26. * Example:
  27. */
  28. /**
  29. * Returns the list of users.
  30. * @access remote
  31. */
  32. /**
  33. *
  34. * @author Christophe Herreman (http://www.herrodius.com)
  35. * @version 1.0
  36. * @since 12/11/2004
  37. */
  38.  
  39. class MethodTable
  40. {
  41. /**
  42. * Creates the methodTable of a service class.
  43. *
  44. * @param $serviceClass The reference to the service class.
  45. * @return Array
  46. */
  47. static public function create($serviceClass){
  48.   $className = get_class($serviceClass);
  49.   $class = new ReflectionClass($className);
  50.   $methods = $class->getMethods();
  51.   $methodTable = array();
  52.  
  53.   foreach($methods as $method){
  54.     $reflectionMethod = new ReflectionMethod($className, $method->name);
  55.     $methodComment = $method->getDocComment();
  56.  
  57.     $methodTableEntry = array();
  58.     $methodTableEntry['access'] = MethodTable::getAccess($methodComment);
  59.     $methodTableEntry['description'] = $reflectionMethod->getDocComment();
  60.     $methodTableEntry['arguments'] = MethodTable::getParameters($reflectionMethod->getParameters());
  61.  
  62.     $methodTable[$method->name] = $methodTableEntry;
  63.   }
  64.  
  65.   return $methodTable;
  66. }
  67.  
  68.  
  69.  
  70. /**
  71. * Returns the access property of a method.
  72. *
  73. * @param $methodComment The comment of the method as returned from the reflection API.
  74. * @return String
  75. */
  76. static private function getAccess($methodComment){
  77.   return MethodTable::getTagComment($methodComment, "@access");
  78. }
  79.  
  80. /**
  81. * Returns the parameters from a ReflectionParameter list.
  82. *
  83. * @param $reflectionParameter An instance of ReflectionParameter.
  84. * @return Array
  85. */
  86. static private function getParameters($reflectionParameter){
  87.   $parameters = array();
  88.  
  89.   foreach($reflectionParameter as $parameter){
  90.     $parameters[] = $parameter->getName();
  91.   }
  92.  
  93.   return $parameters;
  94. }
  95.  
  96.  
  97.  
  98. /**
  99. * Returns the comment next to a tag.
  100. *
  101. * @param $comment The comment of the method.
  102. * @param $tag The tag to return its comment from.
  103. * @return String
  104. */
  105. static private function getTagComment($comment, $tag){
  106.   $tagPosition = strpos ($comment, $tag);
  107.  
  108.   if ($tagPosition === false){
  109.     return;
  110.   }
  111.  
  112.   $comment = trim(substr($comment, $tagPosition + strlen($tag)));
  113.   $tagComment = substr($comment, 0, strpos($comment, chr(13)));
  114.  
  115.   return $tagComment;
  116. }
  117. }

Update: I added this file to the AMFPHP CVS today (10/01/2005).
The project can be viewed at http://www.sourceforge.net/projects/amfphp/


Add to Bloglines - Digg This! - del.icio.us - Stumble It! - Twit This! - Technorati links - Share on Facebook - Feedburner
 

AMFPHP: Multiple service calls

AMFPHP 1 Comment »

Problem: When you try to call 2 or more services at the same time, it's possible that AMFPHP will return an error saying that the class of the service you're using is not known to the gateway.

no class named yourService is known to the gateway

Solution: Check the setBaseClassPath() method in your gateway.php file. It should use and absolute path instead of a relative path. You can change it like this.

PHP:
  1. //before
  2. $gateway->setBaseClassPath("./services/");
  3.  
  4. //after
  5. $gateway->setBaseClassPath(realpath("services/") . "/");

After this change you should be able to call 2 or more services at the same time.


Add to Bloglines - Digg This! - del.icio.us - Stumble It! - Twit This! - Technorati links - Share on Facebook - Feedburner
 
WP Theme & Icons by N.Design Studio
Entries RSS Comments RSS Login