这一章介绍了又一个节约你的时间而且使你的代码更具安全性和逻辑性的领域。
第一,我们将会介绍创建视图的各种不同方法-与你的控制器和模型协同并用来显示结果的页面。
然后,你将会学到如何很快地创建 HTML 表格, 与实现内建的保护; 而且你也将会看到该如何校验你的表格。
我假定这本书的读者熟悉 HTML 和 CSS 。 下列的例子非常简单,因此,我们能把重点放在 CI 代码上。 而且我已经假定我们已经写一个 CSS 文件并已把它保存在网站的某个目录中。
编写视图
视图是用户用户能看到你的网站的所有。 他们使用一个统一的接口, 而且可以根据需要进行修改。 MVC 的好处之一是你分开了表示层和逻辑层, 一切都显得很干净。
到现在为止, 我们已经完成了那非常简单的 'welcome' 页面,(记得第 3 章吗?) 现在让我们看看该如何使它变得更精细。
视图实际上是一组包含有你的内容的HTML结构。结构中有各种元素,如颜色,字体,文字布局等; 不过视图不关心这些,它要做的只是取来内容,显示出来。
创建视图, 首先你需要创建一个HTML 网页的骨架,并保存为.php后缀。 让我们称它为 basic_view.php 。保存在application/views目录中。 (CI的loader会在这个目录寻找视图文件。)
<html>
<head>
</head>
<body>
<p>Hello World!</p>
</body>
</html>
然后当你想要从一个控制器装载它时, 使用在某个函数中调用$this->load->view():
function index() {
$this->load->view('basic_view');
}
注意,如果这是一个model或者一个helper,你将会首先装载它, 然后根据需要使用它。 通过视图,调用它只需要一行代码。
当然,那是一个空的视图。 为了要使它有用,我们需要内容。因此我们要增加名称和一些文本。 首先我们在控制器中定义他们:
function() {
$data['mytitle'] = "A website monitoring tool";
$data['mytext'] = "This website helps you to keep track of the other websites you control";
}
注意我们并没有把它们定义为单独的变量, 而是作为数组$data的元素。 对于第一个元素, 键名是 'mytitle',值是 "A website monitoring tool".
然后,我们调用装载函数:
function index() {
$data['mytitle'] = "A website monitoring tool";
$data['mytext'] = "This website helps you to keep track of the other websites you control.";
$this->load->view('basic_view',$data);
}
我们把$data数组作为$this->load->view()的第二个叁数,在视图名称之后。视图接收到$data数组后,使用PHP函数extract()把数组中的每个元素转换成内存变量,数组的键名即为变量名,值为变量内所包含的值。这些变量的值能直接被视图引用:
<html>
<head>
</head>
<body>
<h1 class='test'><?php echo $mytitle; ?></h1>
<p class='test'><?php echo $mytext; ?></p>
</body>
</html>
虽然你只能传送一个变量到视图, 但是通过建立数组,你能把大量变量整洁地传入视图。它似乎复杂, 但是实际上是一种紧凑和优秀的信息传输方式。
PHP标记的长格式和短格式
在我们继续之前, 先了解一下PHP标记的两种不同格式。
常用的方式是:
<?php echo $somevariable?>
然而,如果你不喜欢这种, CI 也支持一个较短的版本:
<?=$somevariable?>
<?php ?>被<??>取代,而且echo由“=”代替,你也能用短格式来使用if, for, foreach, 和while循环。完整的介绍请参考在线用户手册。
我个人偏好标准格式,因为我已习惯使用它。如果你使用短格式,注意有些服务器不能正确地解释短格式。 如果你仍然想要使用短标签, 可以打开 config 文件, 改变下列设置:
$config['rewrite_short_tags']= FALSE;
如设置为TRUE,CI在把它们送到服务器之前,将把短格式改成标准格式。 不过这样做会对调试造成困难。因此,建议使用标准格式。
CI 也有一个 '模板语法分析器' 类,允许你把变量放入HTML代码而不需要任何的PHP代码。本文不涉及这个内容。如果在与可能被 PHP 代码弄糊涂的 HTML 设计者合作,它相当有用,细节请参见用户手册。
嵌套视图
为了最大程度地重用代码,我们可以提取HTML页面的公共部分,例如,header和footer,然后在显示实际视图时把它们组合起来。
让我们创建一个视图的header部分, 这是一个符合W3C标准的header、包含HTML声明和 meta数据。
首先, 我们列出header部分的代码:
<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 strict//EN'http://www.w3.org/TR/xhtml1/DTD/xhtml-strict.dtd'>< html xmlns='http://www.w3.org/1999/xhtml'>
<title><?php echo $mywebtitle?></title>
<base href=<?php echo "$base"; ?>>
<?php echo $myrobots?>
<link=" stylesheet" type="text/css" href="<?php echo "$base/$css;?>">
把这保存为views/header_view. 下面介绍它包含的变量:
。$mywebtitle, 是标题 (meta标签; 这将不在屏幕上出现,但是搜索引擎将会读取,每个页面的meta有可能有变化,因此,我把它设为一个变量。)
。$myrobots, 这个变量用来告诉机器人当前页面不需要被编入索引。
。$base和 $css, 描述基本网址的字符串。$css包含css文件的路径信息, 这些信息会从CI的config 文件读取(也可以用 CI config 变量 site_url代替。)
现在我们需要知道:
。我们如何调用嵌套视图?
。我们如何获取变量的值?
有二个方法可选择。 第一,在主调用视图中读入其它视图,因此我们的主视图,也就是basic_view,应该加上一行:
<html><head>
<?php $this->load->view ('header_view'); ?>
</head><body>
<?php echo $mytitle; ?>
<?php echo $mytext; ?>
</>
</html>
变量可以在控制器中加上两行:
function index() {
$data['mytitle'] = "A website monitoring tool";
$data['mytext'] = "This website helps you to keep
track of the other websites you control.";
$data['myrobots'] = '<meta name="robots" content
="noindex,nofollow">';
$data['mywebtitle'] = 'Web monitoring tool';
$data['base'] = $this->config->item('base_url');
$data['css'] = $this->config->item('css');
$this->load->view('basic_view',$data);
}
在这里新的变量 $myrobots,$css, $base, $mywebtitle被创建为数组$data的新元素,当header_view被basic_view调用时,CI使用extract()解开他们, 在视图中显示出来(在两个视图中不要出现同名的变量,否则会引起冲突)。
第二个方法将把视图加入控制器里面, 给它分配一个变量:
function index() {
$data['mytitle'] = "A website monitoring tool";
$data['mytext'] = "This website helps you to keep
track of the other websites you control.";
$data['myrobots'] = '<meta name="robots" content
="noindex,nofollow">';
$data['mywebtitle'] = 'Web monitoring tool';
$data['base'] = $this->config->item('base_url');
$data['css'] = $this->config->item('css');
$data['header'] = $this->load->view('header_view', '', TRUE);
$this->load->view('basic_view',$data);
}
从严格的 MVC 设计原则来看,这样做似乎更正确。
实际上有三个叁数可传给load->view函数。
。 第一个, header_view, 是要装载的视图的名字。 这是必选。
。 第二个,是可选项, 是装入视图的数据。
。 第三个是布尔值。如果你不指定它,默认是FALSE, 将视图送到浏览器。 然而,在嵌套视图这种情况下,你需要将header_view送到主视图basic_view中,因此需要将第三项参数设置为TRUE。
现在我们已经建立了与 stylesheet 的关联, 我们能够用定义好的css中的类来更新视图中的显示部分:
<html><head>
<?php $this->load->view('header_view'); ?>
</head><body>
<h1 class='test'><?php echo $mytitle; ?></h1>
<p class='test'><?php echo $mytext; ?></p>
</body>
</html>
请注意CI的 MVC 系统能让你分离显示的内容。 视图只为内容提供结构, 结构的风格则由css stylesheet控制。
视图不关心什么 $mytext的内容是什么,它只是按照正确的格式在正确的位置上显示它。 定义 $mytext 的控制器甚至不知道 (也不关心) 它产生的数据如何被显示。
因此, 如果我们需要改变我们网页的外观, 或在一个不同的系统 (如WAP)上显示他们,那么我们只需要改变视图和CSS stylesheet。 我们不需要修改控制器。
而且如果我们想要改变在网页上的信息,我们不需要去改动视图, 而是只需要改变控制器里的变量值。
记得 '松藕合' 原则吗? 这里再一次体会到了这个原则,这使设计,升级, 和维持你的网站比较容易。
网站结构的现实问题
请稍等片刻,我们在header_view动态地生成了 CSS stylesheet地址:
<link="stylesheet" type="text/css" href="<?php echo "$base/$css";?>">
这意味着控制器必须生成变量的值,这些值与数据如何被显示有关, 但是我们在上面说过控制器不应该知道或者关心它们具体的值是什么。这样不就符合了我们刚才提及的所谓'松藕合'原则? 动态地产生这些数据需要这样一些操作: 首先,控制器必须在 config 文件中读取它们,然后控制器必须在$data数组中装入它们而且传送它们到视图,然后视图必须解开成为内存变量$base和$css, 真正使用这两个变量的是HTML协议。
似乎这样做太绕圈子了,为什么不直接在视图中静止地插入数据?
<link="stylesheet" type="text/css" href="http://www.mysite.com/mystylesheet.css";">
用变量方式做这件事情的好处是:如果你迁移网站, 或移动你的 CSS 文件,你只需要在 config 文件中改变设置,而且每个控制器和视图将会立刻反映变化。 而如果把CSS位置硬编码到每个视图的后果是一旦需要变化,你必须到每个视图中去修改它们,明白这样做的好处了吧?
CI 的表格助手: 录入数据
让我们把目光转向你如何使用你的 HTML 页。任何动态的网站最重要部份之一是和用户互动,而且这通常意味着使用 HTML 表格。 编写表格是重复和无聊的。
CI 的表格助手是密码的非常有用的代码片断。 它有一个稍稍不同的定义, 使表格创建起来比较容易。 让我们建立一个表格,这个表格允许我们在浏览器中录入数据。 在websites数据库的sites表中,我们想要录入网站的名字、类型和网址, 和更新的日期。
你能用简单的 HTML代码 建立表格, 或你能在一个控制器内建立它,把它赋给一个变量, 然后调用视图, 而且传送该变量到视图。 我正在按第二种方式做。
第一,我们必须装载表格助手到我们需要使用它的控制器内。 然后, 我们把下列的代码放入控制器的构造函数:
$this->load->helper('form');
然后,我们必须开始编写表格。
现在, 为了生成表格的输入项, 我们不用这样写:
$variable .= <input type='text' name='name' value=''>
CI 让你这样做:
$variable .= form_input('name','');
(记得'name'是输入项的名称, 'value'是你想输入的内容。 在这里可以设定value的初始值,或你能动态地从表格中获取.)
可以看到,使用CI的表格助手列方便。
使用表格助手的好处之一: 清楚
使用 CI 表格助手的第一个利益是你的代码绝对的清楚。 如果你想要一个比较精细的输入框, 如果用HTML是这样的:
$variable = 'input type="text" name=" url" >