Zend_Controller讲解(一)

刚开始使用ZF的时候,只是从文档上面了解了一下实现机制,并没有怎么看代码。现在ZF已经是Beta版了,MVC的实现跟原来还是有点差别的。而且新的东西也在不断的加入进来。本文是以ZendFramework 0.9.2来进行说明。

在Controller目录下主要有:Front.php和Action.php两个文件。Zend_Controller_Front用于引导实例,设置相关参数。 Zend_Controller_Action提供控制器的基本方法,其它的控制器都应该是Zend_Controller_Action的子类。

然后,Plugin、Request和Response文件夹,就不用多说了。

Router文件夹是URL映射的实现。不管你是否会用到Zend_Controller_Router_Rewrite,都会创建这个对象。其中每一条规则就是Zend_Controller_Router_Route_Interface的实现。如果没有添加URL映射规则,就会以默认的方式来Dispatcher控制器。

最后,Dispatcher是用于通过URL的映射出的参数,来创建不同的控制器。

这里只是对各个文件夹的内容作个说明,我希望我能写点代码来描述这些东西,希望“五一”来了我能完成。 

用Zend_Loader加载文件

在PHP中经常会调用include_once和require_once来加载各种文件,并确保只加载一次。但在5.2以前的版本都会找开目标文件,以降低IO影响效率。据说在5.2中已经改进,不过我没试过。

所以,尽量不要使用他们。如果需要确保文件只加载一次,需要另外进行判断。在Zend_Loader中,ZF已经帮我们把这些工作都作好了。而且,这些方法都是静态方法。所以,在使用ZendFramework开发的时候尽量使用Zend_Loader吧。如果没有使用框架的话,可以自己封装一个这样的东西。

SimpleXML的返回值

在PHP5中,有许多解析xml文件的方法。其中使用SimpleXML是一种非常简单的方法,而且还能与其它方法相结合使用。至于使用方法我这里就不多说了,当你直接输出值的时候可能没有注意,如果你想把值保存下来,却发现有问题。

代码如下:

$handle = new SimpleXMLElement($xml);
$title = $handle->title;

var_dump($title); 

object(SimpleXMLElement)#28 (1) { [0]=> string(15) "逝去的鱼缸" }

$title是一个SimpleXMLElement对象,如果我想将这个值赋给一个数据则必须:

$testArray = (string)$handle->title;

使用强制转型,这样就可以继续其它的操作了。 

Wow!在PHP使用Zope的TAL

TAL(Template Attribute Language)是Zope的模板标记语言,由于TAL是基于名字空间的,所以她可以用任何支持xml和xhtml的编辑器来编辑。而且她只有8个功能语句,以下是参照Plonebook-zh上面的解释。

TAL语句包括:

  • tal:attributes – 动态更改元素属性。
  • tal:define – 定义变量。
  • tal:condition – 测试条件。
  • tal:content – 替换元素中的内容。
  • tal:omit-tag – 忽略一个元素,保留元素内容。
  • tal:on-error – 处理错误。
  • tal:repeat – 重复一个元素。
  • tal:replace – 替换元素的内容,删除元素,保留内容。

使用进来非常灵活。这里有一个PHP的实现PHPTAL。从文档上看在原有的tal、metal、i18n上面单独实现了phptal的名字空间。呵呵,有机会研究一下。

重要的是在ZendFramework的Proposal中提到了整合进Zend_View中。当我去看PHPTAL的网站的时候我就在找授权,不过没找到。而且proposal的留言中,也提到了授权问题。密切关注。

Zend_XmlRpc简单说明

原来我曾经说过,Zend_XmlRpc不好象不能传参数。今天又研究了下,看来原来打了个小马虎Tongue out

我现在以实现MetaWeblog API的例子,说明一下。跟官方文档实现上是差不多的。

首先,要实现一个Xmlrpc的服务端。非常简单,因为ZendFramework已经帮你把它作好了。Laughing

public function indexAction()
    {
        $server = new Zend_XmlRpc_Server();
        $server->setClass('MetaWeblogCore', 'metaWeblog');
        echo $server->handle();
     }

很明显第一行是创建一个Xmlrpc的服务实例。然后通过setClass()方法设置可调用的方法类和名字空间,当然,你可以使用addFunction这个方法,这样可调用的方法直接就可以写在控制中了。

注意$server->handle()返回的是Zend_XmlRpc_Response,而不是最终输出的对象。

现在来看看MetaWeblogCore这个类,这是一个MetaWeblog API的实现。查看规范中文版

  /**
     * The MetaWeblog API newPost
     *
     * @param string $blogid
     * @param string $username
     * @param string $password
     * @param struct $struct
     * @param boolean $publish
     * @return string
     */
    public function newPost($blogid, $username, $password, $struct, $publish)

原来我没有上面的注释,以为这只是PHPDoc里面的东西,就没有写。原来这几行是必须要的。。。

最后,再建立一个client来测试

public function indexAction()
    {
        $client = new Zend_XmlRpc_Client('http://localhost/xmlrpc');

        $blogid = '30';
        $username = 'username ';
        $password = 'password ';
        $struct = array(
            'title' => 'me',
            'description' => 'money'
        );
        $publish = true;
        $result =  $client->call('metaWeblog.newPost', array($blogid, $username, $password, $struct, $publish));

        $this->getResponse()->setHeader('Content-Type', 'text/xml', true);
        $this->getResponse()->setBody($result);
    }

setHeader()和setBody()用于设置返回值。虽然现在看上去还不向一个API都基本方法就是这样。

这里主要说明的那个小马虎。。。。

ZendFramework Beta版发布

ZendFramework Beta版终于发布了,这个版本最显著的变化就是把Zend.php拆分成几个部分:Zend_Debug、Zend_Loader、Zend_Registry、Zend_Version。所以,升级后报错是正常的,只要替换一下就OK了。这次拆分最让我舒服的是Zend_Registry,原来的register和registry方法被,set()和get()替换了。因为这两个单词很像,不好区分。

如果你要使用Zend_Db_Table的话,那就要注意一下,有个小bug。一种方法是使用svn中的版本,或者自己把Zend/Db/Table/Row/Abstract.php中加上'<'号,因为丢失了这个符号,所以不是一个合法的php文件了。从NEWS.txt来看这一版本对Db的改进还是挺大的。而且其它部分也得到了强化和bug修理。

官方预计会在5月10号发布ZendFrameowrk 1.0GA版。哈哈,估计快要爆发了。 

理解观察者模式

当我在IBM developerWorks 中国上看到五种常见的 PHP 设计模式这篇文章的时候,我才开始注意设计模式的。其中这个观察者模式,我当时实在是没看懂到底是什么意思,昨天在看ZendFramework中的Zend_Filter组件的例子的时候,才突然发现原来是这么回事。

在0.8版中, Zend_Filter提供一种过滤链的机制,这种设计就是使用了观察者模式。代码如下:

$filterChain = new Zend_Filter();
$filterChain->addFilter(new Zend_Filter_Alpha())
            ->
addFilter(new Zend_Filter_StringToLower());

// Filter the username
$username $filterChain->filter($_POST['username']);

所有过滤器都实现Zend_Filter_Interface接口,然后通过Zend_Filter对象的addFilter注册被观察者对象,也就是这些过滤器。最后调用Zend_Filter的filter方法,遍历被观察者的对象,并执行Zend_Filter_Interface中实现的的filter操作。

Zend_XmlRpc_Client无法传参?

这几天我想实现MetaWeblog API,在Zend Framework中已经实现了Xmlrpc的服务端和客户端,拿过来直接用就是了。当我调用一个没有参数的方法时,可以正常显示结果。但我调用必需要传参数的方法时,Zend_XmlRpc_Client丢出了一个异常,“Calling parameters do not match signature”。不知道是怎么回事Innocent

在邮件列表中也看到有人提出类似的问题,也是抛出个这个异常信息。不解。。。 

Xdebug不错的php扩展

前一段时间听说xdebug是个不错的php扩展,可以查找程序进行的详细过程和使用的时间。昨天,把这个扩展装了一下,非常不错。

这里一篇文章说的非常详细,包括:安装,使用。

这个扩展修改的报错信息的显示方式,加了些样式。由于在ZendFramework中,所以的操作都被指向index.php这个文件,所以在WinCacheGrind看的时候,也只有index.php一个而已。而且可以非常详细的显示出程序执行的过程。还有一个问题就是当在ZendFramework中抛出异常的时候,Xdebug会在异常前面显示报错信息。如果不是debug的时间,最好注释该扩展。

总之,Xdebug是非常的赞!Laughing

最新ZendFramework的Roadmap

0.9版将在这个月的15号冻结代码,这将是ZendFramework的第一个Beta版。并会以两个星期为间隔发布0.9.X版。在0.9版中,所有还在incubator目录中的功能开发暂停直到1.0版。当Beta版足够稳定和完善时,将发布1.0 RC版,依然以每两个星期为单位发布新的RC版。

1.0 RC大约在四月12,1.0大约在5月10号。

大家来华丽的期待吧!Laughing