应用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的安装。
- MySQL 4.1或更高版本
- PostgresSQL 7.3或更高版本
- SQLite 2 和 3
- Microsoft SQL Server 2000或更高版本
- Oracle
- Yii的安装位置是你已经知道的
- WebRoot是你的Web服务器配置的根目录
- 从你的命令行,进入到WebRoot目录,并执行以下内容:
1 cd Webroot
2 % YiiRoot/framework/yiic webapp demo
3 Create a Web application under '/WebRoot/demo'? [Yes|No]
4 Yes
5 mkdir /WebRoot/demo
6 mkdir /WebRoot/demo/assets
7 mkdir /WebRoot/demo/css
8 generate css/bg.gif
9 generate css/form.css
10 generate css/main.css
你的应用已经成功创建到了/WebRoot/demo下。这个webapp命令的作用是创建一个全新的Yii应用。它只需要指定一个参数,无论是绝对还是相对路径都会创建应用程序。它所生成的目录及文件只是应用程序的一个骨架。
现在,我们进入刚刚创建的demo目录,看看都创建了些什么:
% cd demo %
ls –p
assets/ images/ index.php themes/
css/ index-test.php protected/
下面是更详细的描述:
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应用)和一些帮助信息,下面的图片主是这个示例首页的样子:
你会发现这个程序的顶部有一个导航栏,从左到右分别是:Home(首页),About(关 于),Contact(联系),Login(登录)。让我从左到右点击一遍。这个示例中,About(关于)提供的是一个静态页面,Contact(联 系)前页已经提到,提供的是一个表单,同时包括一个 CAPTCHA(验证码)输入框。(如果你没有安装GD2图形库扩展,将看不到验证码图片)。
点击Login(登录)链接将转到一个显示登录表单的页面。其实这是一个表单验证代码,通过用户名和密 码进行验证。使用demo/demo或 admin/admin的用户名/密码组合进行登录。你也可尝试输入任意组合,将得到一个登录失败的信息。成功登录后,在顶部原来显示Login的链接变 成了Login(username)(其中username可能显示demo或admin,这取决于你用哪个用户名登录)。很神奇吧,你不需要任何编码, 就完成了这么多的工作。
Hello, World!
我们将通过自动生成工具,完成一个简单且有意义的工作。让我们在新的应用上建立一个本章开始提到Hello, World!程序上。在Yii中,建议一个Hello, World!程序将是非常简单的Web页面,最后让这条信息在浏览器上显示。
在第一章,认识Yii中,我们已经了解到Yii是一个MVC结构的框架。一个典型Yii的Web应用程 序是等待用户通过浏览器传入一个请求后,解析该请求的信息,去查找一个对应的控制器,然后调用该控制器内的操作方法。该控制器可以调用一个特定的视图,然 后将渲染后的内容返回给用户。在处理数据时,控制器也可以与模型交互来处理创建、读取、更新和删除(CRUD)等操作。在这个简单的Hello, World!示例中,我们只需要一个控制器和视图,我们不处理任何数据,这样将不需要模型。让我们开始创建控制器吧。创建控制器
和最初开创应用程序一样,这里我们还是调用yiic命令帮助我们创建一个控制器。在这种情况下,我们将使用yiic shell命令来启动一个可以与Yii交互的shell。要启动shell,需进入到应用程序demo目录,如以下命令:
%cd /Webroot/demo
然后接着执行yiic命令:
%YiiRoot/framework/yiic shell
Yii Interactive Tool v1.1
Please type 'help' for help. Type 'exit' to quit.
>>
如果你已经进入到了应用程序目录,你也可以调用相对路径protected/yiic命令,而不用使用Yii的安装目录。因此,与上面相同效果的启动shell命令是:
% protected/yiic shell
你当前显示的是与shell交互的提示符。你可以输入help查看shell为你提供的所有命令列表:
>> help
At the prompt, you may enter a PHP statement or one of the following commands:
- controller
- crud
- form
- help
- model
- module
Type 'help <command-name>' for details about a command.
我们看了有几个可选的命令,有一个controller命令看起来象是我们想要的,可能是用来为应用程序创建一个控制器的命令。我们可以在shell提标符下进一步了解controller命令的更多帮助信息。这些信息包括提供的用法说明,参数描述和一些例子。
>> help controller
USAGE
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 helloWorld
generate MessageController.php
mkdir /Webroot/demo/protected/views/message
generate helloworld.php
generate index.php
Controller 'message' has been created in the following file:
/Webroot/demo/protected/controllers/MessageController.php
You 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类的内容:
<?php
class 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 地址,你应该看到如下画面:
最后一步
要让应用程序显示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
现在显示问题语的位置改变了,你应该看到如下画面:
我们用很少的代码完成了这个简单的应用,我们仅仅对helloWorld视图文件修改了一行HTML代码。
复习一下路由请求
让我们回顾一下运行这个应用程序Yii框架是如何分析的:
- 通过浏览器输入Hello, World地址http://yourhostname/demo/index.php?r=message/helloWorld
- Yii分析这个URL,这条路由表标controllerID是message,它将告诉Yii应该去请求MessageController.php文件,这个文件的位置是protected/controllers/MessageController.php。
- Yii还发现,actionID指定的是helloWorld,因此,会调用MessageController类中的actionHelloWorld()操作方法。
- actionHelloWorld()方法会渲染helloWorld.php视图文件,这个文件的位置是protected/views/message/helloWorld.php。同时,将这个视图内容返回给浏览器。
- 不需要任何配置,这些步骤是连在一起的。按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架构的一部份。 from our presentation code, which is part of the agenda of an MVC architecture.
将数据移到控制器
让我们将创建时间的代码放到控制器中,视图只显示这个时间。我们将代码放到控制器的actionHelloWorld()方法中,设置一个变量$theTime保存时间。
1 首先,让我们改变控制器的操作方法。当前,我们在MessageController控制中的actionHelloWorld()中编下如下代码:
$this->render('helloWorld');
在render()方法这前,我们添加一段调用时间代码,将时间存入局域变量$theTime。然后我们添加render()方法的第二个参数,将$theTime这个变量传给redner方法:
$theTime=date("D M j G:is 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/project1/chapter2/5.jpg](http://static.yiibook.com/images/project1/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
- 根据Yii的约定,我们不但需要在控制器中定义操作方法,也
需要一个视图名称。因此,打MessageController控制器,在actionHelloWorld()下面添加actionGoodbye()
操作方法。并在操作方法中添加渲染的的视图名称。具体代码如下:
class MessageController extends CController
{
...
public function actionGoodbye()
{
$this->render('goodbye');
}
...
} - 下一步,我们要在protected/views/message/目录下创建视图文件,这个视图文件的名字与actionID相同,叫goodbye.php
- 打开这个空的模板文件,添加一行代码:
<h1>Goodbye, Yii developer!</h1>
- 保存并再次查看:http://yourhostname/demo/index.php?r=message/goodbye 应该显示goodbye的信息。
- 现在我们需要添加超链接,把两个页面连接起来,若要从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 成对出现的字符串,另一个超连接显示的名字。由于所有助手都是静态的,所以我们可以直接调用,而不需要创建它的实例。
- 使用链接助手,helloWorld视图将会变成:
<h1>Hello, World!</h1>
<h3><?php echo $time; ?></h3>
<p><?php echo CHtml::link("Goodbye",array('message/goodbye')); ?></p> - 保存更改,并查看:http://yourhostname/demo/index.php?r=message/helloWorld你应该看到这个超链接,点击它应该转到goodbye页面。link助手的第一个参数是链接的显示文本,第二个参数是一个数组,值就是controllerID/actionID。结果如下图所示:
- 我们可以按照同样的方法为goodbye视图添加链接:
<h1>Goodbye, Yii developer!</h1>
<p><?php echo CHtml::link("Hello",array('message/helloWorld')); ?></p> - 保存视图文件,并访问如下URL地址:http://yourhostname/demo/index.php?r=message/goodbye
你现在应该能从goodbye页面看到回到Hello, World!页面的链接,下面是goodbye页面的截图:
小结
在这一章中,我们创建了一个非常简单的应用,包括以下几个方面:
- 如何安装Yii框架
- 如何使用yiic命令创建一个新的应用
- 如何使用yiic命令创建一个新的控制器
- Yii是如何处理你的请求
- 如何在控制器中创建动态内容,并将内容显示给浏览器
- 如何网站内部的超连接
我们已经知道如何将我们的应用程序页面连接在一起。一种方法是在视图文件中添加HTML的标签 以硬编码方法书写URL结构。别一种(首选)是使用Yii的CHtml助手,帮助你建立controllerID/actionID格式的URL地址,这 样格式的结构,将始终与应用程序的配置关联,即使整个应用程序的URL地址改变了,我们也不用去修改内部的URL,从而保证了应用程序内部的链接不失效。
通过Hello, World!这个简单的示例,我们了解到了一些Yii的配置理念,通过一些默认推荐约定,这个简单的应用(和整个路由的请求过程)的开发是如此的简单和方便。
通过创建这个简单的应用程序,让我们更好的理解怎样使用Yii框架,它证明了使用Yii建立应用程序是如此的简单,在下一将,我们将为你介绍一个关于项目的任务管理和问题跟踪的应用程序,这个应用将贯穿本书的其余章节。