Amfphp 1.9 beta - Get it now

Posted on Saturday 16 December 2006

* Update: a second beta is now available here *

Well I've been working on the new version of amfphp for about a week now, and it's ready for a test-drive. I've had the feedback I needed from the alpha, and I am fairly convinced this new version works like a charm. You can download it here. This time it should work with PHP4.

What's new

  • AMF3 support, including RemoteObject. You can finally use it in Flex 2.
  • JSON support. In addition to gateway.php, there is now json.php which allows you to use your services in JSON as well Flash. Two examples here: MochiKit and Spry. XML-RPC also supported. Details below.
  • A new Service Browser. Try it live here. Notice that the samples.MochiTest service is the same one used by the JSON sample, so you can verify for yourself that indeed it works both in AMF and in JSON mode. Fuggawesome.
  • The end of $this->methodTable. From now on, $this->methodTable is ignored. All methods are remotely accessible by default. Details below.

Getting it running in Flex 2

This has nothing to do with amfphp per-say, but to get RemoteObject running, you need to configure the Flex compiler by doing the following:

  • In you source folder, create the services-config.xml file. Paste this in (You can change the uri of the endpoint if you wish):

<?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="amfphp">
                <channels>
                    <channel ref="my-amfphp"/>
                </channels>
                <properties>
                    <source>*</source>
                </properties>
            </destination>
        </service>
    </services>

    <channels>
        <channel-definition id="my-amfphp" class="mx.messaging.channels.AMFChannel">
            <endpoint uri="http://localhost/amfphp/gateway.php" class="flex.messaging.endpoints.AMFEndpoint"/>
        </channel-definition>
    </channels>
</services-config>
 

  • Right-click your project in Flex Builder 2 in the Navigator, go to Flex Compiler, and add -services "services-config.xml" to Additional compiler arguments. Press OK.
  • You can override the gateway location in RemoteObject if you want by setting the endpoint property in the MXML. This is good as you have to clean your project in order for changes to services-config.xml to be caught by the compiler, which means rebuild from scratch. Also, that XML file is painful to look at compared to good old mxml.

About JSON support

Before people start crying about feature bloat, let me put things in perspective. There are two files in the json directory, totaling 5k. That's it. Amfphp has had a JSON parser in it since amfphp 1.2 (the PEAR version, for the service browser), so it didn't need a lot to get it to support JSON.

How it works: To make a request, call /json.php/com.mypackage.MyClass.myMethod/arg1/arg2 (and so on for other arguments). arg1 or arg2 can be strings with or without surrounding quotes, numbers, arrays or objects in JSON format. The myMethod method will be called in class MyClass in the services/com/mypackage folder, with arguments arg1 and arg2 (decoded). Then you can send back whatever you want and it will serialize automatically. If you use NetDebug::trace it will add that in a comment before the actual data. It will serialize recordsets like amfphp does by creating an object which has two keys: "columns" (an array) and "rows" (an array of arrays). You can then easily manipulate this data in JavaScript. If you want to use it with Spry, you can see my example jsondataset.js file which does all the job for you (if anybody at Adobe is listening, you can add it or something along the lines of it in the next version of Spry). If you add POST data to your request it will be deserialized as JSON and you will receive it as the last argument to your method.

Now, why would you use JSON in amfphp instead of, say, library X? Well:

  • You can use the same service in JavaScript AND Flash.
  • You can use the service browser to test your classes.
  • Most PHP Ajax libraries mix and match code and presentation in a fashion which makes me sick to the stomach. Amfphp provides a clean way to organize your code and dispatch calls.
  • It will use PHP's json_* functions if it finds them (built-in in PHP 5.2, available as an extension in older versions), or will revert to PEAR JSON if it doesn't, so you have an easy upgrade path if you need more speed.
  • It will serialize recordsets directly.
  • It doesn't have any JavaScript dependencies, so you can use with whatever toolkit you like (prototype, MochiKit, Spry, you name it).

(I would also say personally that it's entirely fuggawesome, but I think I've already made a pretty strong argument for that).

About XML-RPC support

XML-RPC is similar to SOAP except that it doesn't rely on those godforsaken .wsdl files. It's a lot more verbose that JSON-RPC or AMF-RPC but it's readable, and if you enable gzip compression it's not that bad as far as size goes. It could be useful if you want to share your awesome new service with XML-heads. It requires the xmlrpc extension to be installed. Just call xmlrpc.php through POST and it should work like you expect it to (that is, it uses the same kind of mapping as the "normal" amfphp does, it'll serialize recordsets, etc.)

About the new Service Browser

The new Service Browser rocks. Try it out here if you like. A thing I want to point out is that if you have a fatal error in your service file, it will catch it and not NetConnection.Call.BadVersion on you. That's because it's writing and reading its own amf packets and will do some sanity checking (try calling HelloWorld.triggerAFatalError). It will also show NetDebug::trace output in the "trace" tab, despite this not being supported by RemoteObject for some reason (again, because it's reading and writing it's own amf packets). That being said, the non-test calls are routed through the regular RemoteObject so if there is any discrepancy between my code and the one the player outputs it should be caught early.

If your service uses session you WILL need to use the service browser in a web browser that accepts cookies as I have yet to figure out how to make it honor AppendToGatewayUrl headers.

I need you help with the service browser. I want it to be better, but I don't have that much time, so here's my laundry list, the source is right here, please comment if you're interested in taking on these items.

  • Clean up the current spaghetti-code mess
  • Add Code Generation
  • Make util/MethodTable smarter so it will catch more comments related to a function
  • Show all JavaDoc tags in the service description, not just the param and returns tags.
  • Format HTML properly when encountered
  • Make the Tree view work for any and all objects
  • Make the DataGrid view work when a RecordSet is nested inside something else
  • Make it look better

About $this->methodTable

It's gone for good. The single most annoying thing about amfphp has now been removed. All methods in classes of the service folder are now remotely callable by default. You can make a method non-remote by starting it with an underscore (same as with CakePHP), or by making it private or protected (PHP5 only). You can stop a method from being called (for example, for lack of proper credentials) by creating a beforeFilter($methodName) method and returning false to stop the call (same as with CakePHP, again).

_authenticate support has been temporarily removed (can be done with beforeFilter now), and pageable recordsets have been temporarily disabled as well. New methodologies will be introduced for these features in amfphp 2.0 final.

About recordsets

Currently, only mysql recordsets work. Since amfphp serializes about a dozen different recordset types normally, and I have made a bunch of changes, I will wait until everything is stable before re-enabling the other recordset types. If you need support for those types now, you can rewrite core/shared/adapters/dbnameAdapter.php, using mysqlAdapter.php as a guide.

Acknowledgments

This release would not have been possible without all the hard work of several people who I have borrowed code and ideas from. Big thanks to Zoltan of Fluorine (AMF3 code), Evert of SabreAMF (RemoteObject code), Karl of Charles debugging proxy (debugging needs), Kevin of ServiceCapture (first reverse-engineered AMF3), Aral Balkan for his suggestion of a Flex-based service browser, Renaun Erickson for his PHP4 array_search patch and VO handling code, the people at CakePHP for some of the JSON code, the people at PEAR::JSON, and Christophe Herreman for his original MethodTable class which is now the core of the Service Browser component.


WordPress database error: [Can't open file: 'wp_comments.MYD'. (errno: 145)]
SELECT * FROM wp_comments WHERE comment_post_ID = '229' AND comment_approved = '1' ORDER BY comment_date

No comments have been added to this post yet.

Leave a comment




Your e-mail address is never displayed. If you run into issues with SpamKarma blocking you, email me at $patrick->5etdemi(com)


RSS feed for comments on this post | TrackBack URI