这里,是对Amfphp的使用,做一个工作笔记。至于Amfphp的工作原理等等,我就放在文章的末尾(在网上copy过来的)。

做过flash + mysql + php的项目的朋友,对使用amfphp就不会陌生了。因为amfphp的使用比传动的URLLoader好玩多了。

先看下效果吧:

Amfphp的使用过程:

(1),得下载Amfphp。

点击下载官方 Amfphp2.2

点击下载我整理过的 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的支持。