Zend Framework使用实例

蓝宜
2023-12-01

一、Zend Framework简介

Zend Framework使用模型-视图-控制器(Model-View-ControllerMVC))结构。这个用来把你的程序分离成不同部分使得开发和维护变得容易。

运行Zend Framework需要:PHP 5.1.4 (或更高) Web 服务器支持 mod_rewrite功能,本实例采用Apache 

从这里http://framework.zend.com/download 下载 Zend Framework,有两种格式.zip或者.tar.gz 

二、Zend Framework的配置

1、目录结构

虽然Zend Framework 没有强求使用一个标准的目录结构,但是还是有一些通用的目录结构。这个目录结构假设你完全控制Apache 的配置。(下面以本机做例子,各位需根据自己的情况进行更改,我的服务器的根目录指向的是Web文件夹)

Web/

        test/

                /webapp

             /controllers

             /models

             /templates

             /templates_c            

       /library

       /webroot

             /images

             /js

             /css 

我们已经把程序中的模型、视图和控制器的文件分离到不同的子目录中。支持的图像,脚本和CSS 文件被存放在webroot 目录下的不同子目录中。下载的Zend Framework 文件放在 library 目录下。如果我们还需要其他库文件,都可以放在这里。在这个实例中,我们使用到了Smarty模版技术,所以Smarty 的库文件我们也应该放在library文件下!

2、启动文件

1) 配置.htaccess

我们使用单一的入口文件index.php来对我们的程序进行访问,这给我们提供了程序中所有页面的中心点并确保运行环境配置正确。我们用.htaccess 文件来实现这个目的,添加.htaccess 文件在test 的根目录中,内容如下:

RewriteEngine on

RewriteRule !".(js|ico|gif|jpg|png|css)$ index.php

2)配置Apache

与此同时,我们还需要对apache进行一些设置,打开apache的配置文件 httpd.conf

1、找到“#LoadModule rewrite_module modules/mod_rewrite.so 这句话,把前面的#去掉!

2、然后再找到“AllowOverride None   改成AllowOverride All,重新启动apache即可。

3 ) 启动文件index.php

index.php放在test的根目录下,下面是index.php的内容

PHP代码如下:

<?php

//打开错误提示

error_reporting(E_ALL|E_STRICT);

//设定时区

date_default_timezone_set('Asia/Shanghai');

//指明引用文件的路径

set_include_path('.' .

PATH_SEPARATOR . './library/'.

PATH_SEPARATOR . './webapp/models/'.

PATH_SEPARATOR . get_include_path());

//必须手动加载Loader.php

include "Zend/Loader.php";

//自动加载类,使用时,直接实例化使用

function __autoload($class){

    Zend_Loader::loadClass($class);

}

   //getInstance()方法用来获取前端控制器实例

   $frontController = Zend_Controller_Front::getInstance();

   //设定前端路由器的工作目录

   $frontController->setControllerDirectory(array("default"=>'./webapp/controllers'));

   //抛出异常

   $frontController->throwExceptions(true);

   //设置基地址,方便以后url的跳转用户,.注意,区分大小写!

   $frontController->setBaseUrl('/test');

   //使用smarty模版需关闭本身的视图助手.

 $frontController->setParam('noViewRenderer', true);

 // 关闭错误提示,发生请求错误时候,转到ErrorControllererrorAction控制器

 //$frontController->throwExceptions(false);

//对。。进行注册

   Zend_Registry::set('font', $frontController);

 //------------配置Smarty模版 ----------------

include 'Smarty/Smarty.class.php'; 

/**

 * smarty模版进行初始化

**/

$views = new Smarty();

//$views->left_delimiter = "{{";

//$views->right_delimiter = "}}";

$views->compile_dir = './webapp/templates_c';

$views->cache_dir = './webapp/templates_c/cache_c';

$views->template_dir = "./webapp/templates";

function smarty_block_dynamic($param,$content,&$views)

{

      return $content;

 }

$views->register_block('dynamic','smarty_block_dynamic',false);

Zend_Registry::set('views', $views);

//开始运行程序

 $frontController->dispatch();

   ?>

4)启动文件说明

Zend Framework 是这样设计的,所有的文件必须包含在 include_path 中。我们也把我们的模型目录包含在 include path 中,这样我们以后就能很容易加载我们的模型类。一开始,我们必须 include Zend/Loader.php,这样我们就能访问Zend_Loader ,Zend_Loader 类中有静态方法使我们能够加载其他Zend Framework 类,例如: Zend_Loader::loadClass('Zend_Controller_Front');

Zend_Loader::loadClass 加载已经命名的类。它是把下划线转换成路径隔离符来实现的,并在最后加上.php 后缀。这样,类Zend_Controller_Front 将从Zend/Controller/font.php 加载。如果你在你的类库里使用相同的命名规则,就可以用Zend_Loader::loadCass()来加载它们。我们需要加载控制器类和路由类。 

前端控制器用路由类来映射请求的 URL 到正确的 PHP 函数,然后显示页面。为了能使路由工作,需要解决 URL 的哪一部分是指向index.php 的路径,这样它就可以在那个点后面寻找url 元素。

我们需要配置前端路由器,这样它就知道从哪个目录里找出我们的控制器。

$frontController = Zend_Controller_Front::getInstance();

$frontController->setControllerDirectory('./application/controllers');

设置抛出异常,但是在服务器真正工作以后,我们不应该显示错误信息给用户看。

$frontController->throwExceptions(true);

由于在本实例中我们使用Smarty模版技术。所以我们关闭ZF本身自带的view$frontController->setParam('noViewRenderer', true);设置基地址,方便以后设置url来进行跳转。$frontController->setBaseUrl('/test');Zend_Registry::set('font', $frontController);接下来,我们对Smarty进行设置。首先我们在类库中引用了Smarty.class.php这个类。并且对它的路径进行了设置,以便让ZF知道它的位置。

include 'Smarty/Smarty.class.php'; 

/**

 * smarty模版进行初始化

**/

$views = new Smarty();

//$views->left_delimiter = "{{";

//$views->right_delimiter = "}}";

$views->compile_dir = './webapp/templates_c';

$views->cache_dir = './webapp/templates_c/cache_c';

$views->template_dir = "./webapp/templates";

function smarty_block_dynamic($param,$content,&$views)

{

      return $content;

 }

$views->register_block('dynamic','smarty_block_dynamic',false);

在这里,我们用ZF的对象注册表(Registry)来对$view来进行存贮,这样,在程序的任何对方,我们都可以调用它来进行操作。Zend_Registry::set('views', $views);设置好了以后,运行程序。$frontController->dispatch();

这个时候,你如果运行http://127.0.0.1/test 来进行测试。会发现有个错误类似 Fatal error: Uncaught exception 'Zend_Controller_Dispatcher_Exception' with message 'Invalid controller specified (index)' in这个是因为我们还没有设置好我们程序。

3、设置程序

在设置文件以前,理解Zend Framework 如何组织页面很重要。每个应用程序的页面叫 action ,许多 action 组成控制器。例如,对于这样一个格式的 URL http://localhost/test/news/view/id/1 来说,控制器是news, action view,后面的id1,分别是往这个actionView传递的参数和值。

Zend Framework 控制器把 index 作为一个缺省的action 而保留为特别的action这样,对于http://localhost/test/news/ 这样的url,在news控制器里的 index action将被执行。Zend Framework 也保留了一个缺省的控制器,也叫做index。这样,http://localhost/test/ 将执行 index控制器下的 action index

4、设置控制器

   现在可以设置控制器了。Zend Framework 里,控制器是一个必需被叫做{Controller name}Controller 的类。注意{Controller name}必需以大写字母开头。并且,这个类必须在叫做{Controller name}Controller.php这样的文件中,这个文件还必需在特定的控制器目录中。强调一下,{Controller name}必需以大写字母开头并其他字母一定是小写。每个action是在控制器类里的public 函数,名字必需是{action name}Action在这里,{action name}应该以小写字母开头。这样在文件 test/webapp/controllers/IndexController.php 里我们的控制器类叫做 IndexController

位置:test/webapp/controllers/IndexController.php

PHP代码如下:

<?php

   class IndexController extends Zend_Controller_Action

 {

      function init()

      {

   }

      function indexAction()

      {

      }

      function addAction()

      {

      }

 }

?>

我们现在有三个我们想使用的action,直到我们设置好视图,它们才工作。其中function init是个特殊的函数,简单的说,它就是在controller中的构造函数时调用的函数。

每个action URL 如下: 

http://localhost/test/            in IndexController::indexAction()

 http://localhost/test/index/add     in IndexController::addAction()

现在,我们在程序里有个能工作的路由器和每个页面的 action

5、设置视图

   因为本实例使用的的是Smarty模版,所以和ZF本身的View视图在实现过程中,稍微有点区别!下面我直接介绍在ZF里是任何使用Smarty的。

在使用Smarty之前,我们应该先取出在index.php里定义的$view,并且定义好,需要在模版显示的变量。

PHP代码如下:

class IndexController extends Zend_Controller_Action

   {

     var $views;   /*模板对象*/

     var $data;    /*传递模版变量的对象*/

      function init()

      {

             //拿回注册过的对象

             $this->views = Zend_Registry::get('views');     

    }

      function indexAction()

      {

             //定义模版显示的变量 

             $data[title]=hello world〞;

             //传递变量到模版

             $this->views->assign($data);

             //显示模版

             $this->views->display('index/index.tpl');    

    }

      function addAction()

      {

      }

   }

下面我们开始做视图文件,它们的位置是test/webapp/templates/index/index.tpl

PHP代码如下:

<head>

<meta content="text/html; charset=UTF-8" http-equiv="content-type" />

<title>{$title}</title>

</head>

<body>

<h1>{$title}<h1>

</body>

</html>

这个时候,输入http://127.0.0.1/test看看。应该会出现“hello world 了。

这样,一个简单的实例就完成了。下面我们结合Xmlrpc技术来实现一个稍微复杂一点的实例!

三、XMLRPC

1、什么是XMLRPC

    XMLRPC,顾名思义,就是应用了XML技术的RPC。那么什么是XMLRPC了? 

   RPCRemote Procedure Call的缩写,翻译成中文就是远程过程调用,是一种在本地的机器上调用远端机器上的一个过程(方法)的技术,这个过程也被大家称为“分布式计算 ,是为了提高各个分立机器的“互操作性 而发明出来的技术。

XMLRPC一样也是一个东西的缩写,这个东西就是eXtensible Markup Language,中文意思就是可扩展标记语言,标记语言就是那种用尖括号(<>)括来括去的那种语言,比如说HTMLXML的可扩展性也体现在它只定义了语言的格式,而并没有定义过多的关键字,也就是通常所说的标记(Tag),所以用户可以自由地选择定义标记。它的这种自由和简单的语法规则也使得它广为流传,用来表示各种数据。

2、在ZF中使用XMLRPC

1)创建IndexController.php

下面我们来完成一个实例,为了方便起见,就不建立新的Controller,把刚才我们建立的IndexController修改一下,就能使用了!另外我们还需要建立一个XMLRPC的服务端程序。位置在WEB服务器的根目录上(在本机中,也就是在test文件的上级目录中,取名为1.php),由于XMLRPC使用到了类库,我们还需要下载libphpxmlrpc放在library文件夹下!

文件位置:test/webapp/controller/IndexController.php

PHP代码如下:

class IndexController extends Zend_Controller_Action

   {

         var $views;   /*模板对象*/

         var $data;    /*传递模版变量的对象*/

        public    function init()

        {

                //拿回注册过的对象

                $this->views = Zend_Registry::get('views');     

                $this->font = Zend_Registry::get('font');  

             //得到基地址          

                $this->baseurl=$this->font->getBaseUrl();

         }

          function indexAction()

          {            

                 

               @include "libphpxmlrpc/xmlrpc.inc";

               @include "libphpxmlrpc/xmlrpcs.inc";                             

                if (isset($_POST['var1']) && isset($_POST['var2']))

                { 

//创建客户端

                      $client = new xmlrpc_client('http://127.0.0.1/1.php');

                    //创建一个实例

                   @ $msg = new xmlrpcmsg("add", array(

                               new xmlrpcval($_POST['var1'], "int"),

                               new xmlrpcval($_POST['var2'], "int")));

               //发送信息,

           $response=$client->send($xmlrpc_message);,服务器返回xmlrpcresp的一个实例

               $retval =   $client->send($msg);

               if ($retval->faultCode())

              {

                     print_r("发生一个错误: ");                   

                   print_r("原因: " . htmlspecialchars($retval->faultString()));        

}

               else

              {

                     //$retval->value()获取应答的xmlrpcval(也就是服务器端返回的结果),

               $retval->value()->scalarval();得到描述应答结果的PHP变量

                     $sum = $retval->value()->scalarval();

               }

        }

                                   

             @$data['var1']=$_POST['var1'];

            @$data['var2']=$_POST['var2'];

            @$data['sum']=$sum;   

            @$data[action]= "$this->baseurl/index/";            

           //构造完整的url给模版    

           $time=date("Y-m-d H:i:s")

           @$data['url']="$this->baseurl/index/add/id/$sum/time/$time";           

            /传递变量到模版

           $this->views->assign($data);

           //显示模版

             $this->views->display('index/index.tpl');                      

       }

        

 function addAction()

          {

               $data['title']="实验一下";

             //得到传递的值              

              $id=$this->_request->getParam("id");

              $time=$this->_request->getParam("time");

              $data['id']="$id";

              $data['time']="$time";

              $this->views->assign($data);

              $this->views->display('index/add.tpl');            

          }

}

2)创建显示模版文件

位置:test/webapp/templates/index/index.tpl

PHP代码如下:

<html xmlns="http://www.w3.org/1999/xhtml">

<head>

    <meta content="text/html; charset=UTF-8" http-equiv="content-type" />

    <title>xmlrpc add sample in php</title>

</head>

<h3>hello,下面演示的是利用Xmlrpc调用远程服务器方法的实例!并且我们把得到的结果传递到另外的一个函数中去!<h3>

 <body>

    <form method="POST" action="/test/index/" >

    <input type="text" name="var1" value="{$var1}" />

    +

    <input type="text" name="var2" value="{$var2}" />

    <input type="submit" value="="/>

    <input type="text" name="sum" value="{$sum}" />

    {if $sum}

    <a href="{$url}">点一下看看!</a>

    {/if}

    </form>

 </body>

</html>

 

位置: test/webapp/templates/index/add.tpl

PHP代码如下:

 <html>

   <head>

   <meta content="text/html; charset=UTF-8" http-equiv="content-type" />

         <title>{$title}</title>

   </head>

   <body>

   现在是{$time}

<h1>{$title}</h1> 你刚才传递的是 {$id}</a>

   </body>

   </html>

3)创建XMLRPC服务器端程序

位置:web/1.php

PHP代码如下:

<?php

   

@include ("libphpxmlrpc/xmlrpc.inc");

@include ("libphpxmlrpc/xmlrpcs.inc");

 if ($_SERVER['REQUEST_METHOD'] != 'POST')

 {

            exit(0);

 }

 $add_sig = array(array($xmlrpcString, $xmlrpcInt, $xmlrpcInt));

 $add_doc = "Add the two integer together";

 function add($params)

 {

                //引入用户错误代码值

                global $xmlrpcerruser;

                //返回一个PHP数组

                $val = php_xmlrpc_decode($params);

                $ret = $val[0] + $val[1];

                return new xmlrpcresp(new xmlrpcval($ret, "int"));

 }

 //创建一个xmlrpc_server的实例:

 $server = new xmlrpc_server(array(

                "add" => array(

                        "function" => "add",

                         "signature" => $add_sig,

                         "docstring" => $add_doc

        )));

?>

 类似资料: