用AMFPHP传递自定义类
客户端与服务器使用AMFPHP通信时不仅可以直接传递数字,字符,数组等基本数据类型外,还可以传递更复杂的数据类型。这意味着你可以传递
自定义类的实例。
1.在客户端有个名为ValueObject的AS3类。
该类有id,value和description三个属性。[RemoteClass(alias="")]元标签用来注册该类,服务器就可以根据注册名来查找对应的服务器类。该元标签必须要有,但是别名alias可以任意,不过建议写成完整的限定名。
1package demo
2{
3 [Bindable]
4 [RemoteClass(alias="demo.ValueObject")]
5 public class ValueObject
6 {
7 public var id:String;
8 public var value:String;
9 [Transient]
10 public var description:String;
11
12 public function ValueObject()
13 {
14 }
15 }
16}
2.在服器端对应有一个名为ValueObject的PHP类。
该类也有有id, value和description三个属性。该类中有个属性$_explicitType用来和客户端的类对应起来。如果你使用的版本是PHP5,那么这个属性其实是多余的。
1<?php
2class ValueObject{
3 var $_explicitType="demo.ValueObject";
4
5 public $id;
6 public $value;
7 public $description;
8 function ValueObject(){
9 }
10 function init($r){
11 $keys=array_keys($r);
12 foreach($keys as $k){
13 $this->$k=$r[$k];
14 }
15 }
16}
17?>
3.在AMFPHP的services目录下建立一个服务类ClassMapService。
该类有一个方法updateMyObject,用来接受客户端的自定义类型,并且返回一个服务器端的自定义类型。遗憾的是,客户端的自定义类型没有自动转换成服务器的自定义类型,我们需要手动实现它,PHP类ValueObject有个init方法就是为了达到这个目的。
1<?php
2require_once "demo/ValueObject.php";
3class ClassMapService{
4 function updateMyObject($vo){
5 $result=new ValueObject();
6 $result->init($vo);
7 $result->id="PHP:".$result->id;
8 $result->value="PHP:".$result->value;
9 $result->description="PHP:".$result->description;
10 return $result;
11 }
12}
13?>
创建一个客户端应用程序来跟ClassMapService交互。
1<?xml version="1.0" encoding="utf-8"?>
2<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
3 layout="vertical"
4 verticalCenter="0"
5 creationComplete="init()">
6 <mx:Style>
7 Label{
8 fontSize:12px;
9 color:#000000;
10 }
11 Panel{
12 padding-left:10;
13 padding-right:10;
14 padding-bottom:5;
15 padding-top:5;
16 }
17 Label{
18 textAlign:right;
19 }
20 </mx:Style>
21 <mx:Script>
22 <![CDATA[
23 import demo.ValueObject;
24 import mx.rpc.events.ResultEvent;
25 import mx.rpc.events.FaultEvent;
26 import mx.controls.Alert;
27
28 [Bindable]
29 private var myValueObject:ValueObject=new ValueObject();
30
31 private function init():void{
32 remoteService.updateMyObject.addEventListener(ResultEvent.RESULT,
33 onUpdateResult);
34 }
35
36 private function remoteFaultHandler(event:FaultEvent):void{
37 Alert.show(event.message.toString());
38 }
39 private function buttonClickHandler():void{
40 var vo:ValueObject=new ValueObject;
41 vo.id=id_send.text;
42 vo.value=value_send.text;
43 vo.description=description_send.text;
44 remoteService.updateMyObject.send(vo);
45 }
46 private function onUpdateResult(e:ResultEvent):void{
47 myValueObject=e.result as ValueObject;
48 }
49 ]]>
50 </mx:Script>
51 <mx:RemoteObject id="remoteService"
52 destination="php_destination"
53 endpoint="http://localhost:8001/amfphp/gateway.php"
54 source="ClassMapService"
55 fault="remoteFaultHandler(event)"/>
56
57 <mx:Panel title="ValueObject to send:" width="300">
58 <mx:HBox>
59 <mx:Label text="id:" width="80"/>
60 <mx:TextInput id="id_send"/>
61 </mx:HBox>
62 <mx:HBox>
63 <mx:Label text="value:" width="80"/>
64 <mx:TextInput id="value_send"/>
65 </mx:HBox>
66 <mx:HBox>
67 <mx:Label text="description:" width="80" />
68 <mx:TextInput id="description_send"/>
69 </mx:HBox>
70 <mx:HBox>
71 <mx:Spacer width="180"/>
72 <mx:Button label="send" click="buttonClickHandler()"
73 width="60"/>
74 </mx:HBox>
75 </mx:Panel>
76
77 <mx:Panel title="ValueObject form PHP:" width="300">
78 <mx:HBox>
79 <mx:Label text="id:" width="80"/>
80 <mx:TextInput id="id_get" text="{myValueObject.id}"
81 editable="false" width="170"/>
82 </mx:HBox>
83 <mx:HBox>
84 <mx:Label text="value:" width="80"/>
85 <mx:TextInput id="value_get" text="{myValueObject.value}"
86 editable="false" width="170"/>
87 </mx:HBox>
88 <mx:HBox>
89 <mx:Label text="description:" width="80"/>
90 <mx:TextInput id="description_get"
91 text="{myValueObject.description}"
92 width="170" editable="false"/>
93 </mx:HBox>
94 </mx:Panel>
95</mx:Application>
5.运行程序。
可以发现返回的数据中id和value都包含了输入的数据,而description属性比较不同,原因是客户端的ValueObject类中还有个一个元标签[Transient]。该标签的作用就是向后台传送数据时忽略这个属性的值。如果你的需求不需要交互某个属性,就可以将它设置为[Transient]来减少数据传输。