发新话题
打印

Zend 框架学习之提要篇

重温 createAction

我们重温一下 createAction,它可以验证由注册表单通过 POST 提供的信息。修改 createAction 方法,如下所示。


清单 8. 修改 createAction 方法
复制内容到剪贴板
代码:
    function createAction()
    {
        $filterPost = Zend::registry('fPost');
        $username = $filterPost->testAlnum('username');
        $password = $filterPost->getRaw('password');
        $password2 = $filterPost->getRaw('password2');
        $email = $filterPost->testRegex('email',
"^[a-z0-9]+[a-z0-9_-]*(\.[a-z0-9_-]+)*@[a-z0-9_-]+(\.[a-z0-9_-]+)*\.(
[a-z]+){2,}$^");
        $lName = $filterPost->testName('lName');
        $fName = $filterPost->testName('fName');

        if($username != '' &&
           $email != '' &&
           $lName != '' &&
           $fName != '' &&
           $password != '' &&
           $password2 != '' &&
           $password == $password2){

            $db = Zend::registry('db');
            $row = array(
                         'FirstName' => $fName,
                         'LastName' => $lName,
                         'EmailAddress' => $email,
                         'Username' => $username,
                         'Password' => $password
                         );           
...
    }
以上代码使用 Zend_InputFilter 类验证了电子邮件、用户名、名和姓的输入,而不是直接访问。

TOP

重温 displayProfileAction

在 displayProfileAction 方法中,将使用 Zend_InputFilter 类来检索用户名。修改该方法,如下所示。


清单 9. 修改 displayProfileAction 类
复制内容到剪贴板
代码:
    function displayProfileAction()
    {
        $filterSession = Zend::registry('fSession');
        $username = $filterSession->getRaw('username');
        if ($username != ''){
            $db = Zend::registry('db');
...
            $view->email = $email;
            $view->username = $username;
...
    }

TOP

重温 updateAction

此方法同 createAction 方法类似,所以不再赘述。修改 updateAction 方法,如下所示。


清单 10. 修改 updateAction 方法
复制内容到剪贴板
代码:
    function updateAction()
    {
        $filterPost = Zend::registry('fPost');
        $password = $filterPost->getRaw('password');
        $password2 = $filterPost->getRaw('password2');
        $email = $filterPost->testRegex('email',
        "^[a-z0-9]+[a-z0-9_-]*(\.[a-z0-9_-]+)*@[a-z0-9_-]+(\.[a-z0-9_-]+)*\.([a-z]+){2,}$^");        
        $lName = $filterPost->testName('lName');
        $fName = $filterPost->testName('fName');

        $filterSession = Zend::registry('fSession');
        $username = $filterSession->testAlnum('username');

        if($email != '' &&
           $lName != '' &&
           $fName != '' &&
           $password != '' &&
           $password2 != '' &&
           $password == $password2){
            $db = Zend::registry('db');
            $table = 'users';

            $row = array(
                         'FirstName' => $fName,
                         'LastName' => $lName,
                         'EmailAddress' => $email,
                         'Username' => $username,
                         'Password' => $password
                         );

            $where = $db->quoteInto('Username = ?', $username);
...
    }

TOP

重温 authenticateAction

用户登录时,authenticateAction 方法将被调用,它从 POST 数组中检索用户名及密码。为取代这种方式,而从注册库的 fPost 对象中检索,修改 authenticateAction 方法,如下所示。


清单 11. 修改 authenticateAction 方法
复制内容到剪贴板
代码:
    public function authenticateAction()
    {
        $filterPost = Zend::registry('fPost');
        $username = $filterPost->getRaw('username');
        $password = $filterPost->getRaw('password');

        $db = Zend::registry('db');
        $select = $db->select();
        $select->from('users', '*');
        $select->where('Username = ?', $username);
        $select->where('Password = ?', $password);
        $sql = $select->__toString();
        $rowsFound = $db->fetchAll($select);
...
    }

TOP

订阅提要

如果使用的是一个提供评论性财经信息的经纪业务网站(例如,道琼斯新闻快报),可能要在用户订阅前先行收费。在本教程中,我们假定所有的提要都是免费的。

本部分中涵盖了订阅及退订提要,以及浏览一个给定提要的所有摘要(headline)。

viewFeeds 视图

这是 IndexController 为已登录的用户提供的主视图。该视图展示了可用行为及链接,以查看可用提要的摘要。定义这个文件,并将其放至视图目录中,如下图所示。


清单 12. 主 viewFeeds 视图
复制内容到剪贴板
代码:
<html>
<head>
    <title>You're Logged In!</title>
</head>
<body>
  [<a href="user/logout">Logout</a>]<br>
  [<a href="user/displayProfile">View/Update
profile</a>]<br>
  [<a href="feed">Sub/Unsubscribe to/from
Feeds</a>]<br>
  [<a href="feed/viewSavedEntries">View Saved
Entries</a>]<br>
  <h1>CHOMP! The Feed Reader</h1>
  <h3>Hello <?php echo $this->escape($this->username); ?>
      you're logged in!</h3>
...
  </table>
</body>
</html>
这里有四个可用行为:退出系统、查看/更新配置文件、订阅或退订以及查看已保存条目。

[ 本帖最后由 TigerChou 于 2007-9-10 14:18 编辑 ]

TOP

FeedController

FeedController 具有与提要相关的几个行为。单击 “Sub/Unsubscribe to/from Feeds” 这一链接,将调用 FeedController 的 indexAction 方法。定义 FeedController.php 文件,并将其放至控制器目录中,如下所示。


清单 13. FeedController
复制内容到剪贴板
代码:
<?php
class FeedController extends Zend_Controller_Action
{
    public function indexAction()
    {
        $filterSession = Zend::registry('fSession');
        $username = $filterSession->getRaw('username');

        $db = Zend::registry('db');
        $select = $db->select();
        $select->from('feeds', '*');
        $select->where("feedname NOT IN " .
                       "(select feedname from subscribedfeeds ".
                       "        where username=?)",
                       $username);
        $sql = $select->__toString();
        $subFeeds = $db->fetchAll($select);

        $select = $db->select();
        $select->from('subscribedfeeds', '*');
        $select->where("username=?", $username);
        $sql = $select->__toString();
        $unsubFeeds = $db->fetchAll($sql);
        
        $view = Zend::registry('view');
        $view->title = 'View Available Feeds';
        $view->subFeeds = $subFeeds;
        $view->unsubFeeds = $unsubFeeds;
        echo $view->render('feeds.php');
    }

    public function noRouteAction()
    {
        $this->_redirect('/');
    }
}
?>
该代码先从注册库中存储的 fSession 对象中检索 username,然后检索两个提要列表:一个是当前用户已订阅的提要,一个是未订阅的。对数据库的第一次查询检索已订阅提要,将它们存储在 subFeeds 中,下一次查询检索了当前尚未订阅的提要并将其存储在 unsubFeeds 中。随后,从注册库中获得该视图,并将其初始化、呈现及显示出来。

TOP

提要视图

清单 13 呈现的视图是 feeds.php。此视图显示了已订阅提要和退订链接,以及未订阅提要清单同订阅链接。定义 feeds.php 文件,如下所示。


清单 14. 定义提要视图
复制内容到剪贴板
代码:
<html>
<head>
    <title><?php echo $this->escape($this->title);
?></title>
</head>
<body>
  [<a href='/'>Back to Main Menu</a>]<br>
  <h1><?php echo $this->escape($this->title);
?></h1>
  
  <table>
    <tr>
      <td>Feed Title
        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</td>
      <td>Subscribe to Feed</td>
    </tr>
  <?php
     foreach($this->subFeeds as $row){
         $entryTitle = $row['feedname'];
         echo "<tr><td>$entryTitle</td>";
         echo "<td><a
href='feed/subscribe?title=$entryTitle'>".
              "subscribe</a></td></tr>";
     }
?>
    <tr><tr><td>&nbsp;</td></tr>
      <td>Feed Title
        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</td>
      <td>Unsubscribe to Feed</td>
    </tr>
  <?php
     foreach($this->unsubFeeds as $row){
         $entryTitle = $row['feedname'];
         echo "<tr><td>$entryTitle</td>";
         echo "<td><a
href='feed/unsubscribe?title=$entryTitle'>".
              "unsubscribe</a></td></tr>";
     }
?>
  </table>
</body>
</html>
首先显示一些标题信息,随后遍历 subFeeds 对象中的每一个条目,并同退订链接一起显示出来。请注意该链接是提要/订阅,也就是说,单击该链接时,FeedController 对象的 subscribeAction 方法将被调用。对于退订提要的列表也采用相同的处理方法,不同之处只是调用 unsubscribeAction 方法。

接下来定义 subscribeAction 方法,然后再定义 unsubscribeAction 方法。

TOP

订阅提要

用户想要订阅提要时,subscribeAction 将被调用。必要的行为就是向数据库添加提要链接以及订阅该提要的用户名。在 FeedController 类中定义 subscribeAction,如下所示。


清单 15. 定义 subscribeAction 方法
复制内容到剪贴板
代码:
    public function subscribeAction()
    {
        $filterSession = Zend::registry('fSession');
        $username = $filterSession->getRaw('username');
        $filterGet = Zend::registry('fGet');
        $feedTitle = $filterGet->getRaw('title');

        $db = Zend::registry('db');

        $row = array(
                     'Username' => $username,
                     'feedname' => $feedTitle
                     );
            
        $table = 'subscribedfeeds';
        $rowsAffected = $db->insert($table, $row);

        $this->_redirect('/feed');
    }
此方法从 Zend 注册库的 fSession 和 fGet 对象中分别检索 username 和 feedTitle。随后准备了一条 SQL 语句,用于向 subscribedfeeds 表中插入一行,以使用户订阅到所需提要。

TOP

退订提要

退订提要与订阅提要正好相反。定义 FeedController 的 unsubscribeAction 方法,如下所示。


清单 16. 定义 unsubscribeAction 方法
复制内容到剪贴板
代码:
    public function unsubscribeAction()
    {
        $filterSession = Zend::registry('fSession');
        $username = $filterSession->getRaw('username');
        $filterGet = Zend::registry('fGet');
        $feedTitle = $filterGet->getRaw('title');

        $db = Zend::registry('db');
        $table = 'subscribedfeeds';
        $where = "username='$username' and feedname='$feedTitle'";
        $rowsAffected = $db->delete($table, $where);

        $this->_redirect('/feed');
    }
在这里,从 Zend 注册库的 fSession 和 fGet 对象中分别检索了 username 和 feedTitle,这与订阅提要时一样。然后准备了一条 SQL 语句用于删除 subscribedfeeds 表中与给出的 username 和 feedTitle 相匹配的记录。 在下一部分中,将提到浏览这些可用提要。

TOP

查看可用提要

既然用户已经能够订阅提要了,那么他们就应该能够查看已订阅的提要以及每个提要中的摘要。本部分完成了 viewFeeds 视图、查看提要的摘要和 viewChannel 视图。

完成 viewFeeds 视图

在 清单 12 中,开始实现 viewFeeds 视图,现在我们继续完成它,使您能够查看当前可用的提要。完成对 viewFeeds.php 文件的定义,如下所示。


清单 17. 完成 viewFeeds 视图
复制内容到剪贴板
代码:
<html>
<head>
    <title>You're Logged In!</title>
</head>
<body>
...
  <h3>Hello <?php echo $this->escape($this->username); ?>
      you're logged in!</h3>
  Subscribed Feeds:<br>
  <?php
     $ct = 0;
     $feeds = $this->feeds;
     foreach($feeds as $row){
         $feedTitle = $row['feedname'];
         echo "<a href='feed/viewChannel?title=$feedTitle'>".
              "$feedTitle</a><br>";
     }
     ?>
  </table>
</body>
</html>
这里遍历了可用提要,显示出标题并添加了一个查看最新摘要的链接。请注意该行为的名称是 FeedController 类中的 viewChannel 行为。

TOP

发新话题