通过前面两篇文章的学习,你的CakePHP博客已经初具雏形了。本文会构建博客的文章内容页面,添加新的文章,修改老文章以及删除文章的功能,并且涉及到CakePHP表单创建,数据验证,路由规则等主题。如果还没有仔细了解本教程的前两张,可以访问《Cakephp 2.0十分钟博客教程(一):安装与配置》从头开始学习。
CakePHP系列教程—CakePHP博客三部曲:
文章内容页
在上一篇教程当中,我们已经实现了博客文章列表的显示,并且在文章名上包含该篇文章的URL地址。复习下该段代码。
01
02
03
04
|
echo $this ->Html->link(
$post [ 'Post' ][ 'title' ],
array ( 'controller' => 'posts' , 'action' => 'view' , $post [ 'Post' ][ 'id' ])
); |
该URL指向PostsController控制器的View方法,并传递文章的id作为URL参数。如果点击该链接,可以发现URL地址如下所示。
www.example.com/posts/view/id
现在,一起为该页面建立控制器。在PostsController控制器中添加view()方法,代码如下。
01
02
03
04
|
public function view( $id = null) {
$this ->Post->id = $id ;
$this ->set( 'post' , $this ->Post->read());
} |
这段代码非常简单,通过参数获取到文章$id,然后赋予Post模型对象的id属性,接着通过该对象的read()方法读取匹配该id的一行数据,并赋予post变量传递到视图文件中。完成控制器之后,该为文章内容页建立视图文件了,view视图文件路径位于/app/View/Posts/view.ctp。创建该文件,并复制如下代码到该文件中。
01
02
03
04
05
|
<!-- 路径: /app/View/Posts/view.ctp --> <h1><?php echo $post [ 'Post' ][ 'title' ]?></h1>
<p><small>Created: <?php echo $post [ 'Post' ][ 'created' ]?></small></p>
<p><?php echo $post [ 'Post' ][ 'body' ]?></p>
|
完成上述操作之后,访问index页面,点击文章标题,即可访问view页面。一切正常的话,CakePHP会使用默认布局文件显示如下内容。
添加文章 — CakePHP表单助手
显示文章列表以及文章内容是一个好的开始,然而一个简单的CakePHP博客应用必不可少的就是添加新的文章。这次改变下文件创建的顺序,我们首先创建视图文件,来构建博客页面添加文章的表单。事先约定,在PostsController控制器中处理文章添加逻辑的方法为add(),那么相应的模板文件就位于/app/View/Posts/add.ctp。
之前我们说到CakePHP视图层包含许多助手类,其中就有一个FormHelper用于输出HTML表单。将如下代码复制到add.ctp视图文件中。
01
02
03
04
05
06
07
|
<h1>Add Post</h1> <?php echo $this ->Form->create( 'Post' );
echo $this ->Form->input( 'title' );
echo $this ->Form->input( 'body' , array ( 'rows' => '3' ));
echo $this ->Form-> end ( '添加' );
?> |
表单助手类默认可以在任何视图文件中调用,通过$this->Form,即可实例化一个新的FormHelper类对象。上述代码首先通过create()方法,生成了表单头,如下所示,
<form id=”PostAddForm” method=”post” action=”/posts/add”>
在上面的create()方法中,我们传递了Post作为参数,该参数用于指定当前模型名。默认的,如果该方法没有传递任何参数,则假设该表单通过Post方式,默认当前模型,传递表单数据到当前控制器的add()方法中进行处理。
input()方法用于input表单元素。参数一用户匹配数据库的字段,参数二用于指定该表单元素的各种设置,以索引数组形式组织。
end()方法用于生成表单提交按钮,并完成表单HTML代码的结尾部分。该方法如果指定参数,则用于表单提交按钮中的按钮文字。
到此为止,我们的视图文件建立完毕。是时候建立控制器方法处理该表单提交的数据了。在PostsController控制器中添加一个add()方法,并添加如下代码到该方法中。另外需要在控制器中新建一个$components属性,该属性的作用稍后会作解释。
01
02
03
04
05
06
07
08
09
10
11
12
|
public $components = array ( 'Session' );
public function add() {
if ( $this ->request->is( 'post' ) {
if ( $this ->Post->save(( $this ->request->data)) {
$this ->Session->setFlash( '新文章创建完成' ):
$this ->redirect( array ( 'action' => 'index' ));
} else {
$this ->Session->setFlash( '创建文章出错' );
}
}
} |
完成上述代码之后,访问www.example.com/posts/add,会显示如下页面。
add()方法是目前PostsController控制器中最复杂的方法了。首先,通过$this->request获取CakeRequest请求对象,然后判断当前HTTP请求是否为POST类型。还记得吧,上面创建的表单默认是通过POST方式传递数据的,如果是,则$this->Post获取到模型对象,并调用起save()方法保存表单提交来的数据到数据库中。
需要注意的是$this->request->data,上面说到request是获取到了框架封装的CakeRequest类对象,接着获取其data属性中的值。这里实际上就是表单中提交的数据。可以通过CakePHP调试方法pr()输出下该数组,查看该数组的结构。
接着用到了新添加的Session组件,该组件用于设置一段消息并保存在session变量中,该段消息可以在页面转向后显示在视图文件中。相对于控制器中SessionComponent::setFlash()方法设置的字符串消息,在转向后的视图文件中,可以通过SessionHelper::flash()方法显示该消息,显示结束后,系统会自动销毁该变量,再次刷新页面,就不会再次显示该消息。
写好session消息之后,保存成功,页面需要转向到博客的文章列表页,该步骤通过控制器的流程控制方法redirect()进行,该方法同样使用数组形式作为URL地址,上述代码中意思是转向到当前控制器Posts的index()方法。如果想了解更多的关于CakePHP框架的URL组成形式,可以查看Router::url()方法。
到此为止,如果一切正常的话,你应该可以完美添加新的博客了,如下图所示,填写表单并点击提交之后,系统会转向的文章列表页,注意,红色背景显示的文字即我们在控制器中通过SessionComponent::setFlash()方法设置的提示成功的消息,如果再次刷新页面,该消息会自动消失。
CakePHP 表单数据验证
CakePHP模型类中可以通过$validate属性定义表字段的验证规则,该验证规则主要面向用户通过表单提交的数据。在上面的代码中我们通过FormHelper助手类生成了表单代码,如果说在该表单页面中不填写数据直接提交,也可以通过。而这并不是我们想要的结果,一篇博客文章,至少应该包含文章标题和文章内容。
这些验证规则可以通过在相应的模型中的$validate属性进行定义,进入/app/Model/Post.php文件,添加如下代码到Post模型类中。
01
02
03
04
05
06
07
08
|
public $validate = array (
'title' => array (
'rule' => 'notEmpty'
),
'body' => array (
'rule' => 'notEmpty'
)
); |
$validate属性通过上述数组形式进行赋值,根据数据库字段,非常容易该段代码的含义。这里,我们制定‘title’和’body’字段的验证规则为非空(notEmpty)。完成该段代码之后,访问add()访问,提交一个空的或者任意表单域为空的时候,系统会出现禁止提交的提示,如下图所示。
CakePHP的验证系统非常强大,本身内置了如信用卡号,email地址等规则,你也可以自己建立新的验证规则,以适用不同的数据。访问Data Validation获得更多数据验证的信息。另外,CakePHP表单之所以能够关联模型中字段的验证规则,大前提是通过FormHelper表单助手来创建表单元素,如果你是通过HTML标签进行编码,则无法享受CakePHP框架的表单验证功能。
编辑博客
细心的同学可以发现,锐想CakePHP基础教程到目前为止,为大家提供的例子都遵循了一个基本顺序。建立控制器方法,接着再写视图文件(除了表单一节,为了方便大家学习,首先写出的包含表单的视图文件)。接下来,我们继续按照该顺序构建博客的编辑逻辑。
在PostsController控制器中创建edit()方法,赋值如下内容到该方法。
01
02
03
04
05
06
07
08
09
10
11
12
13
|
function edit( $id = null) {
$this ->Post->id = $id ;
if ( $this ->request->is( 'get' )) {
$this ->request->data = $this ->Post->read();
} else {
if ( $this ->Post->save( $this ->request->data)) {
$this ->Session->setFlash( 'Your post has been updated.' );
$this ->redirect( array ( 'action' => 'index' ));
} else {
$this ->Session->setFlash( 'Unable to update your post.' );
}
}
} |
在看上述代码之前,我们需要回忆下大家在编辑老文章时候的顺序。首先你看到的依然是文章列表,然后在文章列表中选择文章进行编辑。
代码中,首先通过URL传递来的参数获取到文章的id。先判断请求是否为GET方式,如果是GET请求,说明是在文章列表页点击编辑链接,此时,我们需要读取该id相对应的数据,然后赋予request对象的data属性,以在视图文件中的表单域显示,方便我们进行修改。接着,else体重,当我们修改完成,点击提交时,该请求一定是POST方式进行。这段代码和save()方法完全一致,不再多做解释。
view()方法相对应的视图文件如下。
01
02
03
04
05
06
07
08
09
|
<!-- File: /app/View/Posts/edit.ctp --> <h1>Edit Post</h1> <?php echo $this ->Form->create( 'Post' , array ( 'action' => 'edit' ));
echo $this ->Form->input( 'title' );
echo $this ->Form->input( 'body' , array ( 'rows' => '3' ));
echo $this ->Form->input( 'id' , array ( 'type' => 'hidden' ));
echo $this ->Form-> end ( 'Save Post' );
|
该视图文件与add()方法的视图文件也没有太大区别,唯一多出的是一个隐藏表单,和使用HTML标签写表单时隐藏域的功能一样,它负责在点击提交按钮时,传递当前编辑的文章id值。另外,添加新的文章与编辑文章的控制器代码实在相似,CakePHP是如何区分两种操作的呢?方法是$id,如果在request对象中的data元素中包含id键,则判定为更新博客;如果没有id值,则判定为添加新博客。
PS:值得注意的是,在进入文章编辑页面时,表单中会显示该条数据到相应的表单字段中。可能大家会想,可以通过$this->Post->read()获取数据,然后赋予一个变量,并以表单value属性值的形式,传递到视图文件中,以实现表单域中显示待编辑内容的效果。但是CakePHP框架已经为我们准备好了一切,我们只需要将值取出后赋予request对象的data属性即可,不需要再多写一行代码。
接着,可以在index.ctp视图中为每一篇文章添加一个修改按钮了。赋值如下内容到之前创建的index.ctp文件中。
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
<!-- 文件路径: /app/View/Posts/index.ctp (添加编辑URL) --> <h1>Blog posts</h1> <p><?php echo $this ->Html->link( "Add Post" , array ( 'action' => 'add' )); ?></p>
<table>
<tr>
<th>Id</th>
<th>Title</th>
<th>Action</th>
<th>Created</th>
</tr>
<!-- 循环输出由控制器中赋值的 $posts 变量 -->
<?php foreach ( $posts as $post ): ?>
<tr>
<td><?php echo $post [ 'Post' ][ 'id' ]; ?></td>
<td>
<?php echo $this ->Html->link( $post [ 'Post' ][ 'title' ], array ( 'action' => 'view' , $post [ 'Post' ][ 'id' ]));?>
</td>
<td>
<?php echo $this ->Html->link( 'Edit' , array ( 'action' => 'edit' , $post [ 'Post' ][ 'id' ]));?>
</td>
<td>
<?php echo $post [ 'Post' ][ 'created' ]; ?>
</td>
</tr>
<?php endforeach ; ?>
</table>
|
删除文章
关于CakePHP数据库的操作进行到了最后一步,删除文章也是博客应用中必不可少的环节。在PostsController控制器中创建delete()方法。
01
02
03
04
05
06
07
08
09
|
function delete ( $id ) {
if ( $this ->request->is( 'get' )) {
throw new MethodNotAllowedException();
}
if ( $this ->Post-> delete ( $id )) {
$this ->Session->setFlash( 'The post with id: ' . $id . ' has been deleted.' );
$this ->redirect( array ( 'action' => 'index' ));
}
} |
delete()方法包含$id参数,该参数用于表示文章,匹配数据库表中的递增id字段,第一个if语句用于判断当前请求的类型,在后边的视图文件中我们会看到,删除操作是通过表单助手的postLink()方法完成的,所以说如果检测到当前请求是GET形式,则很有可能网站遭到了某种黑客攻击或者误操作。
确定没有问题之后,通过Post模型对象的delete方法,即可删除该条数据。非常简单,不是嘛。最后,在index.ctp文章列表视图中,在每条博客后边添加 一个删除博客的链接按钮。
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
<!-- 文件: /app/View/Posts/index.ctp --> <h1>Blog posts</h1> <p><?php echo $this ->Html->link( 'Add Post' , array ( 'action' => 'add' )); ?></p>
<table> <tr>
<th>Id</th>
<th>Title</th>
<th>Actions</th>
<th>Created</th>
</tr>
<!-- Here's where we loop through our $posts array , printing out post info -->
<?php foreach ( $posts as $post ): ?>
<tr>
<td><?php echo $post [ 'Post' ][ 'id' ]; ?></td>
<td>
<?php echo $this ->Html->link( $post [ 'Post' ][ 'title' ], array ( 'action' => 'view' , $post [ 'Post' ][ 'id' ]));?>
</td>
<td>
<?php echo $this ->Form->postLink(
'Delete' ,
array ( 'action' => 'delete' , $post [ 'Post' ][ 'id' ]),
array ( 'confirm' => 'Are you sure?' ));
?>
<?php echo $this ->Html->link( 'Edit' , array ( 'action' => 'edit' , $post [ 'Post' ][ 'id' ]));?>
</td>
<td>
<?php echo $post [ 'Post' ][ 'created' ]; ?>
</td>
</tr>
<?php endforeach ; ?>
</table> |
上述视图文件没有太多值得解释的地方。唯一需要注意的是postLink()方法。该方法在表单助手中定义,使用Javascript创建POST请求完成删除操作。安全提示:通过GET方式构建删除的操作非常危险,用户可以轻易掌握删除动作的URL地址,并更改id信息删除所有内容!
CakePHP路由器
CakePHP框架的默认路由能够满足绝大多数应用程序的需要。对于非常在意用户体验及搜索引擎优化的程序员来说,可能需要在程序构建完毕之后,通过CakePHP路由器更改默认的URL地址,在本教程的最后,我们简单看下CakePHP路由器。
CakePHP的默认响应请求(访问www.example.com)是使用PagesController控制器,然后输出home.ctp视图文件,这些文件都包含在CakePHP框架的核心库中。现在我们通过路由更改默认响应到PostsController控制器的index()方法。首先找到路由配置文件,/app/Config/routes.php。找到如下代码,并替换新的代码。
01
02
03
04
05
|
//注释掉: //Router::connect('/', array('controller' => 'pages', 'action' => 'display', 'home')); //添加代码: Router::connect( '/' , array ( 'controller' => 'posts' , 'action' => 'index' ));
|
对于该段代码,在本教程中不做过多解释,一切正常的话,现在访问www.example.com,就可以直接转向到PostsController控制器的index()方法了。
PS:CakePHP在获取到路由信息的修改知道,会自动完成反向路由的操作。例如,添加上述路由规则之后,任何在视图文件中,通过HtmlHelper助手link()方法的数组参数定义的链接,都会有www.example.com/posts/index自动输出为www.example.com,你不需担心视图中还保留路由更改之前的URL链接。
总结
到此为止,CakePHP基础教程结束。通过上面三章的学习,你已经能够掌握CakePHP框架的各种操作了,好吧,你已经是CakePHP专家了。当然,想要成为专家,需要做的还有很多,如果说CakePHP只有这些小花招,它也就不会风靡PHP社区这么多年,被称作PHP社区中的ROR了。
以后会推出更多CakePHP教程,帮助所有想学习CakePHP框架的同学们跨越英语障碍。值得一说的是,CakePHP相对于ThinkPHP以及CI框架,在国内的流行程度稍低,但是它绝对是值得深入学习的框架。记住一句话,一起向前行,我们一定行。
相关推荐
cakephp 1.3.x 中文手册,部分英文没有翻译,随后翻译。
### CakePHP 2.X 手册知识点概览 #### 一、入门指南 - **启动教程**:本节介绍如何快速上手CakePHP 2.X,包括安装环境配置及基本项目搭建过程。 - **博客教程**:通过创建一个完整的博客应用来学习CakePHP的核心...
CakePHP 2.x的PrettyDebug插件要求CakePHP 2.x CakePHP DebugKit插件安装有关常规帮助,请参见CakePHP文档中的“”。 将PrettyDebug目录放入您的插件目录中,或从composer.json文件所在的目录中的安装插件: ...
CakePHP 2.x的Thumbs插件 该插件可让您从网站上的任何公共图片创建大拇指。 #入门 首先将这个插件分叉或克隆到CakePHP 2.x项目中; 使用插件的路由器将此插件加载到您的bootstrap.php文件中。 CakePlugin :: load...
在CakePHP 2.x框架中,进行多表联合查询(JOIN)和分页查询是数据库操作中的常见需求,尤其在处理复杂数据时显得尤为重要。以下将详细解释如何在CakePHP中实现这些功能。 首先,多表联合查询是通过JOIN语句来完成的...
在CakePHP中,模型(Model)负责处理数据库操作和业务逻辑,视图(View)用于渲染数据并呈现给用户,控制器(Controller)则协调模型和视图,处理用户的请求。这种设计使得代码结构清晰,易于维护和扩展。 二、....
虽然此版本可能较旧,但仍有大量的文档和社区资源可供学习,包括官方文档、论坛讨论和教程,帮助开发者了解和掌握CakePHP 1.2.1.8004的使用。 总的来说,CakePHP 1.2.1.8004稳定版为开发者提供了一个可靠的基础,...
《CakePHP 1.3.21:框架详解与应用实践》 CakePHP是一个基于Model-View-Controller(MVC)架构...虽然现在已经有更新的版本,但 CakePHP 1.3.21仍然是许多项目的基础,它的设计理念和实践经验依然具有很高的学习价值。
2. MVC设计模式:在CAKEPHP中,MVC模式是基础,模型(Model)代表数据和业务逻辑,视图(View)是用户界面,控制器(Controller)是模型和视图之间的中介。用户交互触发控制器,控制器调用模型进行数据处理,然后将结果...
CakeLTE:CakePHP 4.x的AdminLTE插件 安装 您可以使用将此插件安装到CakePHP应用程序中。 推荐的安装作曲家软件包的方法是: composer require arodu/cakelte 依存关系 ,在CakePHP 4中透明地使用Bootstrap 4。 ...
- **ORM(对象关系映射)**:通过ActiveRecord实现数据库操作,允许开发者用面向对象的方式来处理数据库操作。 - **辅助方法(Helper)**:为视图层提供各种功能,如HTML、表单和时间辅助。 - **组件(Component...
2. **快速开发**:蛋糕PHP提供了一系列预设的约定和工具,如自动化路由、数据库迁移、表单处理等,减少了重复编写基础代码的时间。 3. **安全防护**:内置的安全机制包括防止SQL注入、跨站脚本攻击(XSS)以及CSRF...
在本文中,我们将深入探讨如何在CakePHP 2.x框架中实现过滤和搜索功能,以创建一个具有分页的动态用户界面。 CakePHP是基于MVC(模型-视图-控制器)架构的PHP开发框架,它提供了一套强大的工具来简化Web应用的开发。...
CakePHP,另一方面,是一个基于MVC(模型-视图-控制器)架构的PHP框架,它简化了Web应用程序的开发流程,提供了强大的数据库操作和丰富的组件。CakePHP的特点包括: 1. **快速开发**:通过约定优于配置的原则,...
用于 CakePHP 2.x 的 AclManager 该插件允许您通过 Acl 模块轻松管理 CakePHP 2.x 中的权限。 从更新和修复原始源 特征 管理每个节点的权限 更新缺少 ARO(用户、角色等)的数据库 更新缺少 ACO 的数据库(控制器...
CakePHP 2.x的自定义字段插件。 现在,您可以将自定义字段添加到CakePHP应用和各个模型/控制器中。 如何使用 下载或结帐 您可以下载ZIP文件: : 或签出代码(将“密码”字段留空): git clone ...
CakePHP提供ORM(对象关系映射)功能,使得操作数据库更加直观。 6. **Controller**:控制器处理HTTP请求,调用模型进行业务逻辑处理,并决定如何呈现视图。 7. **View**:视图负责渲染用户看到的页面,可以包含...
CakePHP2.x-HybridAuth 插件根据教程创建的 Cakephp HybridAuth 插件它使用 HybridAuth 库 ##设置将文件夹 HybridAuth 复制到您项目中的插件中要激活此插件,您必须编辑一些文件: ###app\config\bootstrap.php 将此...
CakePHP 3 的 AdminLTE 仪表板 安装 跑步: compose require murilolopes/adminlte:dev-master 在项目的 composer.json 中插入以下行: "muriloangelo/adminlte": "dev-master" 使用命令更新: composer ...
CakePHP 3.x Bootstrap的帮助器 CakePHP 3.x Helpers以@Twitter Boostrap样式生成HTML:可用的Breadcrumbs , Flash , Form , Html , Modal , Navbar , Panel和Paginator帮助器! 如何... ? 安装 如果您想要...