这里,是对Amfphp的使用,做一个工作笔记。至于Amfphp的工作原理等等,我就放在文章的末尾(在网上copy过来的)。
做过flash + mysql + php的项目的朋友,对使用amfphp就不会陌生了。因为amfphp的使用比传动的URLLoader好玩多了。
先看下效果吧:
Amfphp的使用过程:
(1),得下载Amfphp。
点击下载我整理过的 Amfphp 1.9 + Amfphp 2.2
(2),将下载下来的Amfphp包放在自己电脑的虚拟服务器上。个人比较喜欢Appserv,感觉简洁清新。虽然WampServer功能多。
(3), 检查所下的文件是否能正常运行。
amfphp1.9 可以输入以下地址:http://localhost:8080/weixin/chatroom/amfphp19/gateWAY
amfphp2.2 可以输入以下测试地址: http://localhost:8080/weixin/chatroom/amfphp22/
如果,分别出现如下图所示的提示,就是好的了。
默认的官方的amfphp会报如下图所示的错误。
这个时候,可以将那个类里边那个if语句块删除掉。如下图所示:
当配置完这些,我们就可以写Client和Server端的代码了。Client我们用AS3,Server端自然用PHP了。Server端的Php放在Amfphp下的Services目录下。
然会,Client可以去connect,call,Server端就是return的。
经过对String ,Object , Array这三种数据的测试时(FLASH发送过去的数据类型),Amfphp1.9 版本准是正常的。但Amfphp1.9以上版本都不支持Object类型的数据。
Amfphp的使用,应该也与php服务器的构建也有关系。为什么呢。前几天,发现自己做的播放器的留言板,注册,登录功能用不了了。访问时,返回的都是“NetConnection.Call.Failed”。这个时候使用的Amfphp的版本是1.9版本的。不得已,去下了一个Amfphp2.2。竟然可以用了。
下边贴出测试的代码:
AS3:
package { import flash.display.MovieClip; import flash.display.SimpleButton; import flash.text.TextField; import flash.text.TextFieldAutoSize; import flash.net.NetConnection; import flash.events.MouseEvent; import flash.net.Responder; import flash.events.NetStatusEvent; public class AmfphpFlashPizzaExample extends MovieClip { public var getPizzaBtn:SimpleButton; public var resultTxt:TextField; public var warningTxt:TextField; public var amfTypeTxt:TextField; public var dataTypeTxt:TextField; private var _amfType:int = 0; private var _dataType:int = 0; private var _strAddress:String = "TestController.test"; private var _objAddress:String = "TestController.testObject"; private var _arrAddress:String = "TestController.testArray"; private var _netConnection:NetConnection; public function AmfphpFlashPizzaExample() { resultTxt.wordWrap = true; resultTxt.multiline = true; resultTxt.autoSize = TextFieldAutoSize.LEFT; warningTxt.wordWrap = true; warningTxt.multiline = true; warningTxt.autoSize = TextFieldAutoSize.LEFT; resultTxt.text = ""; warningTxt.text = ""; amfTypeTxt.text = ""; dataTypeTxt.text = ""; amfTypeTxt.restrict = "0-1"; amfTypeTxt.maxChars = 1; dataTypeTxt.restrict = "0-2"; dataTypeTxt.maxChars = 1; getPizzaBtn.addEventListener(MouseEvent.CLICK, getPizzaBtnClickHandler); _netConnection = new NetConnection(); _netConnection.addEventListener(NetStatusEvent.NET_STATUS , netStatusHandler); } private function getPizzaBtnClickHandler(event:MouseEvent):void { if (amfTypeTxt.text == "") { warningShow("请选择amfphp的版本,输入对应的数字即可!"); stage.focus = amfTypeTxt; return; } else if(dataTypeTxt.text == "") { warningShow("请选择传递数据的类型,输入对应的数字即可!"); stage.focus = dataTypeTxt ; return; } _amfType = int(amfTypeTxt.text); _dataType = int(dataTypeTxt.text); var url:String; if (_amfType == 0) { url = "http://localhost:8080/weixin/chatroom/amfphp22/"; } else if (_amfType == 1) { url = "http://localhost:8080/weixin/chatroom/amfphp19/gateway.php"; } _netConnection.connect(url); if (_dataType ==0) { test(); } else if (_dataType ==1) { testObject(); } else if (_dataType ==2) { testArray(); } } private function warningShow(str:String):void { if(warningTxt.numLines >6) { warningTxt.text = ""; } warningTxt.appendText(str + "\n"); } private function resultShow(str:String):void { if(resultTxt.numLines >6) { resultTxt.text = ""; } resultTxt.appendText(str + "\n"); } private function netStatusHandler(e:NetStatusEvent):void { warningShow(e.info.code); } private function falseResult(result:Object) { resultShow( "失败:\n" + result.toString() ); } private function handleResult(result:Object):void { resultShow( "成功:\n" + result.toString() ); } private function test():void { var str:String = "为什么要坚持,为什么要放弃。你在微笑,我却哭了!"; _netConnection.call(_strAddress , new Responder(handleResult, falseResult) , str); } private function testObject():void { var obj:Object = {userName:"vini",sex:"boy"}; _netConnection.call(_objAddress , new Responder(handleResult, falseResult) , obj); } private function testArray():void { var arr:Array = ["vini","boy"]; _netConnection.call(_arrAddress , new Responder(handleResult, falseResult) , arr); } } }
PHP:
<?php /** * author vini * blog http://blog1.vini123.com/ * date 2014.02.17 */ header("Content-type:text/html;charset=utf-8"); class TestController { public function test($id) { if(empty($id)) { return "my web address: http://blog1.vini123.com"; } else { return $id; } } public function testObject($array) { if(empty($array)) { return; } $userName = $array['userName']; $sex = $array['sex']; return "userName:".$userName." sex:".$sex; } public function testArray($array) { if(empty($array)) { return; } $userName = $array[0]; $sex = $array[1]; return "userName:".$userName." sex:".$sex; } } ?>
Amfphp是PHP的RPC工具,它的优势体现在开源和和对最新技术的支持。它可以使PHP与下述技术无缝通信:
Flash 和 Flex Remoting
Javascript JSON 和 Ajax JSON
XML 和XML-RPC
一、什么是RPC?
远端程序调用(RPC, Remote Procedure Call) 是一种客户端与服务器端交换数据方式。我们可以调用本地对象的带有不同参数的方法,设置回 调并接受调用结果。我们不用关心发送和接收数据的实现细节。实现细节通常是抽象的, 就像我们在调用本地方法一样。
二、工作原理
客户端(Flash)与服务器端(php), 使用相同的方式描述方法调用和复杂数据。客户端序列化请求并将它发送到网关Amfphp。Amfphp再执行:
反序列化请求
找到相应的远程服务类
实例化类
执行安全检查
(使用指定参数)调用服务器端方法
序列化返回的数据
Amfphp可以正确地序列化、反序列化复杂类型数据。除了对象和数组,它还支持数据连接资源,这就意味着我们可以通过调用远程方法简单返回mysql_query,Amfphp会处理这一切。如果平台支持(目前来说,Flash Remoting 和Flex Remoting),Amfphp还可以处理循环引用和自定义数据。它也支持简单的远程调试。还有Amfphp附带一个服务浏览器,它可以在创建客户端代码前测试远程服务。Amfphp1.0.1还添加了模板,可以自动生成客户端代码。Amfphp1.9 beta更是新增了对AMF3的支持。