YII入门教程第二章

来源:互联网 发布:宇航数控仿真软件 编辑:程序博客网 时间:2024/04/24 14:06

《应用Yii1.1和PHP5进行敏捷Web开发》


第二章:入门

很快你就会发现,真正了解Yii只需要使用它。在这一章中,我们将讲解一个Yii应用,更深刻的了解上一章所介绍的Yii的一些概念。遵循Yii的约定,我们写一个Hello, World程序试用这个框架。

在这一章中,我们将介绍:

  • Yii框架安装
  • 创建一个新的应用
  • 创建控制器和视图
  • 添加动态内容到视图文件
  • Yii请求路由并将页面链接到一起

在使用Yii之前,我们首先需要安装框架,现在让我们开始吧。

安装Yii

在安装Yii之前,你必须配置好你的开发环境,如一台支持PHP5.1.0以上版本的Web服务器。Yii已经在Windows和Linux操作系统上的 Apache Web服务器测试通过。它可能也会运行在其他平台上的支持PHP5的Web服务器,互联网上公布了很多免费资源,你可能会获得一个配置好PHP5的Web 服务器环境。在这里我们会抛开Web服务器和PHP5的安装。

Yii的安装其实非常简单,实际只需要两个步骤:

  1. 从http://www.yiiframework.com/下载Yii框架
  2. 解压下载文件到Web服务器可访问的目录下。

安装完成后,建议你检查一下当前服务器是否已经满足了Yii的所有要求。幸运的是,这样做很容易,Yii自带了一个简单的检查工具。要调用它,在你的浏览器地址栏中输入:http://yourhostname/path/to/yii/requirements/index.php

在下载Yii时,可能会有多个版本让你选择。编写本书时Yii最稳定的版本是1.1.2,虽然大部份的示例代码都应该可以运行在1.1.x版本上,但可能部份会有些差别。如果你使用的不同这个版本,请使用1.1.2版本完成下面的例子。

下面的图片显示的你在屏幕看到的结果,这就是你服务器的配置:

images/book1/chapter2/1.jpg

使用检查工具,确定服务器没有安装和使用扩展或组件,但它只是给出一个建议,以确保可以确定安装。正如你看到的,下在的检查结果,并非都是 Passed(通过)状态,也有部份显示Warning(警告)。当然,你的配置情况可能会略有不同,因此,你的显示结果也会有所不同。其实下面的细节部份没有必要全部能通过。但部份也是必要的,根据 Conclusion(结论)这个段落的内容:

你的服务器配置满足了Yii的最低要求。(Your server configuration satisfies the minimum requirements by Yii.)

安装数据库

在本书中,许多的示例中都将使用到数据库,我们会在用到时给出提示。这了能好更好跟着书中的例子操作,建议你安装一个数据库服务。Yii通过PHP本身可以支持多种数据库,如果你想使用Yii内置的数据库抽象层,这需要框架的支持。从1.1版本开始,支持的数据库有:

  • MySQL 4.1或更高版本
  • PostgresSQL 7.3或更高版本
  • SQLite 2 和 3
  • Microsoft SQL Server 2000或更高版本
  • Oracle

现在我们已经安装了Yii框架,并已经检查了服务器配置符合要求,让我们开始创建一个全新的Yii框架的Web应用程序吧。

创建一个新的应用程序

要创建一个新的应用程序,我们将使用框架附带的一个小工具yiic,这是一个命令行工具,可以使你快速的建立一个全新的Yii应用。你不是必须要用此工具才能创建Yii应用,但使用它将节省你大量的时间,并保证文件及目录的结构。

要使用此工用创建Yii应用,需要打开一个shell窗口,并进入到系统的一个位置来创建应用程序的目录结构。为了这个演示程序,我们将确保如下要求:

  • Yii的安装位置是你已经知道的
  • WebRoot是你的Web服务器配置的根目录
  • 从你的命令行,进入到WebRoot目录,并执行以下内容:
      % cd Webroot  % YiiRoot/framework/yiic webapp demo  Create a Web application under '/WebRoot/demo'? [Yes|No]  Yes         mkdir /WebRoot/demo         mkdir /WebRoot/demo/assets         mkdir /WebRoot/demo/css         generate css/bg.gif         generate css/form.css         generate css/main.css

你的应用已经成功创建到了/WebRoot/demo下。这个webapp命令的作用是创建一个全新的Yii应用。它只需要指定一个参数,无论是绝对还是相对路径都会创建应用程序。它所生成的目录及文件只是应用程序的一个骨架。

现在,我们进入刚刚创建的demo目录,看看都创建了些什么:

% cd demo %ls –passets/images/index.phpthemes/css/index-test.phpprotected/

下面是更详细的描述:

demo/index.php      Web应用程序的入口文件index-test.php Web应用程序的测试入口文件assets/        包含发送的资源文件css/           包含CSS文件images/        包含图片文件themes/        包含应用程序主题文件protected/     包含所有需要保护的应用程序文件

随着在命令行执行一条简单的命令,我们已建立了Yii框架的目录结构和默认所需的文件。但是,这些文件及目录让你看起来有点害怕。刚开始,我们可以暂时忽视其中的一部分。其实这些文件和目录已经是一个可以工作的Web应用程序了,用yiic命令创建的应用程序是一个简单的应用程序。其中 Contact Us(联系我们)页面是一个典型的表单应用,并且还自动生成了登陆页面和基于Yii框架的授权及身份验证功能。如果你的Web服务器支持GD2图形库的扩展,你也会在联系表单项中看到一个CAPTCHA(验证码)。

只要你的Web服务器正在运行,你可以打开浏览器访问http://localhost/demo/index.php。你将看到Web应用程序的首页并显示Welcome to My Web Application(欢迎来到我的Web应用)和一些帮助信息,下面的图片主是这个示例首页的样子:

images/book1/chapter2/2.jpg

你会发现这个程序的顶部有一个导航栏,从左到右分别是:Home(首页),About(关于),Contact(联系),Login(登录)。让我从左到右点击一遍。这个示例中,About(关于)提供的是一个静态页面,Contact(联系)前页已经提到,提供的是一个表单,同时包括一个 CAPTCHA(验证码)输入框。(如果你没有安装GD2图形库扩展,将看不到验证码图片)。

点击Login(登录)链接将转到一个显示登录表单的页面。其实这是一个表单验证代码,通过用户名和密码进行验证。使用demo/demo或 admin/admin的用户名/密码组合进行登录。你也可尝试输入任意组合,将得到一个登录失败的信息。成功登录后,在顶部原来显示Login的链接变成了Logout(username)(其中username可能显示demo或admin,这取决于你用哪个用户名登录)。很神奇吧,你不需要任何编码,就完成了这么多的工作。

Hello, World!

我们将通过自动生成工具,完成一个简单且有意义的工作。让我们在新的应用上建立一个本章开始提到Hello, World!程序上。Hello, World程序在Yii中是一个简单的Web程序,它发送重要信息到我们的浏览器。

在第一章,认识Yii中,我们已经了解到Yii是一个MVC结构的框架。一个典型Yii的Web应用程序是等待用户通过浏览器传入一个请求后,解析该请求的信息,去查找一个对应的控制器,然后调用该控制器内的操作方法。该控制器可以调用一个特定的视图,然后将渲染后的内容返回给用户。在处理数据时,控制器也可以与模型交互来处理创建、读取、更新和删除(CRUD)等操作。在这个简单的Hello, World!示例中,我们只需要一个控制器和视图,我们不处理任何数据,这样将不需要模型。让我们开始创建控制器吧。

创建控制器

和最初开创应用程序一样,这里我们还是调用yiic命令帮助我们创建一个控制器。在这种情况下,我们将使用yiic shell命令来启动一个可以与Yii交互的shell。要启动shell,需进入到应用程序demo目录,如以下命令:

%cd /Webroot/demo

然后接着执行yiic命令:

%YiiRoot/framework/yiic shellYii Interactive Tool v1.1Please type 'help' for help. Type 'exit' to quit. >>

如果你已经进入到了应用程序目录,你也可以调用相对路径protected/yiic命令,而不用使用Yii的安装目录。因此,与上面相同效果的启动shell命令是:

% protected/yiic shell

你当前显示的是与shell交互的提示符。你可以输入help查看shell为你提供的所有命令列表:

>> helpAt the prompt, you may enter a PHP statement or one of the following commands: - controller - crud - form - help - model - moduleType 'help <command-name>' for details about a command.

我们看了有几个可选的命令,有一个controller命令看起来象是我们想要的,可能是用来为应用程序创建一个控制器的命令。我们可以在shell提标符下进一步了解controller命令的更多帮助信息。这些信息包括提供的用法说明,参数描述和一些例子。

>> help controllerUSAGE    controller <controller-ID> [action-ID] ...DESCRIPTION    This command generates a controller and views associated with the specified actions.PARAMETERS  * controller-ID: required, controller ID, e.g., 'post'.     If the controller should be located under a subdirectory,      please specify the controller ID as 'path/to/ControllerID',     e.g., 'admin/user'.     If the controller belongs to a module, please specify      the controller ID as 'ModuleID/ControllerID' or      'ModuleID/path/to/Controller' (assuming the controller is under a subdirectory of that module).  * action-ID: optional, action ID. You may supply one or several action IDs.      A default 'index' action will always be generated.EXAMPLES  * Generates the 'post' controller:            controller post  * Generates the 'post' controller with additional actions 'contact' and 'about':            controller post contact about   * Generates the 'post' controller which should be located under    the 'admin' subdirectory of the base controller path:            controller admin/post  * Generates the 'post' controller which should belong to the 'admin' module:            controller admin/post

在最后两个例子中,使用的命令是一样的,但生成控制器所在的目录不同。Yii是能够检测出admin是一个模块还是一个子目录。

阅读帮助,很明显看出该命令会生成控制器和操作方法及视图文件。由于我们将要做的应用程序主要是显示一条消息,让我们调用controller message 和一个要显示的操作方法:

>> controller message helloWorldgenerate MessageController.php               mkdir /Webroot/demo/protected/views/message        generate helloworld.php        generate index.phpController 'message' has been created in the following file:         /Webroot/demo/protected/controllers/MessageController.phpYou may access it in the browser using the following URL:         http://hostname/path/to/index.php?r=message>>

它已经给出了创建成功的提示,MessageController默认创建到了 protected/controllers/目录下。

多么简单的一条命令,我们就创建了一个新的控制器,PHP文件名是MessageController.php,并放到了控制器目录 protected/controllers/中。新创建的MessageController类是继承应用程序的基类Controller,它的位置是 protected/components/Controller.php。这类是继承了框架的基础类CController。因此,MessageController继承了CController默认的所有行为。既然我们指了一个ActionID的参数是helloWorld,那么相对的也会在MessageController中也会创建一个actionHelloWorld()操作方法。yiic工具像在控制器中定义的操作方法一样,也承担了定义视图的代码。此视图文件与方法的id的名字一样,叫helloworld.php,此视图文件与控制器关联,默认存放在 protected/views/message/下。下面的代码是MessageController类的内容:

<?phpclass MessageController extends Controller{    public function actionHelloWorld()    {         $this->render('helloWorld');    }     public function actionIndex() {        $this->render('index');    } }

我们看到,它也增加了一个actionIndex()方法,并简单渲染一个自动创建的视图文件protected/views /message/index.php。正如第一章中描述的那样,如果只指定了controllerID,但没有指定操作,Yii默认会路由到 actionIndex()方法做进一步处理。yiic太聪明了,知道我们需要一个默认的操作方法。

试着浏览 http://localhost/demo/index.php?r=message/helloWorld 地址,你应该看到如下画面:

images/book1/chapter2/3.jpg

最后一步

要让应用程序显示Hello, World!,我们需要定制视图文件helloWorld.php。这个很容易就可以做到,编辑protected/views/message/helloWorld.php,修改成如下代码:

<?php$this->breadcrumbs=array(    'Message'=>array('message/index'),     'HelloWorld',);?> <h1>Hello, World!</h1>

保存这段代码,并在再次访问http://yourhostname/demo/index.php?r=message/helloWorld

现在显示问题语的位置改变了,你应该看到如下画面:

images/book1/chapter2/4.jpg

我们用很少的代码完成了这个简单的应用,我们仅仅对helloWorld视图文件修改了一行HTML代码。

复习一下路由请求

让我们回顾一下运行这个应用程序Yii框架是如何分析的:

  1. 通过浏览器输入Hello, World地址http://yourhostname/demo/index.php?r=message/helloWorld
  2. Yii分析这个URL,这条路由表标controllerID是message,它将告诉Yii应该去请求MessageController.php文件,这个文件的位置是protected/controllers/MessageController.php。
  3. Yii还发现,actionID指定的是helloWorld,因此,会调用MessageController类中的actionHelloWorld()操作方法。
  4. actionHelloWorld()方法会渲染helloWorld.php视图文件,这个文件的位置是protected/views/message/helloWorld.php。同时,将这个视图内容返回给浏览器。
  5. 不需要任何配置,这些步骤是连在一起的。按Yii的默认约定,整个应用程序的路由请求是无缝的连在一起。当然,如果有必要改变这个流程,Yii已经给我们提供了这样的接口,但是,如果你使用约定,你将节约配置的时间。

添加动态内容

添加动态内容最简单的方法,就是在视图模板文件中嵌入PHP语句。通过视图文件提供的是HTML结果,任何普通文本不会改变的。然而,任何在标签之间的代码会作被执行。这是一个典型HTML中嵌入PHP代码的方法,你可能很熟悉。

添加日期和时间

为我们的页面添加动态内容,并显示日期和时间。再次打开helloWorld视图文件,并添加以下代码:

<h3><?php echo date("D M j G:i:s T Y"); ?></h3>

保存,并查看以下URL地址:http://yourhostname/demo/index. php?r=message/helloWorld

快看,我们已经为应用程序添加了动态内容,每刷新一次页面,将看到显示内容的变化。

不能否认,这并不能令你兴奋,但它确实表明,怎样将PHP代码嵌入到我们的视图模板中。

一个更好的添加日期和时间的方法

虽然这种直接嵌入PHP代码的做法根本不允许复杂的代码,但Yii强烈建议这些语句不改变数据模型,让他们保持简单明了。这将有助于使我们的业务逻辑与视图分离,这是MVC架构的一部份。

将数据移到控制器

让我们将创建时间的代码放到控制器中,视图只显示这个时间。我们将代码放到控制器的actionHelloWorld()方法中,设置一个变量$theTime保存时间。

  1. 首先,让我们改变控制器的操作方法。当前,我们在MessageController控制中的actionHelloWorld()中编下如下代码:
    $this->render('helloWorld');
    在render()方法这前,我们添加一段调用时间代码,将时间存入局域变量$theTime。然后我们添加render()方法的第二个参数,将$theTime这个变量传给redner()方法:
    $theTime=date("D M j G:i:s T Y");$this->render('helloWorld',array('time'=>$theTime));
    调用的render()方法第二个参数的数据是一个array(数组类型),render()方法会提取数组中的值提供给视图脚本,数组中的 key(键值)将是提供给视图脚本的变量名。在这个例子中,数组的key(键值)是time,value(值)是$theTime则提取出的变量名$time是供视图脚本使用的。这是将控制器的数据传递给视图的一种方法。
  2. 现在让我们在视图中使用这个变量而不使用date(日期函数)。再次打开helloWorld视图,替换之前添加过的时间代码为:
    <h3><?php echo $time; ?></h3>
  3. 保存并查看结果:http://yourhostname/demo/index.php?r=message/helloWorld

下面的图片显示了我们这个应用程序的最终看到的结果,Hello World!(当然你的日期和时间会有所不同)

images/book1/chapter2/5.jpg

我们已经讲解了两种在PHP视图模板中生成内容的方法。第一种方法把数据逻辑直接在视图文件中创建。第二种方法把数据逻辑放到控制器中,然后提供给视图一个可用变量。两种方法最终的结果是同样的,时间显示在了HTML页面上。但第二个办法有一个小小的进步,他将业务逻辑的数据与视图分开。MVC架构的目的就是这种分离模式,Yii清晰的目录结构和合理的默认约定使它们连接到了一起。

你有没有注意?

在第一章提到,视图与控制器是非常紧密的兄弟,所以视图文件中的$this指的就是渲染这个视图的控制器。

修改前面的示例,在MessageController中定义一个类的公共属性,而不是局部变量,它是值就是当前的日期和时间。然后在视图中通过$this访问这个类的属性。

在前的的例子中,我们通过给控制器中render()方法传递第二个参数,将时间变量传递给视图。第二个参数提取出的变量,可以在视图中使用。但还有另一种方法,我们鼓励你自己去尝试。

把网页连接在一起

典型的网络应用程序展示给用户的页面不会只有一个。虽然我们的示例很简单,但也不会例外。让我们再增加一个页面,与Hello, World相反的内容,Goodbye, Yii developer!,并在两个页面添加互通的超链接。

通常,每个Yii的Web应用程序,都对应一个单独的视图文件(尽管不一定总是这样)。因此,我们将创建一个新的视图,并使用一个单独的操作方法来显示这个视图。什么时候添加这个页面呢?我们还需要考虑,是否使用一个单独的控制器。由于Hello与Goodbye的页面很相似,所以没有理由将这个应用逻辑放到一个单独的控制器。

连接到新页面

新页面的URL如下所示:http://yourhostname/demo/index.php?r=message/goodbye

  1. 根据Yii的约定,我们不但需要在控制器中定义操作方法,也需要一个视图名称。因此,打MessageController控制器文件,在actionHelloWorld()下面添加actionGoodbye()操作方法。并在操作方法中添加渲染的的视图名称。具体代码如下:
    class MessageController extends CController{  ...   public function actionGoodbye()  {    $this->render('goodbye');  }     ...}
  2. 下一步,我们要在protected/views/message/目录下创建视图文件,这个视图文件的名字与actionID相同,叫goodbye.php
  3. 打开这个空的模板文件,添加一行代码:
    <h1>Goodbye, Yii developer!</h1>
  4. 保存并再次查看:http://yourhostname/demo/index.php?r=message/goodbye 应该显示goodbye的信息。
  5. 现在我们需要添加超链接,把两个页面连接起来,若要从Hello, World!页面添加一个链接到goodbye页面,我们可以在helloWorld视图文件中添加一个标签指向 goodbye,URL结构如:
    <a href="/demo/index.php?r=message/goodbye">Goodbye!</a>

请大家记住,这只是个推荐的命名约定。其实视图文件名不必与ActionID相同,只需要将文件的名字作为第一个参数传递给render()就可以了。

这当然可以工作,但它仅仅是执行了一个特定URL结构,这个结构可能在某个时候发生变化,如果URL结构变化了,那这些链接将会失效。

记得在第一章中,我们介绍Blog(博客)示例时,使用了一个特别的URL地址,它的格式更加友好,并且对SEO优化也不错,如:http://yourhostname/ControllerID/ActionID一个简单的配置,就可以轻易的将现在的URL结构,改成这种路径格式的。能够改变成这种方法,对应用程序来说非常重要。只要我们避免在应用中对URL使用硬编辑,那么改变成路径格式将非常简单。

使用Yii的CHtml得到一些帮助

这种情况可以使用Yii来处理,Yii提供了许多HTML助手,可在视图模板中使用。这些HTML助手都是以静态类的方式存在的。在当前的情况下,如何为应用程序配置URL结构呢?我们希望能过调用CHtml的link方法,link方法需要一个参数是 controllerID/actionID 成对出现的字符串,另一个超连接显示的名字。由于所有助手都是静态的,所以我们可以直接调用,而不需要创建它的实例。

  1. 使用链接助手,helloWorld视图将会变成:
    <h1>Hello, World!</h1><h3><?php echo $time; ?></h3><p><?php echo CHtml::link("Goodbye",array('message/goodbye')); ?></p>
  2. 保存更改,并查看:http://yourhostname/demo/index.php?r=message/helloWorld你应该看到这个超链接,点击它应该转到goodbye页面。link助手的第一个参数是链接的显示文本,第二个参数是一个数组,值就是controllerID/actionID。结果如下图所示:
    /images/book1/chapter2/1.jpg
  3. 我们可以按照同样的方法为goodbye视图添加链接:
    <h1>Goodbye, Yii developer!</h1><p><?php echo CHtml::link("Hello",array('message/helloWorld')); ?></p>
  4. 保存视图文件,并访问如下URL地址:http://yourhostname/demo/index.php?r=message/goodbye
    你现在应该能从goodbye页面看到回到Hello, World!页面的链接,下面是goodbye页面的截图:
    /images/book1/chapter2/1.jpg

小结

在这一章中,我们创建了一个非常简单的应用,包括以下几个方面:

  • 如何安装Yii框架
  • 如何使用yiic命令创建一个新的应用
  • 如何使用yiic命令创建一个新的控制器
  • Yii是如何处理你的请求
  • 如何在控制器中创建动态内容,并将内容显示给浏览器
  • 如何网站内部的超连接

我们已经知道如何将我们的应用程序页面连接在一起。一种方法是在视图文件中添加HTML的标签以硬编码方法书写URL结构。另一种(首选)是使用Yii的CHtml助手,帮助你建立controllerID/actionID格式的URL地址,这样格式的结构,将始终与应用程序的配置关联,即使整个应用程序的URL地址改变了,我们也不用去修改内部的URL,从而保证了应用程序内部的链接不失效。

通过Hello, World!这个简单的示例,我们了解到了一些Yii的配置理念,通过一些默认推荐约定,这个简单的应用(和整个路由的请求过程)的开发是如此的简单和方便。

通过创建这个简单的应用程序,让我们更好的理解怎样使用Yii框架,它证明了使用Yii建立应用程序是如此的简单,在下一章,我们将为你介绍一个关于项目的任务管理和问题跟踪的应用程序,这个应用将贯穿本书的其余章节。