IBM®
跳转到主要内容
    中国 [选择]    使用条款
 
 
Select a scope: Search for:    
    首页    产品    服务与解决方案     支持与下载    个性化服务    
跳转到主要内容

developerWorks 中国  >  Open source  >

使用 CakePHP 快速打造 Web 站点,第 4 部分: 使用 CakePHP 的 Session 和 Request Handler 组件

使 PHP 应用程序更加流线化

developerWorks
前一页第 2 页,共 9 页后一页

文档选项

样例代码


对本教程的评价

帮助我们改进这些内容


目前为止的 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。在向站点中添加此功能时,我们会再次讨论布局问题。





回页首



前一页第 2 页,共 9 页后一页
    关于 IBM 隐私条约 联系 IBM 使用条款