PHP 框架,第 3 部分: 用户验证

本文通过扩展样例应用程序Blahg,探讨了如何在Zend、symfony和CakePHP三种PHP框架中处理评论功能及不符合常规的例外情况,展示了如何解决框架限制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

对 PHP 早期版本的常见批评是不支持模型-视图-控制器(Model-View-Controller,MVC)样式的架构。现在,开发人员可以在许多 PHP 框架中做出选择。“ PHP 框架” 系列将介绍三个广泛使用的 PHP 框架 —— Zend、symfony 和 CakePHP —— 通过在三个框架中构建和扩展样例应用程序来检验这三个框架的类似之处和不同之处。第 1 部分列出了本系列涵盖的内容并且配置先决条件。在第 2 部分中,您分别在三个框架中构建了样例应用程序。本文是第 3 部分,您将扩展应用程序并处理不符合一般规律的例外情况。

关于本系列

本系列专门针对那些想要开始使用框架、但又没有机会详细检验可用框架的 PHP 开发人员。在学完本系列后,您将了解选择这三个框架的原因、如何安装每个框架,并且充分运用将在三个框架中扩展的测试应用程序。听起来要学习的内容很多,但是不必担心。内容虽然多,但是我们已经把内容细分为多个便于管理的部分。

本系列的 第 1 部分 将列出本系列涵盖的内容,介绍将进行考察的框架以及说明如何安装,并查看将构建的第一个测试应用程序。

第 2 部分 将指导您在三个框架中构建样例应用程序,着重说明了它们的类似之处和不同之处。

第 3 部分从扩展测试应用程序开始,然后处理不符合一般规律的例外情况。所有框架都能很好地完成份内的任务。每个项目中都需要完成一些框架设定工作之外的事情。本文就将介绍那些情况。

第 4 部分主要介绍了 Ajax 支持。使用本机代码和第三方库检验了 Ajax 的使用 —— 特别介绍了每个框架如何运行及接受具体的常用库。

第 5 部分将处理如何在框架外部工作。设定一项任务(每晚更新脚本),并在每个框架中检验完成此项任务的过程。





回页首


关于本文

本文将指导您分别在三个框架(Zend、symfony 和 CakePHP)中扩展样例应用程序 Blahg。然后将了解如何处理不符合一般规律的例外情况。如果应用程序是专门针对框架设计的,那么大多数框架都会执行得很好。但是,如果应用程序刚好与框架不相配会怎样?

您应当已经查阅并理解了本系列的 第 1 部分第 2 部分





回页首


扩展 Blahg

第 2 部分 的结束部分建议您尝试扩展 Blahg 来添加 comments 控制器,从而允许读者发表自己的有新意的独特见解来响应特定 post。您也无需担心如何集成 comments 和 posts 控制器,因为本文将提供一些涵盖其工作原理的代码。当然,它的工作方法会有所不同,这取决于特定时间所使用的框架。但是不管使用哪个框架,都需要有一张 comments 表。





回页首


创建 comments 表

对于 Zend 框架和 symfony,请使用以下 SQL 创建 comments 表。


清单 1. 在 Zend 框架和 symfony 中创建 comments 表
                
CREATE TABLE 'comments' ( 
'id' INT( 10 ) NOT NULL AUTO_INCREMENT PRIMARY KEY , 
'post_id' INT( 10 ) NOT NULL , 
'text' TEXT NOT NULL , 
'created' TIMESTAMP ON UPDATE CURRENT_TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP 
) ENGINE = MYISAM ;

对于 CakePHP,请使用以下 SQL。


清单 2. 在 CakePHP 中创建 comments 表
                
CREATE TABLE 'comments' ( 
'id' INT( 10 ) NOT NULL AUTO_INCREMENT PRIMARY KEY , 
'post_id' INT( 10 ) NOT NULL , 
'text' TEXT NOT NULL , 
'created' DATETIME DEFAULT NULL 
) ENGINE = MYISAM ;

comments 表准备好后,就可以添加 comments 功能来实现我们的想法了。





回页首


用 Zend 框架添加评论

用 Zend 框架添加评论类似于创建 posts 功能时所执行的操作。创建一个 comments 模型来为评论处理数据库交互,而且当然是由 comments 控制器来完成实际工作。但是不需要任何视图,因为在阅读 post 时将显示评论。

实际情形大可不必如此。可以把评论视为 posts 的逻辑部分并决定把这些评论包含到同一个控制器、模型中。因此,我们可以把 posts 视为没有父节点的评论并且在一张表内执行所有操作。如果需要,也完全可以在一个 PHP 文件中编写 Blahg,但不意味着它就是一个好主意。这其中的思想是把应用程序划分为不同的功能块。

comments 模型看上去就像 posts 模型一样,只是名称变了而已。可以使用继承自 Zend_Db_Table 的方法来执行任何必要操作。如前述,无需使用任何特定于 comment 的视图,但是需要修改 posts read 视图才能输出所有评论并包括允许人们发表评论的表单。此表单将指向 comments 控制器的 write 操作。

comments 控制器看上去很像 posts 控制器的精简版,因为只需要 writeAction。但有一点重要差别:在写入数据后,需要把用户重定向到提交评论时正在阅读的 post。对于 posts 控制器,还需要修改 readAction 才能检索每个 post 的评论并将这些评论分配到视图中。

代码归档文件 中查找如何完成所有这些操作的示例。您可能会提出其他解决方案。那很好。现在已经用 Zend 添加了评论,接下来将查看如何在 symfony 中添加评论。





回页首


用 symfony 添加评论

要用 symfony 版的 Blahg 添加评论,需要从 schema.yml(应当位于 /column/protected/sf_column/config 中)开始并为 comments 表添加一些定义。需要添加下面几行:


清单 3. 用 symfony 添加评论
                
  comments :
    _attributes: {phpName: Comment }
    id:
    post_id:
    text:    longvarchar
    created: timestamp

像以前一样,如果复制并粘贴该文本,请确保在 comments 前加两个空格的缩进并且在 comments 下的元素前加四个空格的缩进。空格十分重要。

注:像 CakePHP 一样,如果将 created 和 modified 列分别命名为 created_atmodified_at,那么 symfony 将为您变一些魔术。在本例中,将由 MySQL 数据库完成这个魔术。

完成后,需要构建 propel 模型并清除缓存。在命令行中,从 /column/protected/sf_column 执行以下命令:

php /column/src/symfony/data/bin/symfony propel-build-model
php /column/src/symfony/data/bin/symfony clear-cache 

运行这些命令后,您应当会在 /column/protected/sf_column/lib/model 目录中看到 Comment.php 和 CommentPeer.php 文件。现在准备好了模型,可以加快完成 comments 功能的其余部分。

注:这一点应当已经在第 2 部分中提到过,但是如果使用 PHP 扩展和应用库(PHP Extension and Application Repository,PEAR)安装了 symfony,则可以只运行 symfony propel-build-model 而无需先调用 PHP 或者提供该二进制的完整路径。并不是每个人都可以在自己的环境中使用 PEAR 安装,这就是介绍备选安装说明的原因。

现在模型已经就绪,需要修改 /column/protected/sf_column/apps/blahg/modules/post/actions/ 中的 actions.class.file.php 来为评论添加一些选择条件并把评论分配给 post。还需要对 /column/protected/sf_column/apps/blahg/modules/post/templates/ 目录中的 readSuccess.php 文件做一些修改来输出给定 post 的评论。有关两者的详细信息,请参阅 代码归档文件 中的文件。

接下来,需要用 init 为 Blahg 初始化 comment 模块。从 /column/protected/sf_column 目录运行以下命令:php /column/src/symfony/data/bin/symfony init-module blahg comment

接下来,把 executeWrite 操作添加到位于 /column/protected/sf_column/apps/blahg/modules/comment/actions/ 目录的 actions.class.php 中。此操作类似 post 模块中的 executeWrite 操作,不同之处是在写入后需要重定向回正在阅读的 post。

最后,需要修改 posts 模块的 readSuccess.php 文件,添加一张允许读者发表评论的表单。这段代码全都包含在 代码归档文件 中。





回页首


用 CakePHP 添加评论

要将评论添加到 CakePHP 版的 Blahg 中,需要一个 comments 控制器(用于处理 comments 的输出),但是更重要的是,需要编写一个 comment 模型并定义 comment 与 post 之间的关联。在指定一个 post “有多条” 评论而一条评论 “属于” 一个 post 之后,检索 post 的查询将检索该 post 的评论。在 CakePHP 中,这些被称为模型关联

如果查看 代码归档文件 中更新后的 CakePHP 版本的 Blahg,可以看到一个十分典型的 comments 控制器 (comments_controller.php),但是与 posts 控制器明显不同的是: 变量 autoRender 设为 false。这将使您可以使用控制器中的操作而无需视图。如果没有把 autoRender 设为 false,将导致在提交评论时出现 “缺少视图” 错误。另外代码归档文件提供了新的 comment 模型和对 post 模型的更改,可以反映模型关联。正如您看到的那样,在理清了模型关联后,CakePHP 将为您完成大部分工作。





回页首


不符合一般规律的例外情况

目前为止,所编写的 Blahg 一直都符合每个框架并利用了它们提供的优点。这样做十分简单。只要使用的框架可以说明应用程序需要完成的操作,它就可以正常运行。但是如果应用程序与框架不相配该怎么办?

如果您发现自己陷入了这种困境,首先应当问自己:为什么使用一个不允许定义应用程序的框架?答案可能包含以下几种。该框架可能是预先存在的并且不可能进行替换。该框架可能是您的老板惟一认可的框架。也可能是您的应用程序十分与众不同,市场上没有一个框架能够真正适合您的模型。如果遇到这种情况,在开始尝试将应用程序中的独特部分与某个不同形式的框架强制绑在一起之前,请确保应用程序有意义并且是使用有意义的方法构造的。

确实需要让应用程序那样工作?如果是,也可以解决问题。让我们谈谈如何扩展框架。





回页首


问题

您可以在 Blahg 发表内容,而且读者现在可以对您所说的内容作出响应。但是,如果能够一眼就能知道 Blahg 所涉及的内容就太好了。您可以给它冠上很棒的标题,能够涵盖所涉及的主题,如 “World of Spatulas” 或 “Polka for the Rest of Us”,但是您无法控制读者可能在其 post 中谈论哪些内容。并且有时可能觉得在谈论其他内容。或者您可能刚好是一名数学怪才并且需要一些数字。

一个可行的解决方案是获得传入的内容、对使用的单词进行统计,并提供 Blahg 中最常用单词的小列表。问题是:在哪里完成该操作?您可以认为它是一项在模型层完成的任务,因为要给数据分类。也可以认为它是一项控制器任务,因为需要进行一些分析,而且分析意味着逻辑。而且如果需要查看这些数字,还需要在视图中显示内容。但是用户永远不会真正访问 words 控制器。如何扩展框架来完成上述操作?

为了凸显这种基本方法,需要一张用于保存单词的表(让我们把该表称为 “words”)。这张表将保存单词及单词已经出现的次数。可以使用清单 4 中的语法来定义这张表。


清单 4. 保存单词的表
                
CREATE TABLE 'words' ( 
'id' INT( 10 ) NOT NULL AUTO_INCREMENT PRIMARY KEY , 
'word' varchar(255) NOT NULL,
'occurrences' INT( 10 ) NOT NULL
) ENGINE = MYISAM ;

执行单词分析的代码需要:

  1. 删除所有 HTML(无论如何都应当执行的操作)
  2. 删除不是空格的非首字母字符(空格将搞乱省略符号,但是它是很好的起点)
  3. 用单个空格字符替换多个空格字符
  4. 全部小写
  5. 删除空格
  6. 通过得到的数组生成单词统计
  7. 用新统计更新 words 表,添加新单词行并更新已经在该表中的单词行

听起来内容很多,但是不必担心。编写代码时将使用 MVC。从本质上说,最终将得到一个处理 words 表的模型,一个让您查看单词统计的视图,以及一个执行某个逻辑的控制器。





回页首


在 Zend 中添加单词统计

如果需要做的就是编译单词统计而无需显示,则可以使用 Zend_Controller_Plugin_Abstract 来解决这个问题。但是由于实际上需要能够查看单词统计,因此用模型和控制器来构建一个 words 模块可能更有意义。模型将是十分基本的模型,像已经为 Zend 构建的其他模型一样。控制器将有一个用于检索和显示单词统计的 indexAction 方法,但是还将需要一个用于处理文本的方法:processText。此方法不以 Action 为结束。这是故意的。index 视图也非常简单:它需要迭代单词列表并将它们输出到屏幕中。

indexAction 的代码十分简单。只需获得单词,按计数排序(降序)。但是 processText 方法的代码必须多执行一些操作。它需要划分文本,分解为一个数组,并计算每个单词的出现次数。然后代码需要从 words 表中获得单词并将这些单词放到列表中。如果单词位于 master 列表中,则需要用新统计更新行。如果单词是新的,则需要插入带有该单词的一行。这一切都非常简单。您可以在 代码归档文件 中看到所有代码。

要在 posts 和 comments 控制器中使用 processText 方法,首先需要有 WordController.php 文件。在 writeAction 中,需要创建 WordController 的实例。执行此操作时,需要传入 RequestResponse 对象。然后只需调用 processText 方法,就像它是任何旧对象中的方法一样。对于 posts,请不要忘记传入标题 文本。

提示:如果在通过 StripTags 过滤器传递文本之后 再传入文本,那么之后无需去掉标记。它可能类似如下所示的内容:

$wc = new WordController($this->_request, $this->_response);
$wc->processText($data['title'] . ' ' . $data['text']);

有关详细信息,请查阅 代码归档文件。一切就绪并且修改了 posts 和 comments 控制器之后,应当能够输入一些 post 和 comment,并且能够在 http://localhost/zend/word 查看单词统计更新。

注:在大量设置时可能需要以略微不同的方式编写一些代码。此处的目的不是向您展示如何完成文本解析单词统计分析,而是使用它演示如何实现框架所涉及不到的内容。





回页首


在 symfony 中添加单词统计

正如您猜想的那样,需要做的第一件事是将 words 表的定义添加到 schema.yml 配置文件中。牢记正确的缩进,定义应当类似清单 5。


清单 5. 将 words 表的定义添加到 schema.yml 文件中
                
  words 
    _attributes: {phpName: Word }
    id:
    word:    varchar(255)
    occurrences:   integer

接下来做什么?没错 —— 需要构建模型并清除缓存,就像在上面添加 comments 时所做的操作一样。然后需要用 init 初始化一个 word 模块。确保从 /column/protected/sf_column 目录运行所有那些命令。

继续操作并先完成简单的部分。我们知道 word 模型将只完成用户可以访问的部分:显示 words 表中的单词列表。通过查看 posts 模块,您可以了解 executeIndex 操作和 indexSuccess 模板究竟是怎样的。

由于简单部分已经解决,因此需要对来自 posts 和 comments 的文本进行解析、计算等。一种实现方法是在 actions.class.php 中为 word 模块创建一个名为 executeParsetext 的操作,并在保存了 post 或评论后转发给该操作。在此之前,应当先设置一个 ID 来保存 post ID,这样我们才能知道返回位置。在 posts 模块的 actions.class.php 中,它可能类似如下内容:

$this->id = $post->getId();
$this->forward('word', 'Parsetext');

在转发给其他模块后,需要提取传递的变量。这真是有点棘手。获得变量的代码类似如下内容:

$vars =
$this->request->getContext()->getActionStack()->getFirstEntry()->/
getActionInstance()->getVarHolder()->getAll();

注:看上去真的应该有种更简单的方法来完成这项工作。另一种技巧是在 flashMessage 中设置值并转发它,但是看上去并没有改变多少。如果有更好的方法来完成此操作,欢迎您提交反馈。

获得变量后,请像以前一样分解文本并使用 word 模型来保存相应的行。要使用这个操作来解析 posts 和评论的文本,请确保用 init 将标题变量初始化。完成后,可以重定向回 posts 模块,并且由于保存了 post ID,因此可以直接去读取它。

所有这些代码都包含在 代码归档文件 中。在继续查看如何在 CakePHP 中执行同样操作之前请先花些时间查看这些代码。





回页首


在 CakePHP 中添加单词统计

在 CakePHP 中,将分两个部分实现此功能。我们将构建的内容称为组件,它是一种控制器助手,并且此组件将处理文本。然后将为单词创建一个标准模型、控制器和视图查看数据库中的单词列表。posts 和 comments 控制器将使用 words 模型来保存处理后的单词统计。

要创建 WordcountComponent,请在 /column/protected/cakephp/app/controllers/components 目录中创建一个名为 wordcount.php 的文件。把 WordcountComponent 类定义为 object 的扩展并使用已经熟悉的代码创建 processText 方法以去掉标记、分离并把文本计入数组。这个方法应当返回单词统计数组。

使用已经了解的 CakePHP 知识,创建一个基本的模型、视图和控制器,用于获得 word 表内容并在执行索引操作时显示。应当不需要任何其他操作。

在 posts 和 comments 控制器中,需要添加几行来说明正在使用 word 模型和新组件:

var $uses = array ('Post', 'Word');
var $components = array('Wordcount');

一切就绪后,需要将代码添加到两个控制器的 write 操作中以去掉标记、将文本传递给 WordcountComponent、获得 words 表的内容、迭代 WordcountComponent 所返回的单词统计数组并相应地保存。至此,您应当充分了解所有这些操作,同样,完成这些操作的代码包含在 代码归档文件 中。





回页首


结束语

无论在框架中投入多少精力,都没有一种方法可以让一个框架能够处理 PHP 开发人员可以构建的所有可能的应用程序。框架越严格,在处理不符合一般规律的例外情况时就越不灵活。在最初选择框架的过程中,需要查看框架将如何处理您的独特需求。忘掉创建/读取/更新/删除(Create/Read/Update/Delete,CRUD)吧。大多数框架都能很好地完成前述几个操作。框架能够满足您的需求才能显示出它的力量。您可能也需要调整思路做出让步,但是过于严格的框架将不能满足多功能性要求。

看看是不是还能提出框架无法满足的其他独特问题。然后研究文档并查看是否可以解决问题。或者,如果解决起来有困难,请提出一种好方法来忽略单词统计过程中过于常见而无用的单词,例如条款、前置词、代名词等。

在第 4 部分中将使用 Ajax 并了解如何使用本机代码和第三方库,具体地说就是每个框架如何运行和接受特定的常用库。






回页首


下载

描述名字大小下载方法
第 3 部分的样例代码os-php-fwk3.source.zip21KBHTTP
关于下载方法的信息


参考资料

学习
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值