PHP作为Flex程序的数据源

来源:互联网 发布:windows快捷键 编辑:程序博客网 时间:2024/06/09 21:13

 

Adobe Flash Builder 4 简体中文正式版 Windows版点击下载:http://g.csdn.net/5134151

Adobe Flash Builder 4 简体中文正式版 Mac版点击下载:http://g.csdn.net/5134152

Adobe 在线课堂:http://adobev.csdn.net/zx/index.html
Adobe平台技术峰会课程视频:http://adobev.csdn.net/

现在,很多人似乎从网页开发转到了构建RIA-s。但是我们也很轻易就看到新的客户端技术的紧急问题所在,随着诸如FlexSilverligth或者JavaFX等名字越来越频繁地出现在网页开发里,这种向着RIAs转换的趋势也在影响着服务器端的程序员。

 

PHP的角色变化

如果你有一个RIA作为用户交互界面的话,服务器端将不再需要把视觉表现部分和数据混在一起了。这意味着PHP程序员不再需要头疼用于风格化的数据,诸如携带着表格啊,网页元素还有大量的标签等等信息(的数据)。他们只需要做的一件事就是以某种便于使用的格式发送这些数据,而凑巧XML是被Flex所支持的。我们来看看用于开展FlexPHP交流的一些代码。服务端的代码需要从数据库获取数据,用XML标签包装之,反之的话就是剥离成代码反馈给它(数据库)。

除了这个类以外有个文件包含了所有数据库的配置信息(config.php)服务器还有一个简易文件来调用getAllXML函数。

并且返回结果:

这是基本的PHP了,让我们转向Flex。假设我们构建了一个可以提供书籍列表的服务器,现在来连接它并用好看的表格来显示。我把代码黏贴出来并解释下都发生了什么。

 

我们在里面有两个组件。第一个是HTTPService,众所周知是用来通过HTTP方式下载数据的东东。你可能奇怪为什么当我试图得到XML的时候会把“e4x”当做结果。E4X是“ECMAScript for XML”的简称,意味着我们想把数据当成本地Flex XML类,而那也将更容易操作。第二个就是DataGrid,它有几行,它“关注”的是任何出现在数据sampleService中的书。当程序创建完毕时,sampleService发送调用到我们的服务器。结果就是一个小RIA,像这样:

这对于只有几行的代码来说还行,不过我们可以让它更好些。

数据格式——XMLAMF

XML真的不错,易于使用,易于创建,你可以用任何编程语言解析它,甚至可以被阅读。不过有得必有失,当你必须考虑所传递信息本身的体积的时候,XML就不是一个好的数据格式了;如果你的软件里有两部分之间的沟通可以通过非文本数据来进行的话,标签包裹的方式就显得累赘。幸运的是FlexPHP均支持一种叫做AMF的二进制数据格式。用它来发送数据的高效率让人震撼。眼见为实,James Ward创建了一个用不同的数据格式发送大型数据来测试带宽的应用,你可以在这里查看结果。最爽的是它的易于使用,因为1.7版本的Zend框架包含了zend_amf,可以让你随时发送AMF。要运行以下例子你需要在服务器上安装它,如果没有的话到Zend网站上下载。

 

XMLAMF

 

首先改变所有之前用的XML代码,并用对象代替它。它是一个直译的过程,你可以对比以下的BookDAO和我们之前使用的那个看是不是没多少改变。

 

随着这个改变我们完成了一半。现在我们需要用输出我们AMF服务器的某些东东取代sample1.php

 

我希望代码里的注释足够解释当前状况。如果你的浏览器打开这个文件并且一切正常的话你应该可以看到写着"Zend Amf Endpoint"的空页面。

我们的下一个任务就是修改我们的Flex小程序以获得从新建服务器过来的数据。这个修改简单到不易察觉。我们看看新的源码。

数据表格没有变,因为我们想用同样方式显示数据。解释细节超出了本文讨论范围,不过你需要做以下事情。

1.        定义一个AMFChannel指向可以掌握requests的文件。

2.        把它放进ChannelSet,因为RemoteObject不会把单独的channels当做参数。

3.        建立一个RemoteObject代替HTTPService(此处原文可能有笔误”HTTPSerivce)

 

如果你经常使用GET或者POST参数的话,RemoteObject是一个奇怪的东西。它为给定的对象创建了一种桥梁,在这个案例中叫“BookDAO”,并

允许你调用它的函数,就好像它是本地文件一样。我们不把url直接给它,取而代之的是我们创建的chanelSet。最终目的是设置到“zend”,如果你在用zend_amf的话。所以这边我们有RemoteObject,另一边PHP就是BookDAO.php。“源”定义了一个类来接桥,而且方法指向类里面单独的一个函数(btw,你在那儿可以有多于一个的mx:Method标签)。一个简单的发展流程图如下:

 

你可能刚好注意到我们的getAll方法在取回结果的时候做了些事情——它把从源获取的数据制成分页的数据表格,这让结果和之前一样却可以帮我们节省了很多带宽。

节省带宽只是你使用AMF的第一个好处而已,同时你还可以看到你的PHP编程不再臃肿和复杂。

 

组织数据模型

 

好的,现在我们开始节省带宽之旅。除了节省用户时间不说,使用AMF也可以节省我们自己的时间。虽然PHPActionscript都允许你不经特定类就通过连线发送数据,就如之前我们在例子中所做的那样,可是这并不是最好的方式。说这些我主要是想指出还可以让数据进行某种收缩。要记得大部分实际情况中Flex应用的作者和后端的作者并不是同一个人,所以最好在从服务器收到数据之前预先知道它长什么样。要实现这些(预览)的话,就要在两边创建拥有一样域的类,叫做Value Objects(或者Data Transfer Objects)。但是用AMF的话还有额外的好处——我们建立了映射使得数据可以自动在PHPActionscript对象间协同翻译,不需要我们添加任何序列化和反序列化的代码。瞧瞧我们的value object

 

这需要一些旁注。首先AS变量需要声明而在PHP不必。PHP的问题是你不能明确的定义变量的类型,所以当试图定义一个数据协议的时候,在注释里留下PHP变量类型是有用的。另一个不同是AS类型声明之上的RemoteClass元数据标签。它是定义计划的第一部分,说明标记为“BookVO”来自PHP的对象应该被翻译给这个类。PHP里你不用标签,而应该在sampleamf.php增加一个单独的行:

$server->setClassMap("BookVO","BookVO");

而当你在PHP想用新建的类的话,你也需要改变rowToBook函数,所以它的第一行变成:

$book = new BookVO();

现在你应该从getAll获得BookVO的一个数组作为结果。剩下的唯一一件事就是把Actionscript对应部分导入Flex project里。因为Flex编译器里不包括用在已编译swf里的类,加强它最简便的方法就是在主文件里增加一个单独无用的变量。

 

private varbookDummy:BookVO;

 

这些在大部分时间里都不是必须的,因为任何一个常规项目里你都会在某些地方用到那些类,但知道这些可能会帮你找到计划失败的原因。

 

惰性装载

 

最后要担心的是发送数据的量,当使用AMF会比XML小得多的时候,它将会成比例的随着数据库条目数的增加而增加——就算用户只会阅读前面的一些条目,他也只能等全部都下载了之后才能看到。

 

这个问题的经典网页解决方案就是使用分页,并不需要特别解释的一个方案。但是,在一个应用里使用分页的难处在于处理数据不够舒服,要不然你更愿意卷屏?这篇文章的余下部分将会简单的展示这用户拥有所有数据而不下载的时候使用这两种方案的情形。这个技术称之为“懒惰装载”,是基于“不求勿施”的思路设计的。

 

我们首先做的就是询问数据库里储存的书的数量,创建一个相同长度的ArrayCollection数组,当成我们DataGrid的一个dataProvider。接着我们将只下载在DataGrid里显示的行值并把它们安放在我们ArrayCollection里合适的空位上。这样的设置的前提是简单的假设数据不会在用户使用的时候发生变化。

 

我们从PHP开始,因为这里改动不大。我们现在需要两个新的函数——一个获取条目数,也是显而易见的:

还有另一个截取数据的一段,是通过MySql LIMIT命令获得的:

 

惰性装载

 

最后要担心的是发送数据的量,当使用AMF会比XML小得多的时候,它将会成比例的随着数据库条目数的增加而增加——就算用户只会阅读前面的一些条目,他也只能等全部都下载了之后才能看到。

 

这个问题的经典网页解决方案就是使用分页,并不需要特别解释的一个方案。但是,在一个应用里使用分页的难处在于处理数据不够舒服,要不然你更愿意卷屏?这篇文章的余下部分将会简单的展示这用户拥有所有数据而不下载的时候使用这两种方案的情形。这个技术称之为“懒惰装载”,是基于“不求勿施”的思路设计的。

 

我们首先做的就是询问数据库里储存的书的数量,创建一个相同长度的ArrayCollection数组,当成我们DataGrid的一个dataProvider。接着我们将只下载在DataGrid里显示的行值并把它们安放在我们ArrayCollection里合适的空位上。这样的设置的前提是简单的假设数据不会在用户使用的时候发生变化。

 

我们从PHP开始,因为这里改动不大。我们现在需要两个新的函数——一个获取条目数,也是显而易见的:function getCount()

第一个改动就是我们RemoteObject方法的重定义,因为我们不再使用”getAll”取而代之的是两个新创建的方法。第二个改动就是我们将会填充的dataProvider的定义,还有我们DataGrid滚动条——我们将会在每次用户使用滚动的时候检查是否需要下载新的数据。

两个函数持有的RemoteObject的结果是简洁的。

一旦我们获取了数据就开始初始化dataProvider并设它的长度为我们所需。之后我们下载第一段数据,包括了从dataGrid显示的第一行到最后一行。调用反馈之后,getSomeResult函数设置dataProvider里的项目为刚从数据库取得的部分。它使用我们之前调用getSome函数时使用的参数来适当的定位(事件发生获取器(event.token.message.body)掌握着参数)

 

剩下的事就是掌握DataGrid滚动条的变化并继续下载我们缺少的数据。为了更有效率,我们在每次调用前都会做个检查,调整范围以便只下载未下载的那些行,那些是在checkWhichAreMissing函数里完成的。

至此,我们就得到了一个完全有效的应用,就是当用户需要时能下载数据的应用。你可以从文末的链接处下载整个项目的文件以及附带的注释。希望这些代码可以成为你开始发掘使用FlexPHP源的可能性的良好开端。

本文译自:http://insideria.com/2010/06/a-whole-lot-of-people.html

原创粉丝点击