
|[_RemoteClass_ Object|http://livedocs.adobe.com/flex/2/docs/wwhelp/wwhimpl/common/html/wwhelp.htm?context=LiveDocs_Parts&file=00001187.html]|class mapped object|
|[date|http://livedocs.adobe.com/flex/2/langref/Date.html]|[DateTime|http://www.php.net/manual/en/function.date-create.php]|
|[mx.collections.ArrayCollection|http://livedocs.adobe.com/flex/2/langref/mx/collections/ArrayCollection.html]|[object|http://www.php.net/manual/en/reserved.classes.php]|
||PHP to ActionScript mapping||
||PHP||ActionScript||
|[null|http://us.php.net/manual/en/language.types.null.php]|[null|http://livedocs.adobe.com/flex/2/langref/statements.html#null]|
|[boolean|http://us.php.net/manual/en/language.types.boolean.php]|[boolean|http://livedocs.adobe.com/flex/2/langref/package.html#Boolean()]|
|[string|http://us.php.net/manual/en/language.types.string.php]|[string|http://livedocs.adobe.com/flex/2/langref/package.html#String()]|
|[DomDocument|http://us3.php.net/manual/en/class.domdocument.php]|[xml|http://livedocs.adobe.com/flex/2/langref/package.html#XML()]|
|[DateTime|http://www.php.net/manual/en/function.date-create.php]|[date|http://livedocs.adobe.com/flex/2/langref/Date.html]|
|[float|http://us.php.net/float]|[number|http://livedocs.adobe.com/flex/2/langref/package.html#Number()]|
|[integer|http://us.php.net/manual/en/language.types.integer.php]|[number|http://livedocs.adobe.com/flex/2/langref/package.html#Number()]|
|[array|http://us.php.net/manual/en/language.types.array.php]|[array|http://livedocs.adobe.com/flex/2/langref/package.html#Array()]|
|Associative Array w/ mix of keys|[Object|http://livedocs.adobe.com/flex/2/langref/package.html#Object()]|
|Associative Array w/ Numeric index of keys|[Array|http://livedocs.adobe.com/flex/2/langref/package.html#Array()]|
|[[object|http://www.php.net/manual/en/reserved.classes.php]|[object|http://livedocs.adobe.com/flex/2/langref/package.html#Object()]|
|[_RemoteClass_ Zend_Amf_Value_TypedObject|http://livedocs.adobe.com/flex/2/docs/wwhelp/wwhimpl/common/html/wwhelp.htm?context=LiveDocs_Parts&file=00001187.html]|typed object|
|Zend_Amf_Value_ByteArray|[flash.utils.ByteArray |http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/utils/ByteArray.html]
|Zend_Amf_Value_ArrayCollection|[mx.collections.ArrayCollection|http://livedocs.adobe.com/flex/2/langref/mx/collections/ArrayCollection.html]|
h3.Example of serialization/deserialization
The following is used to showcase passing an array to and from the Zend Framework. It is not a tutorial for how data from ActionScript we have a RemoteObject called myservice that's endpoint is Zend_Amf (use case below). We are calling a remote method called sortArray which takes an array as an argument.
{code}
// ActionScript
private var myArray:Array;
//~~~
private function callSortArray():void {
myArray = new Array("b", "a", "d","c");
myservice.sortArray(myArray);
}
{code}
In PHP we create a simple class that just re-orders the array and return an array. This is showing how the data types are handled. Zend_AMF hides all serialization from the end user on both sides. This allows the client and server application developers to leverage all of there existing capabilities and does not inject a new set of rules to make the php class Zend_AMF specific.
{code}
class ArrayUtil {
public function sortArray($newArray) {
sort($newArray);
return $newArray;
}
}
?>
{code}
The result is returned to ActionScript through its callback handler. There is no type handling the method just receives an array.
{code}
// ActionScript
private function sortArrayHandler(event:ResultEvent):void {
myArray = event.result;
trace(myArray.length); // 4
trace(myArray); // Output: a,b,c,d
}
{code}
h3.Handling Exceptions via Faults
Zend_Amf_Server catches Exceptions generated by a dispatched method, and generates an Zend_Amf_Server_Fault response when such an exception is caught. The exception messages and codes are not used in a fault response which is return to the client as a Fault event. These events will be logged only as information about the error could potentially compromise the application.
{zone-data}
{zone-data:class-list}
* Zend_Amf_Fault
* Zend_Amf_Request
* Zend_Amf_Request_Http
* Zend_Amf_Response
* Zend_Amf_Server
* Zend_Amf_Server_Exception
* Zend_Amf_Server_Fault
* Zend_Amf_Util
* Zend_Amf_Util_BinaryStream
* Zend_Amf_Value
* Zend_Amf_Value_ArrayCollection
* Zend_Amf_Value_ByteArray
* Zend_Amf_Value_TypedObject
* Zend_Amf_Value_ITypedObject
* Zend_Amf_Value_Message
* Zend_Amf_Value_Message_AcknowledgeMessage
* Zend_Amf_Value_Message_CommandMessage
* Zend_Amf_Value_Message_ErrorMessage
* Zend_Amf_Value_Message_RemotingMessage
* Zend_Amf_Parse
* Zend_Amf_Parse_Number
* Zend_Amf_Parse_Boolean
* Zend_Amf_Parse_String
* Zend_Amf_Parse_Object
* Zend_Amf_Parse_Null
* Zend_Amf_Parse_Undefined
* Zend_Amf_Parse_Refrence
* Zend_Amf_Parse_MixedArray
* Zend_Amf_Parse_Array
* Zend_Amf_Parse_Date
* Zend_Amf_Parse_Xml
* Zend_Amf_Parse_TypedObject
* Zend_Amf_Parse_Amf3_Integer
* Zend_Amf_Parse_Amf3_Date
* Zend_Amf_Parse_Amf3_String
* Zend_Amf_Parse_Amf3_Xml
* Zend_Amf_Parse_Amf3_ByteArray
* Zend_Amf_Parse_Amf3_Array
* Zend_Amf_Parse_Amf3_Object
{zone-data}
{zone-data:use-cases}
Getting started with Zend_Amf requires a basic installation of the Zend Framework on your server. Review the getting started guide for setting up your webserver. http://framework.zend.com/manual/en/introduction.installation.html
For a reference we are going to assume that your web server folder is setup in the following manor.
/data/
/public or /htdocs or /www /include/
/library/Zend/Amf/
/include/
_Where the Zend Framework is placed into the /library directory_
You will then need to create an index.php where all of your AMF calls will be handled. For this example all calls to the Zend Framework are from an application running in the flash player. If you are using Flash and html views together you will need to create a gateway file independent of the index.php page that has the same content.
The following is an example of your index.php file that will act as the endpoint for AMF calls. The following code instantiates the Zend_Amf server class. You then tell the class what remote services or names spaces that you want to allow your Flasher Player application to access. In the following example we have specified the HelloWorld class to be added into the Zend_Amf server to be remotely exposed. With your webserver properly configured the following file should be accessible at http://localhost/index.php
{code}
require_once 'Zend/Amf/Server.php';
require_once 'include/services/HelloWorld.php'
// Instantiate server
$server = new Zend_Amf_Server();
$server->setClass('HelloWorld');
// Handle request
$server->handle();
{code}
There is nothing special to Zend_Amf for creating service classes. It is just a standard PHP class file. The following class HelloWorld has one public function say which takes in a string and returns a string that has been concatenated with today's date. Note that private methods will not be exposed through Zend_Amf. Place the file into /include/services/HelloWorld.php
{code}
class HelloWorld {
/**
* Say hello!
*
* @param string $sMessage
* @return string
**/
public function say($sMessage) {
$date = getdate();
return 'You said: ' . $sMessage .' on '.$date[weekday];
}
}
?>
{code}
We will use Flex to connect to the application. The following code creates a RemoteObject endpoint that terminates at http://localhost/ which is where our following example is located. The code creates a simple input field and a button that send that data to the server on the click event.
Start with a new flex project from inside of flex builder and call it zend. You should now have an open project called product in your Navigator window. Right click on the zend project name and select 'properties'. In the Project properties dialog go into 'Flex Build Path' menu, 'Library path' tab and be sure the 'rpc.swc' file is added to your projects path. Press Ok to close the window.
We now need to tell Flex which services configuration file to use for inspecting our remote methods. For this reason create a new 'services-config.xml' file into your Flex project root folder. To do this right click on the zend project folder and select 'new' 'File' which will popup a new window. Select the product folder and then name the file 'services-config.xml' and press finish.
Flex has created the new services-config.xml and has it open. Use the following example text for your services-config.xml file. Make sure that you update your endpoint to match that of your testing server. Make sure you save the file.
{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/" class="flex.messaging.endpoints.AMFEndpoint"/>
</channel-definition>
</channels>
</services-config>
{code}
Now open your project properties panel again by right clicking on the project folder from your Navigator and selecting properties. From the properties popup select 'Flex Compiler' and add the string: -services "services-config.xml". Press Apply then OK to return to update the option. What you have just done is told the Flex compiler to look to the services-config.xml file for runtime variables that will be used by the RemotingService class.
The following code is just in MXML and you can add it to your default application. Run the code and you will remoting with the Zend Framework via Zend_Amf.
{code}
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:RemoteObject id="myservice" fault="faultHandler(event)" showBusyCursor="true" source="HelloWorld" destination="zend">
<mx:method name="say" result="resultHandler(event)" />
</mx:RemoteObject>
<mx:Script>
<![CDATA[
import mx.managers.CursorManager;
import mx.rpc.events.ResultEvent;
import mx.rpc.events.FaultEvent;
private function faultHandler(fault:FaultEvent):void
{
CursorManager.removeBusyCursor();
trace("code:\n" + fault.fault.faultCode + "\n\nMessage:\n" + fault.fault.faultString + "\n\nDetail:\n" + fault.fault.faultDetail);
}
private function resultHandler(event:ResultEvent):void
{
response_txt.text = event.result.toString();
}
]]>
</mx:Script>
<mx:TextInput x="10" y="20" id="server_txt" text="Connect to Zend Amf" />
<mx:TextArea x="10" y="50" id="response_txt" width="278"/>
<mx:Button x="178" y="20" label="Send to Server" id="send_btn" click="myservice.say(server_txt.text)"/>
</mx:Application>
{code}
It should be noted that additional examples should be constructed that will properly utilize an MVC architecture and folder names. A good database example would be a great next step.
{zone-data}
{zone-data:skeletons}
{zone-data}
{zone-template-instance}