430 123
发新话题
打印

Zend 框架学习之提要篇

查看频道中的最新提要

用户单击该链接查看提要的时候,触发了一个新的行为,即 viewChannel 行为。在 FeedController 类中定义此行为,如下所示。


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

        $db = Zend::registry('db');
        $select = $db->select();
        $select->from('feeds', '*');
        $sql = $select->__toString();
        $results = $db->fetchAll($sql);

        foreach ($results as $row)
            $feedLink = $row['link'];
        $rssFeed = Zend_Feed::import($feedLink);
        
        $view = Zend::registry('view');
        $view->title = $feedTitle;
        $view->rssFeed = $rssFeed;
        echo $view->render('viewChannel.php');
    }
此方法从 Zend 注册库的 fGet 对象中检索用户想浏览其摘要的提要名称。链接是从数据库中检索而来的,而 RSS 提要数据则检索自该链接,该链接传递到视图对象,viewChannel 行为也从这个链接中检索摘要和链接数据。

TOP

viewChannel 视图

既然已经获取了 RSS 提要数据,那么让我们把它应用到 viewChannel 视图中,并将这些链接显示给用户。定义 viewChannel 视图,如下所示。


清单 19. 定义 viewChannel 视图
复制内容到剪贴板
代码:
<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>Channel Title (click to read)
        &nbsp&nbsp&nbsp&nbsp&nbsp&nbsp</td>
      <td>Save entry to database</td>
    </tr>
  <?php
     /* Get feeds from the database by title */
     foreach ($this->rssFeed as $item) {
         $entryTitle = $item->title();
         $link = $item->link();
         echo "<tr><td><a
href='$link'>$entryTitle</a></td>";
         echo "<td><a href=\"saveEntry?feedTitle=".
              "$this->title&title=$entryTitle&link=$link\">".
              "Save</a></td></tr>";
     }
?>
  </table>
</body>
</html>
上面视图中的 PHP 代码遍历 rssFeed 对象的每个条目。通过调用 $item->title() 获取摘要名称,而调用 $item->link() 获取文章链接。随后摘要同全文链接一起被显示出来,将此条目保存到数据库的链接一并显示。

TOP

保存、查看及删除提要条目

有了可将条目保存到数据库的链接,您还需要定义适当的行为、赋予视图功能以及在不需要的时候删除这些条目。

保存条目

保存条目使用户稍后还能够查看这些条目。回顾上文,清单 19 中已介绍了将条目保存到数据库的链接,现在您需要定义行为以使用这个功能。在 FeedController 类中定义 saveEntryAction 方法,如下所示。


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

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

        $row = array(
                     'Username' => $username,
                     'feedname' => $feedTitle,
                     'channelname' => $channelTitle,
                     'link' => $channelLink
                     );

        $table = 'savedentries';
        $rowsAffected = $db->insert($table, $row);

        $this->_redirect\
        ("/feed/viewChannel?title=$feedTitle");
    }
上述代码从 Zend 注册库的 fSession 对象中检索 username,从 Zend 注册库的 fGet 对象中检索 feedTitle、channelTitle(摘要名称)以及 channelLink(全文链接)。这四个字段随后被保存为一行,保存在数据库的 savedentries 表中。将数据保存到数据库中后,通过在 URL 中设置相同的 feedTitle,用户即被重定向到 viewChannel 行为。

TOP

查看已保存条目

既然能够将条目保存到数据库中,那么我们需要定义 viewSavedEntries 行为。回顾我们在清单 12 的 viewFeeds 视图中提供的链接。定义 FeedController 类的 viewSavedEntriesAction 方法,如下所示。


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

        $db = Zend::registry('db');
        $select = $db->select();
        $select->from('savedentries', '*');
        $select->where("username=?", $username);
        $sql = $select->__toString();
        $entries = $db->fetchAll($sql);
        
        $view = Zend::registry('view');
        $view->title = 'View Saved Entries';
        $view->entries = $entries;
        echo $view->render('viewSavedEntries.php');
    }
此行为从 Zend 注册库的 fSession 对象中检索 username,然后设置一个查询,检索用户已订阅的所有提要,并将结果传至 viewSavedEntries 视图。

TOP

viewSavedEntries 视图

清单 21 中呈现的视图展示了用户已保存的所有条目。定义 FeedController 类中的 viewSavedEntriesAction 方法,如下所示。


清单 22. 定义 viewSavedEntries 视图
复制内容到剪贴板
代码:
<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 (Click to View)
        &nbsp&nbsp&nbsp&nbsp&nbsp&nbsp</td>
      <td>Delete Channel Entry</td>
    </tr>
  <?php
     /* Get feeds from the database by title */
     foreach ($this->entries as $row) {
         $link = $row['link'];
         $channelTitle = $row['channelname'];
         $feedTitle = $row['feedname'];
         echo "<tr><td><a href='$link'>".
              "$feedTitle > $channelTitle</a></td>";
         echo "<td><a
href=\"feed/deleteEntry?feedTitle=$feedTitle".
              "&channelTitle=$channelTitle&link=$link\">".
              "Delete</a></td></tr>";
     }
?>
  </table>
</body>
</html>
该视图的核心是循环遍历当前用户已保存的所有条目,显示标题和指向全文的链接,以及从数据库中删除该条目的链接。

TOP

删除条目

当用户请求从数据库中删除一个条目之后,deleteEntryAction 方法被调用,将该条目从数据库中删除。在 FeedController 中定义此方法,如下所示。


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

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

        $this->_redirect('/feed/viewSavedEntries/');
    }
上述代码从 Zend 注册库的 fSession 对象中检索用户名,并从 Zend 注册库的 fGet 对象中检索 feedTitle、channelTitle(摘要名称)和 channelLink(全文链接。

这样就完成了我们的提要阅读器!在接下来的部分中,我们将定义最后两个管理任务。

TOP

管理行为

用户还有两个最后的管理任务,即查看/更新账户和退出系统。

更新账户

用户更新账户时,我们可以从 清单 10 中看出,用户名是从 SESSION 数组中检索的,这是不可更改的。要想在注册视图中将其设为可更改,用如下方式对其定义。


清单 24. 修改 register.php
复制内容到剪贴板
代码:
                    
...
  <p>Username:
    <?php
       if($this->button == 'Update')
           echo $this->username .
                '<input name=\
                "username" type="hidden" value="'.
                $this->username . '">';
       else
           echo '<input name="username" value="'.
                $this->username . '">';
    ?>
...
因而,如果用户正在更新自己的账户,系统将显示出用户名,隐藏输入标记,并将其值设为已登录用户的用户名。否则,将显示一个空的文本框。

TOP

下面是 Zend 框架中一视图两用的一个很好的例子。
退出系统

退出系统结束当前会话。在 UserController 类中定义 logoutAction 方法,如下所示。


清单 25. 退出系统
复制内容到剪贴板
代码:
    public function logoutAction()
    {
        session_destroy();
        $this->_redirect('/');
    }
这将结束当前会话并使用户返回到根目录下。祝贺您,我们已经完成了全部的任务。

TOP

结束语

通过新接触到的 MVC 技能和 Zend 数据库技能,加上已添加的 FeedController 及相关视图,您应已能够游刃有余地操作 MVC 模式。并且,通过从互联网中检索 RSS 提要,您掌握了 Zend_Feed 类。另外,您也学到了如何利用 Zend_InputFilter 类中的辅助函数验证输入的数据,而无需忙乱而耗时地编写代码来自行验证。

第 4 部分将探讨使用 Zend_HTTPClient 类从何处检索和将整篇文章(提要条目)存储到数据库中,以及如何将不支持 RSS 提要的可订阅网站添加到提要-阅读器界面,该界面的内容同样是通过 Zend_HTTPClient 可选择地保存到数据库中的。

TOP

下载

描述名字大小下载方法
Part 3 source codeos-php-zend3.source.zip8KBHTTP

TOP

 430 123
发新话题