Flex RemoteObject and AMFPHP 1.9 教程

URL:http://www.slleo.com/blog/article.asp?id=110

AMFPHP :http://amfphp.sourceforge.net/

http://www.5etdemi.com/blog/archives/2006/12/amfphp-19-beta-get-it-now/

 

 

As you probably know Patrick Mineault has recently released a new version of amfphp which starts the support for Flex2.

In this tutorial we will see how to install the new amfphp release and how to works in flex2 with the RemoteObject tag using amfphp.

本教程将学习 AMFPHP1.9 及 Flex RemoteObject标签的使用方法

1. 下载并安装 amfphp

首先下载 amfphp-1.9.beta ,然后解压到php的服务器目录下,(本例为http://localhost/amfphp2)

2. 创建你的第一个 service

在 amfphp 的 services 目录下 创建 tutorials 文件夹,我们将在这里面放 php 类文件。在 tutorials 目录下新建一个php文件: HelloWorld.php

<?php
/**
* First tutorial class
*/

class HelloWorld {   
    /**     
    * first simple method     
    * @returns a string saying 'Hello World!'     
    */

    function sayHello()    {
        return "Hello World!";
        }
    }
?>

 

注意,跟以前版本的 amfphp 不同,这里不需要 $this->methodTable 数组了,amfphp 1.9 不再利用这个数组注册远程方法。在amfphp 1.9 中 所有的方法都可以被远程访问,除非你声明的方法是 private 的(只在 php5 中支持)或者方法名是以下划线("_")开始的。
我们编写的类中还利用了javadoc 注释,可以在 amfphp browser 中看到这些注释。
跟以前的amfphp 一样,你可以在http://localhost/amfphp2/browser中查看你的services
如图所示:

你可以看到类和方法的 javadoc 注释都被显示出来.

3. 创建一个新的Flex project

首先创建一个新的Flex project,打开 project properties(右键单击project name选择properties)。
在 Project properties 对话框中选择 Flex Build path 菜单中的 Library path,并且确认 rpc.swc 文件已经添加到你的项目路径当中.
如图

接下来创建服务配置文件,在你的Flex project根目录先建立services-config.xml 文件,如下

<?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://alessandro-pc:8081/amfphp2/gateway.php" class="flex.messaging.endpoints.AMFEndpoint"/>
        </channel-definition>
    </channels>
</services-config>

 

再次打开 project properties 对话框 在 Flex Compiler 的Additional compiler arguments中添加字符串:

-services "services-config.xml"

 

如图

OK!我们已经为利用 RemoteObjects 做好了准备。

3.1 建立 mxml 文件

在 Flex project 中新建一个文件"main.mxml",

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" backgroundColor="#FFFFFF" viewSourceURL="srcview/index.html">
    <mx:Button x="170" y="157" label="sayHello" width="79"/>
    <mx:Button x="170" y="187" label="test fault"/>
    <mx:TextArea x="10" y="36" width="239" height="113" id="result_text"/>
    <mx:Label x="10" y="10" text="Result:"/>
</mx:Application>

 

我们创建了两个按钮,sayHello 按钮用来调用远程方法, testfault 按钮调用一个未定义的 php 方法以此来查看错误信息,然后这些返回结果都被显示到 TextArea 中。

下一步,继续完成这个 mxml文件。添加 RemoteObject 标签并在其中声明我们要调用的远程方法。

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" backgroundColor="#FFFFFF" viewSourceURL="srcview/index.html">
    <mx:RemoteObject id="myservice" fault="faultHandler(event)" showBusyCursor="true" source="tutorials.HelloWorld" destination="amfphp">
        <mx:method name="sayHello" 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();
                result_text.text = "code:/n" + fault.fault.faultCode + "/n/nMessage:/n" + fault.fault.faultString + "/n/nDetail:/n" + fault.fault.faultDetail;
            }

 

 

 

 

 

    <mx:Button x="250" y="157" label="sayHello" width="79" click="myservice.getOperation(&apos;sayHello&apos;).send();"/>
    <mx:Button x="250" y="187" label="test fault" click="myservice.getOperation(&apos;foo&apos;).send(); "/>
    <mx:TextArea x="10" y="36" width="319" height="113" id="result_text"/>
    <mx:Label x="10" y="10" text="Result:"/>
</mx:Application>

            private function resultHandler(evt:ResultEvent):void
            {
                result_text.text = evt.message.body.toString(); // same as: evt.result.toString();
            }
        ]]>
    </mx:Script>

 

OK,完成!

在这里要注意两点:
1. 我用 "myservice.getOperation('sayHello').send();" 来调用远程的sayHello方法,你也可以使用 "myservice.sayHello.send();" 来做同样的事情,(译者注:如果远程方法接受参数,则在send方法中传递参数,如myservice.sayHello.send(var1),多个参数之间用逗号隔开)
2. 在 resultHandler 方法中我用 evt.message.body 来访问返回信息,这里也可用 evt.result 来代替

下面解释一下 mx:RemoteObject 标签,

id="myservice" 这个不用说了
fault="faultHandler(event)", 定义错误监听器。
showBusyCursor="true", 是否在调用远程方法期间显示鼠标指针等待(忙)状态。
source="tutorials.HelloWorld" 远程service的路径
destination="amfphp" 指向 services-config.xml 文件中的 <destination>

我们已经定义了 RemoteObject 对象,接下来添加想要调用的远程方法,

在 <RemoteObject> 标签之间添加

<mx:method name="sayHello" result="resultHandler(event)" />

name 属性为远程方法名
result 属性指定接受到返回结果时触发的函数。

让我们来看一个更复杂的例子,这个例子展示了用 ArrayCollection 作为返回数据以及在Flex中使用 [RemoteClass]

在本例中,远程方法返回一个映射了类的数组(an array of mapped classes),也就是说,返回的这个数组中的每个元素都有一个AS类与之对应。

首先创建一个php类 Person.php

<?php
class Person {
    var $firstName;
    var $lastName;
    var $phone;
    var $email;
    // explicit actionscript package
    var $_explicitType = "tutorials.Person";
    }
?>

 

其中 $_explicitType 变量告诉 amfphp 这个Person类与 AS 中的 tutorials.Person 类相对应。

接下来在 amfphp/services/tutorials 目录下编写 Person 类

package tutorials
{
    [RemoteClass(alias="tutorials.Person")]
    [Bindable]
    public class Person
    {
        public var firstName:String;
        public var lastName:String;
        public var phone:String;
        public var email:String;
    }
}

 

其中
[RemoteClass(alias="tutorials.Person")]
告诉Flex 该类与一个远程对象相关联(注意,相关联的类必须有相同的结构,否则Flex 不能正确识别远程对象)

下面创建php的service文件 "PersonService.php",
这个类只有一个 getList 方法用来返回Person对象的数组

<?php
require_once "./Person.php";
class PersonService{   
    /**     
    * Get a list of people     
    * @returns An Array of Person     
    */

    function getList(){
        $people = array(
            array("Alessandro", "Crugnola", "+390332730999", "alessandro@sephiroth.it"),
            array("Patrick", "Mineault", "+1234567890", "patrick@5etdemi.com"),
        );
        $p = array();
        for($a = 0; $a <count($people); $a++){
            $person = new Person();
            $person->firstName = $people[$a][0];
            $person->lastName = $people[$a][1];
            $person->phone = $people[$a][2];
            $person->email = $people[$a][3];
            $p[] = $person;
        }
        return $p;
    }
}
?>

 

先来看一下最终的swf,然后再分析代码

3.1.1 最终 mxml 文件

完整的 main.mxml 代码如下

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" backgroundColor="#FFFFFF">
    <mx:RemoteObject id="myservice" source="tutorials.PersonService" destination="amfphp" fault="faultHandler(event)" showBusyCursor="true">
        <mx:method name="getList" result="getListHandler(event)" fault="faultHandler(event)" />
    </mx:RemoteObject>
    <mx:DataGrid x="10" y="10" width="345" id="people_list" dataProvider="{dp}" change="changeHandler(event)">
        <mx:columns>
            <mx:DataGridColumn headerText="Last name" dataField="lastName"/>
            <mx:DataGridColumn headerText="First name" dataField="firstName"/>
            <mx:DataGridColumn headerText="Telephone" dataField="phone"/>
            <mx:DataGridColumn headerText="Email" dataField="email"/>
        </mx:columns>
    </mx:DataGrid>

    <mx:Script>
        <![CDATA[
            import mx.utils.ArrayUtil;
            import tutorials.Person;
            import mx.collections.ArrayCollection;
            import mx.rpc.events.ResultEvent;
            import mx.controls.Alert;
            import mx.rpc.events.FaultEvent;

 

 

 

 

 

            [Bindable]
            private var dp:ArrayCollection;

            [Bindable]
            private var selectedPerson:Person;

            private function faultHandler(fault:FaultEvent):void
            {
                Alert.show(fault.fault.faultString, fault.fault.faultCode.toString());
            }

            private function getListHandler(evt:ResultEvent):void
            {
                dp = new ArrayCollection( ArrayUtil.toArray(evt.result) );
            }

            private function changeHandler(event:Event):void
            {
                selectedPerson = Person(DataGrid(event.target).selectedItem);
            }
        ]]>
    </mx:Script>
    <mx:Button x="290" y="357" label="get list" click="myservice.getOperation(&apos;getList&apos;).send();"/>
    <mx:Form x="10" y="174" width="345" height="175">
        <mx:FormHeading label="Selected Person" />
        <mx:FormItem label="First Name">
            <mx:TextInput id="person_first_name" text="{selectedPerson.firstName}" />
        </mx:FormItem>
        <mx:FormItem label="Last Name">
            <mx:TextInput id="person_last_name" text="{selectedPerson.lastName}" />
        </mx:FormItem>
        <mx:FormItem label="Telephone">
            <mx:TextInput id="person_phone" text="{selectedPerson.phone}" />
        </mx:FormItem>
        <mx:FormItem label="Email">
            <mx:TextInput id="person_email" text="{selectedPerson.email}" />
        </mx:FormItem>
    </mx:Form>
</mx:Application>

 

RemoteObject 标签 指向 tutorials/PersonService.php 类 并且定义一个方法来调用 PersonService.php 文件中的 getList 方法,当接到返回值后 getListHandler 方法会将返回值转化为 ArrayCollection 对象并且存储在变量 dp 中

最后 get list 按钮的 click="myservice.getOperation('getList').send(); 用来调用远程服务。

 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值