CakePHP-2.x笔记

2016-05-06

因工作需要接触了cakephp,英文文档很全,代码维护也很积极,是一个不错的MVC框架。

目录结构

app:包含了应用程序的文件,所有的controllers、models、views、layouts,以及JavaScript、css、图片、flash。

lib:CakePHP的核心库文件,以及一些支持CakePHP的类文件和脚本。

plugins:存放插件目录。

vendors:用来存放第三方的文件。

配置文件

在开始编写程序前,我们还需要进行以下工作。

1:修改Security.salt的值,在app/config/core.php文件中。(用来产生hash码,增强安全性。)

2:输入MySQL数据库的连接配置。在app/config/database.php.default中,重命名为database.php,然后根据自己的数据库配置此文件。

数据库配置文件:

app/config/database.php

命名规则

1:controller

类名称:必须是复数,并且要附加上Controller。

PHP文件:必须是复数,且附加上_controller,PHP扩展名。

2:model

类名称:必须是单数

PHP文件:必须是单数,PHP扩展名,如果多个单词,用“_”连接。

3:view

view文件的名称是从controller中action名称而来。例如:ProductsController::add(),view的路径那么就是:app/view/products/add.ctp。

cakephp里怎么输出原生的mysql查询语句?

打开项目文件:\lib\Cake\Model\Datasource\DboSource.php

在_execute函数中输出$sql变量即可:

protected function _execute($sql, $params = array(), $prepareOptions = array()) {
	$sql = trim($sql);
	var_dump($sql);
	if (preg_match('/^(?:CREATE|ALTER|DROP)\s+(?:TABLE|INDEX)/i', $sql)) {
		$statements = array_filter(explode(';', $sql));
		if (count($statements) > 1) {
			$result = array_map(array($this, '_execute'), $statements);
			return array_search(false, $result) === false;
		}
	}

全局配置文件:

/app/config/core.php

例如:

Configure::write('debug', 2);

这里可以配置debug参数,

这个选项定义了应用程序的Debug级别。

设置为一个非零的数值Cake会输出所有的pr()和debug()函数调用,并且在Forward之前会有提示信息。设置为2或者是更高的数值,则会在页面底部输出sql语句。

在debug模式下(DEBUG被设为1或者更高),Cake会输出错误自定义错误页面,

例如 “Missing Controller”,”Missing Action”等等。在生产环境下(DEBUG被设为0),Cake输出 “Not Found”页面,你可以自行修改该页面(app/views/errors/error400.ctp)。

还有Session、异常、php错误之类的配置都在这里。

错误提示(关闭notice通知):

Configure::write('Error', array(
	'handler' => 'ErrorHandler::handleError',
	'level' => E_ALL & ~E_DEPRECATED ^E_NOTICE,
	'trace' => true
));

路由配置

app/config/routes.php

例如:

Router::connect('URL',array('controller'=>'controllername','action'=>'actionname', 'firstparam') );

1.URL是一个正则表达式,表示你希望采用的URL格式

2.controllername是希望调用的controller的名字

3.actionname是希望调用的controller的action名字

4.firstparam是action的第一个参数名

全局方法

自动加载类:

App::uses('AppModel', 'Model');

模型

不包含查询:

$this->User->find('all', array(
    'conditions' => array(
        'NOT' => array(
            'User.id' => array(1, 2, 3)
        )
    )
));

组件(component)

助件(Helper)

访问控制名词解释:

访问请求对象(Access Request Object,ARO)

访问控制对象(access-control object,ACO)

登陆后权限控制: \app\Controller\Component\AuthComponent.php startup() 在此函数调试

cakephp recursive作用

在cakephp中我们会定义一些model,然后定义模型与模型之间的关系。

在查询时,cakephp会自主的把所有有关系的模型记录也查询出来,如果需要哪些附属数据倒是很好,但是如果不需要的要,就显得累赘、臃肿了。

cakephp是一个成熟的框架,在查询中定义了一个属性:recursive。定义需要查询的关系级数。

值为int型 array(-1 ,0, 1, 2)

-1 代表model本身
0  代表model本身 + belongTo + hasOne
1  代表model本身 + belongTo + hasOne + hasMany
2  代表model本身 + belongTo + hasOne + hasMany + hasAndBelongsToMany

具体用法为在find 或者 pagenate查询时使用

查询 GROUP BY

比如需要查询的SQL如下:

SELECT COUNT(active) as count,active FROM `users` WHERE group_id=1 GROUP BY active;

对应的代码:

<?php
public function testgroup()
{
    $this->loadModel('user');
    $this->user->recursive = -1;
    $result = $this->user->find('all',
		array(
			'conditions' => array('group_id' => '1'),
			'fields' => array('active', 'COUNT(active) as count'),
			'group'=>'active'
		)
	);
    var_dump($result);
    die;
}

官方文档:http://book.cakephp.org/2.0/en/index.html

中文文档(英文文档更详细些):http://book.cakephp.org/2.0/zh/index.html

国内文档:http://www.phpfans.net/manu/CakePHP/

Cakephp自动生成test代码bat脚本

生成Model:

e:
cd E:\SVN\2016\Projects\app\Model
for /f %%i in ('dir /b *.php') do (
    cd E:\SVN\2016\Projects\app
    cake bake test Model %%~ni
    )
pause

生成Controller:

e:
cd E:\SVN\2016\Projects\app\Controller
for /f %%i in ('dir /b *.php') do (
    cd E:\SVN\2016\Projects\app
    cake bake test Controller %%~ni
    )
pause

生成Component:

e:
cd E:\SVN\2016\Projects\app\Controller\Component
for /f %%i in ('dir /b *.php') do (
    cd E:\SVN\2016\Projects\app
    cake bake test Component %%~ni
    )
pause

缓存

开启redis缓存

\app\Config\bootstrap.php 添加如下内容

Cache::config('redis', array(
	'engine' => 'redis',
	'duration' => '+1 minutes',
	'prefix' => 'cake_short_'
));

检查路径 \app\Config\core.php 把关闭缓存的配置注释:

//	Configure::write('Cache.disable', true);

使用方法:

Cache::read($key, $config = 'default')
Cache::write($key, $value, $config = 'default')

参考文档:http://book.cakephp.org/2.0/zh/core-libraries/caching.html

cakephp调用多个数据库

首先在app/config/database.php添加一个配置

然后在model里用调用test这个数据库:

<?php
class Example extends AppModel {
    public $useDbConfig = test;
}

cakephp 2.9开启ACL

简单的 Acl 控制的应用教程:https://book.cakephp.org/2.0/en/tutorials-and-examples/simple-acl-controlled-application/simple-acl-controlled-application.html

Acl Extras 插件https://github.com/markstory/acl_extras

cakephp创建ACL,更新aco数据库

1.安装AclExtras插件:

下载地址:https://github.com/markstory/acl_extras/

2.利用AclExtras生成acos表数据,cakephp\app 目录下执行:

cake AclExtras.AclExtras aco_sync

恢复aro数据库

cake AclExtras.AclExtras recover aro

初始化Acl表(注意:这步操作会清空aros acos aros_acos表)

./Console/cake schema create DbAcl
  • aros:在添加组及用户时会自动生成数据。
  • acos:记录controller方法对应权限的所有记录
  • aros_acos:记录aros表与acos表关系映射

ERROR

AclNode::node() - Couldn’t find Aro node identified by “Array ( [Aro0.model] => Group [Aro0.foreign_key] => 1 ) “

这个报错一般是由于aros表被清空导致,此时需要手动填入aros内容:

+----+-----------+-------+-------------+-------+-----+------+
| id | parent_id | model | foreign_key | alias | lft | rght |
+----+-----------+-------+-------------+-------+-----+------+
|  1 | NULL      | Group |           1 | NULL  |   1 |    2 |
|  2 | NULL      | Group |           2 | NULL  |   3 |    4 |
|  3 | NULL      | Group |           3 | NULL  |   5 |    6 |
|  4 | NULL      | Group |           4 | NULL  |   7 |    8 |
|  5 | NULL      | Group |           5 | NULL  |   9 |   10 |
|  6 | NULL      | Group |           6 | NULL  |  11 |   12 |
|  7 | NULL      | Group |           7 | NULL  |  13 |   14 |
|  8 | NULL      | Group |           8 | NULL  |  15 |   16 |
|  9 | NULL      | Group |           9 | NULL  |  17 |   18 |
| 10 | NULL      | Group |          10 | NULL  |  19 |   20 |
| 11 | NULL      | Group |          11 | NULL  |  21 |   22 |
| 12 | NULL      | Group |          12 | NULL  |  23 |   24 |
| 13 | NULL      | Group |          13 | NULL  |  25 |   26 |
| 14 | NULL      | Group |          14 | NULL  |  27 |   28 |
| 15 | NULL      | Group |          15 | NULL  |  29 |   30 |
| 16 | NULL      | Group |          16 | NULL  |  31 |   32 |
| 17 | NULL      | Group |          17 | NULL  |  33 |   34 |
| 18 | NULL      | Group |          18 | NULL  |  35 |   36 |
+----+-----------+-------+-------------+-------+-----+------+
18 rows in set

Fatal error: Class declarations may not be nested in ExceptionRenderer.php on line 57 cakephp

遇到报错:

Fatal error: Class declarations may not be nested in path\to\project\lib\Cake\Error\ExceptionRenderer.php on line 57 cakephp

但是,不幸的是,它没有告诉确切的文件和或变量信息。所以,对此毫无头绪,因为你必须一个接一个地通过所有的控制器去查找重复的声明。

但是,解决,事实上非常简单,准确的文件可以在日志文件中找到,对于CakePHP 2.x位于

app/tmp/logs/error.log

日志里会出现:

2017-03-02 13:59:13 Error: Fatal Error (64): Can't use method return value in write context in [/mnt/data/web/app/Controller/AppController.php, line 85]
2017-03-02 13:59:13 Error: [FatalErrorException] Can't use method return value in write context
Request URL: /

接下来去解决它吧。

An internal error has occurred

这种情况一般可以开启调试模式:

Configure::write('debug',2)

但是记得经常去清理缓存目录

app\tmp\cache