slobber

http://www.slobber.cn

[翻译]使用 Flex 2 与 AMFPHP

slobber | 06 九月, 2006 07:53

在另一篇文章 (整合 Flex 2 与 PHP) 中,我演示了如何开发一个简单的 Adobe Flex 2 应用程序去连接到一个 PHP 后台程序。如果你已经读了这篇文章,可能你会考虑有没有途径使 Flex 程序与 PHP 之间直接交换变量,而不用将它们编码为 XML?答案是肯定的,在本文中,我将展示如何实现它。

注意: 本教程是基于Flex 2 Beta 3的。我将尽快将它更新到 Flex 的零售版本。

前提

为了实现本文的大部分目标,你需要安装以下的软件和文件:

Flex Builder 2 (包含 SDK)

AMFPHP 1.1

PHP (安装在本地的一个服务器上)


预备知识

PHP 中级知识。

开始

如果你打算去构建一个中型或者大型的企业级应用,你需要使用 Adobe Flex Data Services 2 (缩写为 FDS)。通过高性能的数据传输,基于消息的发布订阅机制,以及更多的特性,FDS 实现了数据交互的简单高效。而 AMFPHP 是仅实现了一个 FDS 功能的一个小的子集。如果工作于一个大型公司,在数据交换层上,你可能需要考虑下 FDS。

实现本教程任务的关键是一个称为 AMFPHP 的项目。这个项目最开始是由 Wolfgang Hamann 开始的。项目团队逐渐成长,现在大约有五、六个开发者。由于他们的努力工作,Flex 社区现在有了一个从 Flex 前台到 PHP 后台的桥梁。

如果环境还没准备好,你需要去下载安装 Flex 2 and AMFPHP v. 1.1 (详细信息请阅读帮助文件)。当然,如果你没有读过我的另一篇文章《整合 Flex 2 与 PHP》,也建议你去看看。

本教程中你建立的这个例子将示范如何使用 Flex 来显示一个数据库中的记录。你不需要去插入或更新任何记录,仅仅就是给用户显示数据。使用的是和之前文章中的例子相同的数据库,如果之前你已经建立过了,用那个也没有问题。没有建立数据库的话,建立如下的 MySQL 表:

CREATE TABLE 'users' (
  'userid' int(10) unsigned NOT NULL auto_increment,
  'username' varchar(255) collate latin1_general_ci NOT NULL,
  'emailaddress' varchar(255) collate latin1_general_ci NOT NULL,
  PRIMARY KEY  ('userid')
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci AUTO_INCREMENT=3 ;

在数据库中添加几行数据。字段名说明了它应该填的内容。别忘了,这个例子只是从数据库中显示数据,如果你不添加些,你就没什么可显示的了。可以使用 PHPMyAdmin 来往表里添加数据。

下面是一个新的 PHP 代码。 将这部分代码以 sample.php 文件名保存在你的 AMFPHP 安装位置的 services 文件夹中:

<?php
// Create new service for PHP Remoting as Class
class sample
{
    function sample () 
    {
        // Define the methodTable for this class in the constructor
        $this->methodTable = array(
            "getUsers" => array(
                "description" => "Return a list of users",
                "access" => "remote"

            )
        );
    }

    function getUsers () {
        $mysql = mysql_connect(localhost, "username", "password");
        
        mysql_select_db( "sample" );
        
        //return a list of all the users
        $Query = "SELECT * from users";
        $Result = mysql_query( $Query );
        while ($row = mysql_fetch_object($Result)) {
               $ArrayOfUsers[] = $row;
        }
        return( $ArrayOfUsers );
    }
}
?>

如果你对 AMFPHP 比较熟悉,这段代码是不是很简单?

类名要和文件名相同。在这个例子中,文件名为 sample.php,所以类名为 sample。当一个类加载时,它运行 sample() 函数 (类总是通过调用和类名相同的函数来进行初始化),这个函数中定义了 AMFPHP 可以使用的方法。这个例子中,只有一个方法: getUsers,如同描述中所写的,它返回一个用户信息列表。在这个函数中,你可以看到它真的相当简单: 连接到一个 MySQL 数据库,获得所有用户,最后返回一个包含用户信息的数组。

前台应用程序

现在让我们看看前台的应用程序,sample.mxml,最终以 Flash 的形式显示。令人惊奇的是,它仅仅需要大约 50 行代码。

<?xml version="1.0" encoding="utf-8"?>

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" xmlns="*" creationComplete="initApplication()">
    <mx:DataGrid dataProvider="{dataProvider}">
        <mx:columns>
            <mx:DataGridColumn headerText="Userid" dataField="userid"/>

            <mx:DataGridColumn headerText="User Name" dataField="username"/>
            <mx:DataGridColumn headerText="User Name" dataField="emailaddress"/>
        </mx:columns>

    </mx:DataGrid>
    <mx:Script>
        <![CDATA[
            [Bindable]
            public var dataProvider:Array;

            import flash.net.Responder;
 
            public var gateway : RemotingConnection;

            public function initApplication()
            {
                gateway = new RemotingConnection( "http://localhost/flex/php/gateway.php" );
                gateway.call( "sample.getUsers", new Responder(onResult, onFault));
            }

            public function onResult( result : Array ) : void
            {
            dataProvider = result;
            }


            public function onFault( fault : String ) : void
            {
                trace( fault );
            }
        ]]>
    </mx:Script>

</mx:Application>

第一行,<?xml version="1.0" encoding="utf-8"?>,声明这是一个 XML 文档。所有的 Flex 应用程序第一行都是这句话。

第二行声明这是一个应用程序,并且在 Flash 加载 (creationComplete) 后运行 initApplication() 函数:

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"  xmlns="*" creationComplete="initApplication()">

下一部分是一个用来显示用户列表的 DataGrid 组件:

<mx:DataGrid dataProvider="{PHPData}">
<mx:columns>
        <mx:DataGridColumn headerText="Userid" dataField="userid"/>

        <mx:DataGridColumn headerText="User Name" dataField="username"/>
        <mx:DataGridColumn headerText="User Email" dataField="emailaddress"/>
    </mx:columns>

</mx:DataGrid>

不像在文章《整合 Flex 2 与 PHP》中的 DataGrid 组件,这个组件显示数据库中的全部三列信息。注意,列名元素必须和 MySQL 表中的字段名匹配。

以下的部分是一系列 ActionScript 指令:

<mx:Script>

    <![CDATA[
        [Bindable]
            public var PHPData:Array;

        import flash.net.Responder;
 
        public var gateway : RemotingConnection;

        public function initApplication()
        {
            gateway = new RemotingConnection( "http://localhost/flex/php/gateway.php" );
            gateway.call( "sample.getUsers", new Responder(onResult, onFault));
        }

        public function onResult( result : Array ) : void
        {
            PHPData = result;
        }


        public function onFault( fault : String ) : void
        {
            trace( fault );
        }
        ]]>
</mx:Script>

下面说明这部分的功能。以下几行声明了一个数组: PHPData,它可以绑定到 ([Bindable]) MXML 对象上:

[Bindable]
public var PHPData:Array;

在本例中,PHPData 数组作为 dataProvider 被绑定到 <mx:DataGrid>。这意味着 DataGrid 从 PHPData 变量中获得数据;本例中,它是一个 PHP 对象数组

以下的代码片断对于 Flex 调用 AMFPHP 是必须的:


import flash.net.Responder;
 
public var gateway : RemotingConnection;

public function initApplication() : void
{
    gateway = new RemotingConnection( "http://localhost/flex/php/gateway.php" );
    gateway.call( "sample.getUsers", new Responder(onResult, onFault));
}

public function onResult( result : Array ) : void
{
    PHPData = result;
}


public function onFault( fault : String ) : void
{
    trace( fault );
}

首先,代码导入 flash.net.Responder 包,里面包含用来进行远程访问的类。实际上,Flex 会在你声明一个新 Responser 时自动导入这个包。我在这写上它仅仅是为了说明它的使用。

接下来,代码定义了一个变量——gateway,是一个 RemotingConnection 数据类型。其实你已经知道这个 RemotingConnection 数据类型了——在 Flex 应用程序的目录中有个叫 RemotingConnection.as 的文件,其中包含以下代码:

package 
{
    import flash.net.NetConnection;
    import flash.net.ObjectEncoding;

    public class RemotingConnection extends NetConnection
    {
        public function RemotingConnection( sURL:String )
        {
            objectEncoding = ObjectEncoding.AMF0;
            if (sURL) connect( sURL );
        }
        
        public function AppendToGatewayUrl( s : String ) : void
        {
            //
        }
    }
}

注意类名要和文件名相同。本例中,你在 NetConnection 包中添加一个新方法——AppendToGatewayUrl.

下一步,写了一个函数,initApplication:

public function initApplication()
{
    gateway = new RemotingConnection( "http://localhost/flex/php/gateway.php" );
    gateway.call( "sample.getUsers", new Responder(onResult, onFault));
}

当你的程序加载后首先运行 initApplication 函数。通过变量 gateway 建立一个新连接到 AMFPHP 中的 gateway.php 脚本。gateway.php 文件按照代码中的位置设置。然后,在下一行中调用 sample 类中的函数 getUsers (sample.getUsers)。响应时,你运行如下两个函数中的一个: 如果一切正常运行 onResult,如果遇到错误运行 onFault。

下面的一行将变量 result 赋值给变量 PHPData,变量 result 是由 AMFPHP 传送给 ActionScript 的:

public function onResult( result : Array ) : void

{
    PHPData = result;
}

这是当你运行 MySQL 查询 ($ArrayOfUsers) 后返回的 PHP 对象数组。AMFPHP 已经为你将 PHP 对象数组翻译为 ActionScript 对象数组。很酷,是吧?

现在看看最后一行:

public function onFault( fault : String ) : void
{
    trace( fault );
}

本例中,如果发生错误,此处就是用来处理错误的,可能给用户显示一条信息。在这个例子中,就是简单的 trace 一下故障变量,当你在调试模式下运行 Flex 应用程序时,trace 是非常有用的函数。

也许对于初学者还是有些复杂,让我们清楚地说明下各个文件的位置。你一共建立了三个文件,另外你下载及使用的 AMFPHP 有一堆文件。

  • å°† Flex 项目文件 sample.mxml å’Œ RemotingConnection.as 放到同一个文件夹。
  • å°† PHP 文件,例如 AMFPHP 中的 actions、adapters、app、browser 等文件夹,放在 services 文件夹中。
  • å°† PHP 文件从 AMFPHP 目录放到你的网络服务器的根目录。
  • å°† sample.php 放到 AMFPHP 项目的 services 目录中。

这样,你编写了一个非常简单的应用程序,它演示了如何从 Flex 前台连接到 PHP 后台的方法。请联系我,告诉我你的新发现。

接下来的方向

我要感谢 Patrick Mineault 和 Jess Warden 对我的帮助,他们提供了我在这个教程中使用的软件,并且解答了我的一些问题使我得以开始这篇教程。如果你对使用 PHP 和 Flex (或者 Flash) 感兴趣,可以去访问以下的博客:

关于作者

Mike Potter 进行开发网站和网络应用程序已经超过八年了。在 PHP 设计方面,他有丰富的经验,构建过加拿大最大的业余体育组织网站:加拿大冰壶协会。开发这个网站之后,他去 OEone 工作,在那他帮助实现了一个在 Mozilla 网络浏览器中允许的基于 Linux 的桌面系统。他帮助开放那个桌面系统的日历程序的源代码,之后在 Mozilla 日历项目中工作了一年。Mike 在 2005 年加入 Adobe,现在作为开源软件和网络开发的传道者工作于开发人员交流部门。

最新回复

发表评论

 authimage
 
Accessible and Valid XHTML 1.0 Strict and CSS
Powered by LifeType - Design by BalearWeb