转自别人的文章,因为此文章对初学者很有帮助,所以转载之.
http://tb.blog.youkuaiyun.com/TrackBack.aspx?PostId=1742140
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('sayHello').send();"/>
<mx:Button x="250" y="187" label="test fault" click="myservice.getOperation('foo').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('getList').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(); 用来调用远程服务。