注意!
本指南针对cake_0.9.1_dev 发布版不是SVN的版本。请不要把指南的代码改成于SVN一样。

Cake 指南:建立一个简单的Blog

这是一个还在不断变化的一个应用框架的指南。文章中的东西可能可以运行,但是如果有些东西无法运行,请您先仔细阅读 API 文档。错误报告对我们很有价值,所以,请报告任何影响您使用的地方。

注意:命名方法的约定已经从下划线_风格变成了骆驼回归法则。所以,在我们目前的发布版中link_to()已经变成linkTo()

默认Cake目录结构一览

在本篇指南中,我们将一起使用Cake来创建一个简单的Blog应用。我假设你对PHP十分了解,可以在你的系统中游刃有余(包括从命令行中运行程序),同时已经有一个配置好的开发服务器环境,例如运行PHP的 XAMPP。

下载

下载最新的Cake 包并解压缩到你的Web服务器的DOCUMENT_ROOT下(因为本文是指南的缘故,我假设他可以从http://localhost/cake/ 下访问)。你可以看到基本的目录结构。

创建数据库

创建一个用来存放Blog帖子的表格,并且初始化一些数据。以下是SQL语句:

CREATE TABLE posts (
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(50),
body TEXT,
created DATETIME DEFAULT NULL,
updated DATETIME DEFAULT NULL
);
INSERT INTO posts (title,body,created)
VALUES ('The title', 'This is the post body.', NOW());
INSERT INTO posts (title,body,created)
VALUES ('A title once again', 'And the post body follows.', NOW());
INSERT INTO posts (title,body,created)
VALUES ('Title strikes back', 'This is really exciting! Not.', NOW());

注意表名称是复数形式, 这是Cake使用的所有表格的默认形式。还有,idcreatedupdated字段是有特殊含义的,等一会儿你就会发现。也就是说现在你不应该更改他们的名字

配置Cake的数据库设置

若要配置数据库访问,我们编辑 config/database.php.default (他应该是自己包含说明的), 并将它保存为config/database.php. 如果config/database.php 不存在,Cake仍会运行,并且不使用数据库访问。

创建一个模型类 (MVC中的Model)

现在给帖子表格posts创建一个模型类,新建 app/models/post.php包含以下内容 :

app/models/post.php

<?php
class Post extends AppModel
{}
?>

这已经足以使Cake来关注这个模型了,载入、并把它和数据库表格连接在一起。注意:模型类的类名是单数形式。坚持命名约定十分重要,因为如果不这样,Cake就不会自动运行。默认情况下,模型类和数据库表使用同一个单词而前者以单数形式,后者是复数形式。

建立一个控制器助手类

新建一个控制器助手类。把下面的内容放在 app/helpers/posts_helper.php中:

app/helpers/posts_helper.php

<?php
class PostsHelper extends AppController
{}
?>

创建一个控制器类 (Controller)

新建一个控制器类. 把下面的内容放在 app/controllers/posts_controller.php中:

app/controllers/posts_controller.php

<?php
class PostsController extends PostsHelper
{}
?>

控制器已经准备好了,这是我们需要在他里面添上行为(Action)来对存储的数据进行操作。添加一个方法到 PostsController 类中 :

app/controllers/posts_controller.php

<?php
class PostsController extends PostsHelper
{function index()
{}
}
?>

PostsController::index() 不需要其他内容了,除了需要一个模版(在Cake中称之为视图“View”)。

建立一个视图 (View)

把下面的代码放入 app/views/posts/index.thtml:

<h1>Blog posts</h1>
<table>
<tr>
<th>Id</th>
<th>Title</th>
<th>Created</th>
</tr>
<?php foreach ($this->models['post']->findAll() as $post): ?>
<tr>
<td><?php echo $post['id']?></td>
<td>
<?php echo $html->linkTo($post['title'], "/posts/view/{$post['id']}")?>
</td>
<td><?php echo $post['created']?></td>
</tr>
<?php endforeach; ?>
</table>

这应该可以正确运行,我们来测试一下。我假设你可以通过浏览http://localhost/cake/ 来得到Cake目录,这样测试一下我们的新控制器,它指向http://localhost/cake/posts/index 。你会(希望如此)看到类似于下面的一些东西:

Blog posts
ID      Title                   Created
1   The title           2005-07-03 10:52:21
2   A title once again  2005-07-03 10:52:34
3   Title strikes back  2005-07-03 10:52:43

为什么我没看到呢?

如果你遇到了一个页面,上面说“not Found: The requested URL /posts/index was not found on this server,”你可能要使用 http://localhost/cake/index.php?url=posts 来访问 . 很明显,这很不美观。如果你遇到了一个页面上说“Fatal error: Call to a member function on a non-object ...”那么你可能要检查一下你的配置内容,有没有把config/database.php.default 改名为config/database.php. 参见 Blog指南中的故障及解决方法。

我们现在做了些什么?

让我们回顾一下。我们创建了数据库表posts,一个模型类Post,一个控制器PostsController 和他的index()方法,还有一个视图文件app/views/posts/index.thtml。我觉得他一点也不困难。让我们继续吧。

帖子标题是连接到/cake/posts/view/[post_id]的. 让我们点击它。

Missing action
You are seeing this error because the action is not defined in controller Posts
Notice: this error is being rendered by the app/views/errors/missing_action.thtml view file,
a user-customizable error page for handling invalid action dispatches.
Error: Unable to execute action on Posts

噢~,对了,我们忘记添加PostsController::view()行为了。让我们现在完成它:

app/controllers/posts_controller.php

<?php
class PostsController extends PostsHelper
{function index()
{}
function view($id)
{$this->models['post']->setId($id);
$this->set('data', $this->models['post']->read());
}
}
?>

还有视图文件:

app/views/posts/view.thtml

<h1><?php echo $data['title']?></h1>
<p><small>Created: <?php echo $data['created']?></small></p>
<p><?php echo $data['body']?></p>

回到浏览器,刷新,看到:

The title
Created: 2005-07-04 03:31:47
This is the post body.

成功了!

添加功能

在指南的第一部分之后,我们有了一个帖子的列表,同时我们可以查看帖子了。当我们完成了第二部分,我们可以:

  • 添加一个新的帖子。
  • 删除不要的帖子。
  • 编辑存在的帖子。

添加一个新的帖子

添加一个新的帖子:

app/controllers/posts_controller.php

<?php
class PostsController extends PostsHelper
{function index()
{}
function view($id)
{$this->models['post']->setId($id);
$this->set('data', $this->models['post']->read());
}
function add()
{if (empty($this->params['data']))
{$this->render();
}
else
{if ($this->models['post']->save($this->params['data']))
{$this->flash('Your post has been saved.','/posts');
}
else
{$this->set('data', $this->params['data']);
$this->validateErrors($this->models['post']);
$this->render();
}
}
}
}
?>

同时行为的模版文件是:

app/views/posts/add.thtml

<h1>Add post to blog</h1>
<?php echo $html->formTag('/posts/add')?>
<p>Title: <?php echo $html->inputTag('post/title', 40)?> <?php echo $html->tagErrorMsg('post/title', 'Title is required.') ?></p>
<p>Body:  <?php echo $html->areaTag('body') ?> <?php echo $html->tagErrorMsg('post/body', 'Body is required.') ?></p>
<p><?php echo $html->submitTag('Save') ?></p>
</form>

现在你可以通过地址"/cake/posts/add"来访问 add 页面page at the address "/cake/posts/add", 或者,我们可以在索引页面的底部放上一个快捷的“Add new post”连接:

app/views/posts/index.thtml

<h1>Blog posts</h1>
<table>
<tr>
<th>Id</th>
<th>Title</th>
<th>Created</th>
</tr>
<?php foreach ($this->post->findAll() as $post): ?>
<tr>
<td><?php echo $post['id']?></td>
<td>
<?php echo $html->linkTo($post['title'], "/posts/view/{$post['id']}")?>
</td>
<td><?php echo $post['created']?></td>
</tr>
<?php endforeach; ?>
</table>
<?php echo $html->linkTo('Add new post', '/posts/add') ?>

现在让我们试试添加一些帖子。

像我这样没规矩的,添加了一个没有标题的帖子。当然,我们可以通过数据有效性检验(Data Validation)来避免这种不正确的行为。

数据有效性

数据有效性规则是放在数据模型中的。

app/models/post.php

<?php
class Post extends AppModel
{var $validate = array(
'title'=>VALID_NOT_EMPTY,
'body'=>VALID_NOT_EMPTY);
}
?>

了解API文档中更多关于有效检验器的内容。

删除一个帖子

app/controllers/posts_controller.php

<?php
class PostsController extends PostsHelper
{function index()
{}
function view($id)
{$this->models['post']->setId($id);
$this->set('data', $this->models['post']->read());
}
function add()
{if (empty($this->params['data']))
{$this->render();
}
else
{if ($this->models['post']->save($this->params['data']))
{$this->flash('Your post has been saved.','/posts');
}
else
{$this->set('data', $this->params['data']);
$this->validateErrors($this->models['post']);
$this->render();
}
}
}
function delete($id)
{if ($this->models['post']->del($id))
{$this->flash('The post with id: '.$id.' has been deleted.', '/posts');
}
}
}
?>

delete 行为没有模版。在成功删除之后,我们只要显示一个快捷消息(所谓的“flash”),然后转回索引页面。

现在我们添加一个删除行为的连接到每一个blog帖子的视图中:

app/views/posts/index.thtml

<h1>Blog posts</h1>
<table>
<tr>
<th>Id</th>
<th>Title</th>
<th>Created</th>
</tr>
<?php foreach ($this->post->findAll() as $post): ?>
<tr>
<td><?php echo $post['id']?></td>
<td>
<?php echo $html->linkTo($post['title'], "/posts/view/{$post['id']}")?>
<?php echo $html->linkTo('Delete',"/posts/delete/{$post['id']}", null, "Are you sure you want to delete post entitled /'{$post['title']}/'?")?>
</td>
<td><?php echo $post['created']?></td>
</tr>
<?php endforeach; ?>
</table>
<?php echo $html->linkTo('Add new post', '/posts/add') ?>

在完成它之后,我们就可以删除那些空白标题的帖子了。

编辑帖子

app/controllers/posts_controller.php

<?php
class PostsController extends PostsHelper
{function index()
{}
function view($id)
{$this->models['post']->setId($id);
$this->set('data', $this->models['post']->read());
}
function add()
{if (empty($this->params['data']))
{$this->render();
}
else
{if ($this->models['post']->save($this->params['data']))
{$this->flash('Your post has been saved.','/posts');
}
else
{$this->set('data', $this->params['data']);
$this->validateErrors($this->models['post']);
$this->render();
}
}
}
function delete($id)
{if ($this->models['post']->del($id))
{$this->flash('The post with id: '.$id.' has been deleted.', '/posts');
}
}
function edit($id=null)
{if (empty($this->params['data']))
{$this->models['post']->setId($id);
$this->params['data']= $this->models['post']->read();
$this->render();
}
else
{$this->models['post']->set($this->params['data']);
if ( $this->models['post']->save())
{$this->flash('Your post has been updated.','/posts');
}
else
{$this->set('data', $this->params['data']);
$this->validateErrors($this->models['post']);
$this->render();
}
}
}
}
?>

app/views/posts/edit.thtml

<h1>Edit post to blog</h1>
<?php echo $html->formTag('/posts/edit')?>
<input type="hidden" name="data[id]" value="<?php echo $html->tagValue('id')?>"/>
<p>Title: <?php echo $html->inputTag('post/title', 40)?>
<?php echo $html->tagErrorMsg('post/title', 'Title is required.') ?></p>
<p><?php echo $html->areaTag('body') ?>
<?php echo $html->tagErrorMsg('post/body', 'Body is required.') ?></p>
<p><?php echo $html->submitTag('Save') ?></p>
</form>

你也可以在表单标签中用

<?php echo $html->hiddenTag('id')?>

来代替直接使用html的<input>标签。

同时, 在 index.thtml 中, 我们添加一个编辑连接:

<h1>Blog posts</h1>
<table>
<tr>
<th>Id</th>
<th>Title</th>
<th>Created</th>
</tr>
<?php foreach ($this->post->findAll() as $post): ?>
<tr>
<td><?php echo $post['id']?></td>
<td>
<?php echo $html->linkTo($post['title'], "/posts/view/{$post['id']}")?>
<?php echo $html->linkTo('Delete',"/posts/delete/{$post['id']}", null, "Are you sure you want to delete post entitled /'{$post['title']}/'?")?>
<?php echo $html->linkTo('Edit',"/posts/edit/{$post['id']}")?>
</td>
<td><?php echo $post['created']?></td>
</tr>
<?php endforeach; ?>
</table>
<?php echo $html->linkTo('Add new post', '/posts/add') ?>

从视图中分离逻辑

让我们回头看一下 index.thtml 视图:

app/views/posts/index.thtml

...
<?php foreach ($this->post->findAll() as $post): ?>
...

我们应该从视图中删除 findAll() 的调用,然后把它放在控制器重。这可以建立一种更好的逻辑和视图的分离。然后我们从控制器重为视图获取数据。现在就让我们完成它吧。

在帖子的控制器中,我们从posts模型中获取所有的记录,并且储存在变量 data 中。

app/controllers/posts_controller.php

<?php
...
function index ()
{$this->set('data', $this->models['post']->findAll());
}
...
?>

同时在视图中,我们通过对每行数据的迭代,来全部显示他的内容。

app/views/posts/index.thtml

...
<?php foreach ($data as $post): ?>
...

这太简单了,不是么?


ShiningRay @ Nirvna Studio


文章来源: http://shiningray.cnblogs.com/archive/2005/08/05/207807.html

[转]Cake 指南:建立一个简单的Blog相关推荐

  1. 使用uliweb创建一个简单的blog

    1.创建数据库 uliweb的数据库都在models.py文件里面,因此先创建该文件 vim apps/blog/models.py 添加如下两行: #coding=utf-8 from uliweb ...

  2. 机器人坐标系建立_如何在30分钟内建立一个简单的搜索机器人

    机器人坐标系建立 by Quinn Langille 奎因·兰吉尔(Quinn Langille) 如何在30分钟内建立一个简单的搜索机器人 (How to Build A Simple Search ...

  3. stm32单片机c语言入门,STM32入门教程1,初学者入门,从零开始,使用keil建立一个简单的ST...

    本文讲述的是如何从零开始,使用keil建立一个简单的STM32的工程,并闪烁LED灯,给小白看. 第零步,当然首先你得有一个STM32的板子,其IO口上接了一个LED... 第一步,建立一个文件夹0. ...

  4. bat 删除文件_利用电脑文本文档建立一个简单方便的删除文件的小程序

    删除文不需要的文件或者资料,是日常工作中必定会遇到了. 各种的杀毒软件或者防护软件都具备删除文件的功能,例如360.腾讯电脑管家.这些操作起来其实也不是太麻烦! 不过呢!今天来和大家分享一个更简单的方 ...

  5. tensorflow学习笔记二——建立一个简单的神经网络拟合二次函数

    tensorflow学习笔记二--建立一个简单的神经网络 2016-09-23 16:04 2973人阅读 评论(2) 收藏 举报  分类: tensorflow(4)  目录(?)[+] 本笔记目的 ...

  6. 一个简单的blog系统(九) 增加标签和标签页面

    一个简单的blog系统(九) 增加标签和标签页面 1.现在,我们来给博客添加标签和标签页面. 假定每篇文章最多只有两个标签,当单机主页左侧标签页链接的时候,跳转到标签页并且列出所有已经有的标签,当单击 ...

  7. 一个简单的blog系统(十一) 增加文章检索功能

    一个简单的blog系统(十一) 增加文章检索功能 1. 现在,我们就来给博客添加文章检索功能.假定,可以根据关键字魔木查询文章标题,也就是说支持正则表达式,而且字母不会区分大小写. 1.1 首先,我们 ...

  8. 一个简单的blog系统(四) 实现用户页面和文章页面

    一个简单的blog系统(四) 实现用户页面和文章页面 1.现在我们来给博客添加用户页面和文章页面. 1.1 所谓用户页面就是当单击某个用户名链接时,跳转到:域名/u/用户名,并且跳出该用户的所有文章. ...

  9. Hibernate学习——建立一个简单的Hibernate项目

    最近老师让做个web小应用,大三的时候学习过一点J2EE的东西,也做过一些web相关的XXX管理系统,都是用servlet,jsp这些完成的,虽然勉强能够完成任务,但其中各种代码掺杂在一起,不好看而且 ...

  10. 一个简单的blog系统(十二) 增加友情链接页面

    一个简单的blog系统(十二) 增加友情链接页面 1.首先,我们打开header.ejs,在其中添加一行代码,并作出响应修改: <li><a href="/links&qu ...

最新文章

  1. CodeForces - 1400G Mercenaries(容斥原理)
  2. LeetCode #43字符串相乘
  3. 基于java的信访项目_基于JAVA的某省人大信访信息系统的设计与实现
  4. 在Windows Server 2016 Core上运行SQL Server容器
  5. 无需activity获得屏幕尺寸
  6. java宿舍管理系统主要功能_Java学生宿舍管理系统主要内容及特点
  7. 英特尔核显驱动hd630_hd630相当于什么显卡
  8. ckeditor5-vue自定义图片上传函数
  9. 苹果尝试支持AdobeFlash,结果尴尬了
  10. Pyton学习—循环语句
  11. opencv 二值图像的孔洞填充
  12. 关于计算机算法的ppt,中科院计算机算法分析与设计_习题3-4_答案.ppt
  13. 准确率,召回率,mAP,ROC,AUC,特异性,敏感性,假阴性,假阳性
  14. mysql到底是什么_MySQL数据库之MySQL到底是什么
  15. BOM:window对象的方法之定时器setTimeout()和停止setTimeout()定时器
  16. Apache AzKaban 环境搭建与入门使用
  17. 【变色龙】app封装系统源码+某站在售封装系统
  18. 【原创】山西 - 大同 太原 4日游
  19. wowslider.js 裂变bannber效果插件
  20. C语言循环水题,科学网—水文模型大本营 - 陈昌春的博文

热门文章

  1. turtle绘制哔哩哔哩小电视
  2. 华科计算机博士公寓宿舍,华中科技大学宿舍条件,宿舍环境图片(10篇)
  3. Ant Design中如何遍历渲染图标
  4. s3c2410--watchdog
  5. 基于51单片机超声波智能垃圾桶系统
  6. 全志V851S开发版无法正常挂载TF卡,sdc0、sdc1报错
  7. 性能优化--缓存(Redis)
  8. 第四类计算机微处理器,工程用600千瓦柴油发电机组性能诚信互利
  9. 122Echarts - 关系图(Les Miserables)
  10. 获取时间差(类似微信朋友圈消息的时间显示)