 | 目前为止的 Tor
到目前为止,您已经使用 CakePHP 创建了一个用于管理产品和经销商的简单应用程序。在第 1 部分中了解了 MVC 模式。在第 2 部分中使用功能强大的 scaffolding 组件轻松地开发了应用程序的框架。在第 3 部分中完成了大量项目来改进 Tor。首先是清理数据。
哪些内容需要清理
在清理数据时,您可能会注意到,迄今为止的大多数用户输入都十分简单。大多数数据输入都可以使用 paranoid 方法来过滤,因为您应当不会从用户那里获得过于复杂的信息。users 控制器的 login 操作如下所示。
清单 1. 清理用户名输入
function login()
{
if ($this->data)
{
$results = $this->User->findByUsername(Sanitize::paranoid($this->data
['User']['username']));
if ($results && $results['User']['password'] == md5($this->data
['User']['password']))
{
$this->Session->write('user', $this->data['User']['username']);
$this->redirect(array('action' => 'index'), null, true);
} else {
$this->set('error', true);
}
}
}
|
与注册过程一样,期望用户的名称应当仅包含字母、空格、连字符和省略符。然而,省略符和连字符对 SQL 数据库可能造成损害。使用 sql 方法确保这些信息会安全地抵达数据库。
清单 2. 应当根据期望值清理不同的输入
function register()
{
if (!empty($this->data))
{
$this->data['User']['username'] = Sanitize::paranoid($this->data
['User']['username']);
$this->data['User']['email'] = Sanitize::paranoid($this->data
['User']['email'], array('@', '.', '-', '+'));
$this->data['User']['first_name'] = Sanitize::sql($this->data
['User']['first_name']);
$this->data['User']['last_name'] = Sanitize::sql($this->data
['User']['last_name']);
$this->data['User']['password'] = md5($this->data
['User']['password']);
|
这些只是清理数据的几个简单示例。
保护应用程序
下一个任务是使用 Security 组件确保 Tor 的安全。如果考虑哪些表单需要具有最高的安全性,那么自然会想到那些更改数据库的表单。这是一条很棒的经验法则:如果要对数据库做出更改,则应当通过 POST 方法提交表单。
符合这个规则的一种操作是产品 delete 操作。由于删除产品将从数据库中删除一行,因此它应当是一个仅限于 POST 方法的请求。实施这个要求的代码如下所示。
清单 3. ProductsController 要求 delete 操作采用 POST 方法
function beforeFilter()
{
$this->Security->requireAuth('delete');
$this->Security->requirePost('delete');
}
|
如果现在尝试删除一个产品,就会发现得到了一个 400 错误。这很好,因为它意味着所有删除都必须由特殊格式的请求引发。但是,我们需要恢复删除功能,因此需要对指向 delete 操作的视图做适当的更改。新的 showDelete 见清单 4。
清单 4. delete 操作调用应当在表单内发生
<?php if ($showDelete) { ?>
<?php echo $form->create('Product', array('action' => 'delete/' .
$product['Product']['id']));?>
<li><?php echo $form->end('Delete product');?></li>
<?php } ?>
|
还应当要求注册表单和登录表单都使用 POST 请求。代码将类似于我们在本教程中实现的内容。
为无效请求提供反馈
最后一项任务是使用 blackHoleCallback 向用户提供针对无效请求的适当响应。其目的在于提供一些有帮助的友好的反馈,而不是令人费解的服务器错误。
下面提供了这段代码的一种可能的实现。
清单 5. 错误请求函数 beforeFilter() 的更友好信息
{
$this->Security->requireAuth('delete');
$this->Security->requirePost('delete');
$this->Security->blackHoleCallback='invalid';
}
function invalid() {
header('HTTP/x 400 Bad Request');
echo('<h1>Tor</h1>');
echo('<p>We\'re sorry - there has been a problem processing your request.
Please try submitting the form again.</p>');
die;
}
|
修改默认布局
我们将在 Tor 中添加一种产品收藏功能。站点的访问者应当能够保存产品供以后使用,或使用 RSS feed 来跟踪刚上市的新产品。要添加此功能,需要使用会话处理函数和 Request Handler。但是,在开始之前,必须先略微扩展 Tor,从而为新特性提供一个位置。为此,我们将修改默认的布局以定制 Tor 的外观和感觉。
在为 Tor 创建 products 控制器时,使用了 Bake 脚本来创建应用程序框架。最后的结果是类似于图 1 的通用页面,其中包含一个表。
图 1. 简单的布局
虽然这个布局非常适于让应用程序的设计具体化,但现在处于这样一个转折点:用户需要更多的功能而不仅仅是查看产品。由于默认布局提供了一个很好的起点,因此需要做的只是略微更新现有的视图来组织应用程序。
布局
布局是不与控制器或模型直接对应的某种视图。也就是说,布局只是一个模板。更改默认的布局将影响围绕所有其他视图的区域,通常用于诸如页眉、页脚和菜单栏等区域。
我们一直以来使用的都是默认的 CakePHP 布局,它位于 cake/lib/views/templates/layouts/default.thtml 中(请不要更改它!)。要想用定制的模板重写该布局,应该将默认模板复制到 app/views/layouts/default.ctp 并将其内容改为清单 6 这样(只修改了默认模板中的菜单 div)。
清单 6. 用定制模板重写布局
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>
Tor : <?php echo $title_for_layout;?>
</title>
<?php echo $html->charset();?>
<link rel="icon" href="<?php echo $this->webroot;?>favicon.ico"
type="image/x-icon" />
<link rel="shortcut icon" href="<?php echo $this->webroot;?>
favicon.ico" type="image/x-icon" />
<?php echo $html->css('cake.generic');?>
<?php echo $scripts_for_layout;?>
</head>
<body>
<div id="container">
<div id="header">
<h1><?php echo $html->link('Tor', '/'); ?>
: Welcome <?php echo $session->read('user') ?></h1>
</div>
<div id="content">
<div id="menu">
<?php echo $html->link('Products',
array('controller' => 'products')); ?> | <?php echo
|-------10--------20--------30--------40--------50--------60--------70--------80--------9|
|-------- XML error: The previous line is longer than the max of 90 characters ---------|
$html->link('Favorites', array('controller' => 'users',
|-------10--------20--------30--------40--------50--------60--------70--------80--------9|
|-------- XML error: The previous line is longer than the max of 90 characters ---------|
'action' => 'favorites')); ?> |
<?php echo $html->link('Login', array('controller' =>
'users', 'action' => 'login')); ?> |
<?php echo $html->link('Logout', array('controller' =>
'users', 'action' => 'logout')); ?>
</div>
...
(message flash, content for layour, cake link, debug, etc
...
</body>
</html>
|
这段代码基于 CakePHP 的默认布局,只添加了一个菜单栏并添加了一些 Tor 标志。由于它仍然使用默认的 CSS,因此在视觉上站点并没有很大的变化。
注意,布局代码是 XHTML Transitional。即使我们的视图全都是 XHTML 格式的,也完全可以将其插入另一种格式的布局中,例如 Atom、WML 或 XHTML-Mobile。在向站点中添加此功能时,我们会再次讨论布局问题。
|  |