search
HomeBackend DevelopmentPHP TutorialCake PHP framework [转]

发布时间:2005-10-19
  这是一个基于 PHP 的 framework 。它的作者称 Cake PHP framework 的设计思想源自 37signals 的 Ruby on Rails ,一个最近非常的 Ruby 框架
类似于 Ruby on Rails ,它封装了数据库连接,模板,及生成链接。最大的特点就是数据操作,不用自己再写多少代码。和 Ruby on Rails 类似,它生成一个数据表的操作最少只要一行代码。 Cake PHP framework 还有很大的一个优点就是它是一个轻量级的框架,虽然第一次看来会觉得很神奇,但是仔细看它的代码也很好懂而且也没什么特殊之处,但其开发使用方式确实很独特,实用,高效。如果是作基于数据库的 PHP 系统,这是一个很值得考虑的选择 。

看一下 Cake Tutorial 就能了解用 Cake PHP framework 建立一个 Web Application 是如何的快速方便了。它介绍了如何快速地建立一个 blog 程序的例子,几分钟就能搞定。

越来越发现 PHP 世界的有趣,哈哈。

载Download
下载最新的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使用的所有表格的默认形式。还有,id、created、updated字段是有特殊含义的,等一会儿你就会发现。也就是说现在你不应该更改他们的名字。

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

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

app/models/post.php


class Post extends AppModel
{
}

?>



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

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

app/helpers/posts_helper.php


class PostsHelper extends AppController
{
}

?>


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

app/controllers/posts_controller.php


class PostsController extends PostsHelper
{
}

?>


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

app/controllers/posts_controller.php


class PostsController extends PostsHelper
{
        function index()
        {
        }
}

?>


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

建立一个视图 (View)
把下面的代码放入 app/views/posts/index.thtml:

Blog posts



        
               
               
               
        
        post->findAll() as $post): ?>
        
               
               
               
        
        
Id Title Created

                        linkTo($post['title'], "/posts/view/{$post['id']}")?>
               



这应该可以正确运行,我们来测试一下。我假设你可以通过浏览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


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


Created:





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

The title

Created: 2005-07-04 03:31:47

This is the post body.

成功了!

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

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

app/controllers/posts_controller.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

Add post to blog


formTag('/posts/add')?>
        

Title: inputTag('post/title', 40)?> tagErrorMsg('post/title', 'Title is required.') ?>


        

Body:  areaTag('body') ?> tagErrorMsg('post/body', 'Body is required.') ?>


        

submitTag('Save') ?>





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

app/views/posts/index.thtml

Blog posts



        
               
               
               
        
        post->findAll() as $post): ?>
        
               
               
               
        
        
Id Title Created

                        linkTo($post['title'], "/posts/view/{$post['id']}")?>
               


linkTo('Add new post', '/posts/add') ?>




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

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

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

app/models/post.php


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

?>



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

删除一个帖子
app/controllers/posts_controller.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

Blog posts



        
               
               
               
        
        post->findAll() as $post): ?>
        
               
               
               
        
        
Id Title Created

                        linkTo($post['title'], "/posts/view/{$post['id']}")?>
                        linkTo('Delete',"/posts/delete/{$post['id']}", null, "Are you sure you want to delete post entitled \'{$post['title']}\'?")?>
               


linkTo('Add new post', '/posts/add') ?>


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

编辑帖子
app/controllers/posts_controller.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

Edit post to blog


formTag('/posts/edit')?>
        
        

Title: inputTag('post/title', 40)?>
                tagErrorMsg('post/title', 'Title is required.') ?>


        

areaTag('body') ?>
                tagErrorMsg('post/body', 'Body is required.') ?>


        

submitTag('Save') ?>





你也可以在表单标签中用

hiddenTag('id')?>

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

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

Blog posts



        
               
               
               
        
        post->findAll() as $post): ?>
        
               
               
               
        
        
Id Title Created

                        linkTo($post['title'], "/posts/view/{$post['id']}")?>
                        linkTo('Delete',"/posts/delete/{$post['id']}", null, "Are you sure you want to delete post entitled \'{$post['title']}\'?")?>
                        linkTo('Edit',"/posts/edit/{$post['id']}")?>
               


linkTo('Add new post', '/posts/add') ?>


从视图中分离逻辑
让我们回头看一下 index.thtml 视图:

app/views/posts/index.thtml

...
post->findAll() as $post): ?>
...


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

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

app/controllers/posts_controller.php

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


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

app/views/posts/index.thtml

...

...


这太简单了,不是么?
Statement
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
How can you check if a PHP session has already started?How can you check if a PHP session has already started?Apr 30, 2025 am 12:20 AM

In PHP, you can use session_status() or session_id() to check whether the session has started. 1) Use the session_status() function. If PHP_SESSION_ACTIVE is returned, the session has been started. 2) Use the session_id() function, if a non-empty string is returned, the session has been started. Both methods can effectively check the session state, and choosing which method to use depends on the PHP version and personal preferences.

Describe a scenario where using sessions is essential in a web application.Describe a scenario where using sessions is essential in a web application.Apr 30, 2025 am 12:16 AM

Sessionsarevitalinwebapplications,especiallyfore-commerceplatforms.Theymaintainuserdataacrossrequests,crucialforshoppingcarts,authentication,andpersonalization.InFlask,sessionscanbeimplementedusingsimplecodetomanageuserloginsanddatapersistence.

How can you manage concurrent session access in PHP?How can you manage concurrent session access in PHP?Apr 30, 2025 am 12:11 AM

Managing concurrent session access in PHP can be done by the following methods: 1. Use the database to store session data, 2. Use Redis or Memcached, 3. Implement a session locking strategy. These methods help ensure data consistency and improve concurrency performance.

What are the limitations of using PHP sessions?What are the limitations of using PHP sessions?Apr 30, 2025 am 12:04 AM

PHPsessionshaveseverallimitations:1)Storageconstraintscanleadtoperformanceissues;2)Securityvulnerabilitieslikesessionfixationattacksexist;3)Scalabilityischallengingduetoserver-specificstorage;4)Sessionexpirationmanagementcanbeproblematic;5)Datapersis

Explain how load balancing affects session management and how to address it.Explain how load balancing affects session management and how to address it.Apr 29, 2025 am 12:42 AM

Load balancing affects session management, but can be resolved with session replication, session stickiness, and centralized session storage. 1. Session Replication Copy session data between servers. 2. Session stickiness directs user requests to the same server. 3. Centralized session storage uses independent servers such as Redis to store session data to ensure data sharing.

Explain the concept of session locking.Explain the concept of session locking.Apr 29, 2025 am 12:39 AM

Sessionlockingisatechniqueusedtoensureauser'ssessionremainsexclusivetooneuseratatime.Itiscrucialforpreventingdatacorruptionandsecuritybreachesinmulti-userapplications.Sessionlockingisimplementedusingserver-sidelockingmechanisms,suchasReentrantLockinJ

Are there any alternatives to PHP sessions?Are there any alternatives to PHP sessions?Apr 29, 2025 am 12:36 AM

Alternatives to PHP sessions include Cookies, Token-based Authentication, Database-based Sessions, and Redis/Memcached. 1.Cookies manage sessions by storing data on the client, which is simple but low in security. 2.Token-based Authentication uses tokens to verify users, which is highly secure but requires additional logic. 3.Database-basedSessions stores data in the database, which has good scalability but may affect performance. 4. Redis/Memcached uses distributed cache to improve performance and scalability, but requires additional matching

Define the term 'session hijacking' in the context of PHP.Define the term 'session hijacking' in the context of PHP.Apr 29, 2025 am 12:33 AM

Sessionhijacking refers to an attacker impersonating a user by obtaining the user's sessionID. Prevention methods include: 1) encrypting communication using HTTPS; 2) verifying the source of the sessionID; 3) using a secure sessionID generation algorithm; 4) regularly updating the sessionID.

See all articles

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

SublimeText3 Linux new version

SublimeText3 Linux new version

SublimeText3 Linux latest version

MantisBT

MantisBT

Mantis is an easy-to-deploy web-based defect tracking tool designed to aid in product defect tracking. It requires PHP, MySQL and a web server. Check out our demo and hosting services.

Safe Exam Browser

Safe Exam Browser

Safe Exam Browser is a secure browser environment for taking online exams securely. This software turns any computer into a secure workstation. It controls access to any utility and prevents students from using unauthorized resources.

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

Integrate Eclipse with SAP NetWeaver application server.

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment