前言

写在最前面,我考察的版本:cakephp-1.3.12-0-g96a8d97

都说CakePHP是一个很简单的框架,试了下,觉得还是比较简单的,MVC的流程很清晰。学过JAVA的人可能比较有亲切感,感觉很类似,都是配置多过实际代码的系统。可惜的就是优点和缺点一样都不明显,感觉用和没用差别不是很大,囧。当然也有可能是因为我是粗略地过了一下,看得不是很深入。

PHP有几个比较common的问题点需要解决,以后框架的考察都根据这些点进行罗列。

1. 资源加载

用过JAVA的开发肯定对JAVA里的import感觉很好,import进来我就可以用了,不用烦恼资源包的加载问题。PHP这方面就做得很差,很多东西都需要自己解决。如果要在PHP里做到自动化类加载的话,必须实现__autoload函数,或者使用spl_autoload_register函数进行自动加载函数的注册。

CakePHP自带了资源加载方法,具体可以参考:3.4.4 The App Class。不过这个东西不能乱用,它使用的是require方法来加载代码,不小心使用的话会造成重复类定义,参考这里
这里举个例子:
[codesyntax lang="php"]

App::import('Lib', 'ImageManipulation'); //imports app/libs/image_manipulation.php

[/codesyntax]

2. Model

CakePHP的模型做得不错。易用性上很好。定义模型只需要建一个模型类文件,内容几乎不用填。数据库的映射它自己会做。可以参考这里:3.7.1 Understanding Models
性能我没考察过,默认的layout有输出过sql,简单看了下,貌似写得不太好。。。如果是简单来做网站的话还没问题,需要考虑性能的话,最好还是要深挖一下这块 。

3. View

CakePHP自带的View就不用看了,就是PHP文件,这个也能算是模板么,太囧了。

没有官方的Smarty支持,只有一个第三方的smarty插件。我这里比较推荐的方法是完全抛弃cake自带的view系统,只要在controller的action函数里带上$this->autoRender=false;就能阻止cake自动调用view的事件,然后就能使用smarty进行输出了。

关于官方自带的view的使用方法,可以简单参考这个示例,个人感觉就是一个纯PHP文件,实际意义不大,性能上也比不过smarty。关于controller和view之间的交互,可以参考这里:3.5.4 Controller Methods

在controller的action函数里使用$this->layout = 'layout_name';可以从default的layout切换到其他layout。

4. Controller

控制器还是比较好理解的,和传统的控制器基本一致。关于如何向controller传送参数,请参考这里:3.4.5 Routes Configuration

5. Business Logic

没看明白业务逻辑应该写在哪里,恩。不过有lib包的加载方法,可以写在lib包里,然后手动加载。

6. Several Knowledge Point

文件的命名是有规范的,按它的规范起名和放置文件的话,很多功能就能自动化,不用手动定义。关于命名规范,可以参考官方文档:2.4 CakePHP Conventions

框架自带的一系列Helper比较扯淡,在PHP页面上把HTML的form和js都生成好,什么代码都在服务端写?这不是什么好主意。当然,看的时间比较短,不知道是不是我理解错了。

7. Simple Sample

简单范例,先上图:


数据库的表很简单,库php,表users,列id和name。功能就是在首页上显示2个按钮,按search all,显示所有的id和名字在页面上,按search single,根据输入框里输入的用户id进行数据查找并显示。

首先第一步需要改的是系统默认的router,否则CakePHP将永远将首页定向到默认的介绍页面。编辑app/config/routes.php,将两行代码中的上面那行改掉,编辑成我们定义好的首页controller。
[codesyntax lang="php"]

Router::connect('/', array('controller' => 'HomePage', 'action' => 'index'));

[/codesyntax]
这个改动会将首页/定向到自定义的controller,名字是home_page_controller.php,内容如下。
[codesyntax lang="php"]

<?php
class HomePageController extends AppController {
    var $name = 'HomePage'; // controller name
    var $uses = array(); // If you do not wish to use a Model in your controller, set var $uses = array()

    function index() {
    }
}

[/codesyntax]
函数index会处理默认的页面请求,里面没有逻辑,所以controller会直接渲染views/home_page/index.ctp。
[codesyntax lang="html4strict"]

<html>
<head>
    <title>Open Source PHP Framework Test</title>
    <script type="text/javascript" src="../js/jquery-1.4.2.min.js"></script>
    <script type="text/javascript">
        function sendSingleRequest() {
            $.ajax({
                type: 'post',
                url: '../users/single/' + $('#uid').val(),
                dataType: 'html',
                success: function(data){
                    console.log(data);
                    $('#result').html(data);
                },
                error: function(e){
                    console.log(e);
                    alert(e);
                }
            });
        }
        function sendAllRequest() {
            $.ajax({
                type: 'post',
                url: '../users/all',
                dataType: 'html',
                success: function(data){
                    console.log(data);
                    $('#result').html(data);
                },
                error: function(e){
                    console.log(e);
                    alert(e);
                }
            });
        }
    </script>
</head>
<body>
    <div>
        <div>User Id: <input id="uid" type="text" value="" /></div>
        <div><input id="searchSingle" type="button" value="search single" onclick="sendSingleRequest();" /></div>
        <div><input id="searchAll" type="button" value="search all" onclick="sendAllRequest();" /></div>
    </div>
    <div id="result"></div>
</body>
</html>

[/codesyntax]
同时记得不要忘记为users表创建model,app/model/user.php。
[codesyntax lang="php"]

<?php
class User extends AppModel {
    var $name = 'User';
}

[/codesyntax]
在首页上,无论点击哪个按键都会定向到users_controller.php。
[codesyntax lang="php"]

<?php
class UsersController extends AppController {
    var $name = 'Users'; // controller name

    /**
     * Search all users from Model User,
     * and rendering with template '/users/list'
     */
    function all() {
        $this->set('users', $this->User->find('all'));
        $this->render('/users/list');
    }

    /**
    * Search single user from Model User via user id,
    * and rendering with template '/users/list'
    */
    function single($id) {
        $this->set('users', $this->User->find('all', array ('conditions' => array ('User.id' => $id))));
        $this->render('/users/list');
    }
}

[/codesyntax]
点击搜索单个的话,会定向到users/single/id,也就是single函数,会根据用户id进行查询,然后渲染views/users/list.ctp。
而点击搜索所有的话,会定向到users/all,也就是all函数,会进行全表查询,然后渲染views/users/list.ctp。
[codesyntax lang="php"]

<table>
    <tr>
        <th>ID</th>
        <th>NAME</th>
    </tr>
    <?php foreach ($users as $user) { ?>
    <tr>
        <td><?php echo $user['User']['id']; ?></td>
        <td><?php echo $user['User']['name']; ?></td>
    </tr>
    <?php } ?>
</table>

[/codesyntax]
最后都会显示在以result 为id的div里。

恩,这个例子很简单吧。