命名规范
类文件都是以.class.php为后缀(这里是指的ThinkPHP内部使用的类库文件,不代表外部加载的类库文件),使用驼峰法命名,并且首字母大写,例如 DbMysql.class.php;
类的命名空间地址和所在的路径地址一致,例如 Home\Controller\UserController类所在的路径应该是 Application/Home/Controller/UserController.class.php;
确保文件的命名和调用大小写一致,是由于在类Unix系统上面,对大小写是敏感的(而ThinkPHP在调试模式下面,即使在Windows平台也会严格检查大小写);
类名和文件名一致(包括上面说的大小写一致),例如 UserController类的文件命名是UserController.class.php, InfoModel类的文件名是InfoModel.class.php, 并且不同的类库的类命名有一定的规范;
函数、配置文件等其他类库文件之外的一般是以.php为后缀(第三方引入的不做要求);
函数的命名使用小写字母和下划线的方式,例如 get_client_ip;
方法的命名使用驼峰法,并且首字母小写或者使用下划线“_”,例如 getUserName,parseType,通常下划线开头的方法属于私有方法;
属性的命名使用驼峰法,并且首字母小写或者使用下划线“”,例如 tableName、_instance,通常下划线开头的属性属于私有属性;
以双下划线“”打头的函数或方法作为魔法方法,例如 call 和 __autoload;
常量以大写字母和下划线命名,例如 HAS_ONE和 MANY_TO_MANY;
配置参数以大写字母和下划线命名,例如HTML_CACHE_ON;
语言变量以大写字母和下划线命名,例如MY_LANG,以下划线打头的语言变量通常用于系统语言变量,例如 _CLASS_NOT_EXIST_;
对变量的命名没有强制的规范,可以根据团队规范来进行;
ThinkPHP的模板文件默认是以.html 为后缀(可以通过配置修改);
数据表和字段采用小写加下划线方式命名,并注意字段名不要以下划线开头,例如 think_user 表和 user_name字段是正确写法,类似 _username 这样的数据表字段可能会被过滤。
配置
ThinkPHP框架中所有配置文件的定义格式均采用返回PHP数组的方式,格式为:1
2
3
4
5
6
7
8//项目配置文件
return array(
'DEFAULT_MODULE' => 'Index', //默认模块
'URL_MODEL' => '2', //URL模式
'SESSION_AUTO_START' => true, //是否开启session
//更多配置参数
//...
);
配置参数不区分大小写(因为无论大小写定义都会转换成小写),所以下面的配置等效:1
2
3
4
5
6
7
8//项目配置文件
return array(
'default_module' => 'Index', //默认模块
'url_model' => '2', //URL模式
'session_auto_start' => true, //是否开启session
//更多配置参数
//...
);
1 | //项目配置文件 |
我们可以在应用入口文件中定义应用的配置文件的后缀,例如:1
define('CONF_EXT','.ini');
配置文件加载顺序
惯例配置->应用配置->模式配置->调试配置->状态配置->模块配置->扩展配置->动态配置
惯例配置;
惯例重于配置是系统遵循的一个重要思想,框架内置有一个惯例配置文件(位于ThinkPHP/Conf/convention.php),按照大多数的使用对常用参数进行了默认配置。所以,对于应用的配置文件,往往只需要配置和惯例配置不同的或者新增的配置参数,如果你完全采用默认配置,甚至可以不需要定义任何配置文件。
应用配置:
应用配置文件也就是调用所有模块之前都会首先加载的公共配置文件(默认位于Application/Common/Conf/config.php)。
模式配置:
如果使用了普通应用模式之外的应用模式的话,还可以为应用模式(后面会有描述)单独定义配置文件,文件命名规范是: Application/Common/Conf/config_应用模式名称.php(仅在运行该模式下面才会加载)。
调试配置:
如果开启调试模式的话,则会自动加载框架的调试配置文件(位于ThinkPHP/Conf/debug.php)和应用调试配置文件(位于Application/Common/Conf/debug.php)
状态配置:
每个应用都可以在不同的情况下设置自己的状态(或者称之为应用场景),并且加载不同的配置文件。
举个例子,你需要在公司和家里分别设置不同的数据库测试环境。那么可以这样处理,在公司环境中,我们在入口文件中定义:1
define('APP_STATUS','office');
那么就会自动加载该状态对应的配置文件(位于Application/Common/Conf/office.php)。
如果我们回家后,我们修改定义为:1
define('APP_STATUS','home');
那么就会自动加载该状态对应的配置文件(位于Application/Common/Conf/home.php)。
模块配置:
每个模块会自动加载自己的配置文件(位于Application/当前模块名/Conf/config.php)。
如果使用了普通模式之外的其他应用模式,你还可以为应用模式单独定义配置文件,命名规范为: Application/当前模块名/Conf/config_应用模式名称.php(仅在运行该模式下面才会加载)。
读取配置1
$model = C('URL_MODEL');
如果url_model尚未存在设置,则返回NULL。
因为配置参数是全局有效的,因此C方法可以在任何地方读取任何配置,即使某个设置参数已经生效过期了。
动态配置
C(‘参数名称’,’新的参数值’);
动态配置赋值仅对当前请求有效,不会对以后的请求造成影响。
动态改变配置参数的方法和读取配置的方法在使用上面非常接近,都是使用C方法,只是参数的不同。 也可以支持二维数组的读取和设置,使用点语法进行操作,如下:1
2
3
4// 获取已经设置的参数值
C('USER_CONFIG.USER_TYPE');
//设置新的值
C('USER_CONFIG.USER_TYPE',1);
扩展配置
扩展配置可以支持自动加载额外的自定义配置文件,并且配置格式和项目配置一样。 设置扩展配置的方式如下(多个文件用逗号分隔):1
2// 加载扩展配置文件
'LOAD_EXT_CONFIG' => 'user,db',
假设扩展配置文件user.php 和db.php分别用于用户配置和数据库配置,这样做的好处是哪怕以后关闭调试模式,你修改db配置文件后依然会自动生效。
如果在应用公共设置文件中配置的话,那么会自动加载应用公共配置目录下面的配置文件Application/Common/Conf/user.php和Application/Common/Conf/db.php。
如果在模块(假设是Home模块)的配置文件中配置的话,则会自动加载模块目录下面的配置文件 Application/Home/Conf/user.php 和 Application/Home/Conf/db.php。
默认情况下,扩展配置文件中的设置参数会并入项目配置文件中。也就是默认都是一级配置参数,例如user.php中的配置参数如下:1
2
3
4
5
6
7
//用户配置文件
return array(
'USER_TYPE' => 2, //用户类型
'USER_AUTH_ID' => 10, //用户认证ID
'USER_AUTH_TYPE' => 2, //用户认证模式
);
那么,最终获取用户参数的方式是:1
C('USER_AUTH_ID');
如果配置文件改成:1
2// 加载扩展配置文件
'LOAD_EXT_CONFIG' => array('USER'=>'user','DB'=>'db'),
则最终获取用户参数的方式改成:1
C('USER.USER_AUTH_ID');
批量配置
C配置方法支持批量配置,例如:1
2$config = array('WEB_SITE_TITLE'=>'ThinkPHP','WEB_SITE_DESCRIPTION'=>'开源PHP框架');
C($config);
$config数组中的配置参数会合并到现有的全局配置中。
我们可以通过这种方式读取数据库中的配置参数,例如:1
2
3
4
5// 读取数据库中的配置(假设有一个config表用于保存配置参数)
$config = M('Config')->getField('name,value');
// config是一个关联数组 键值就是配置参数 值就是配置值
// 例如: array('config1'=>'val1','config2'=>'val2',...)
C($config); // 合并配置参数到全局配置
合并之后,我们就可以和前面读取普通配置参数一样,读取数据库中的配置参数了,当然也可以动态改变。1
2
3
4// 读取合并到全局配置中的数据库中的配置参数
C('CONFIG1');
// 动态改变配置参数(当前请求有效,不会自动保存到数据库)
C('CONFIG2','VALUE_NEW');
架构
模块化设计
一个完整的ThinkPHP应用基于模块/控制器/操作设计,并且,如果有需要的话,可以支持多入口文件和多级控制器。
一个典型的URL访问规则是:1
http://serverName/index.php(或者其他应用入口文件)/模块/控制器/操作/[参数名/参数值...]
解释下其中的几个概念:
|名称|描述|
|-|-|
|应用|基于同一个入口文件访问的项目我们称之为一个应用。|
|模块|一个应用下面可以包含多个模块,每个模块在应用目录下面都是一个独立的子目录。|
|控制器|每个模块可以包含多个控制器,一个控制器通常体现为一个控制器类。|
|操作|每个控制器类可以包含多个操作方法,也可能是绑定的某个操作类,每个操作是URL访问的最小单元。|
模块化设计的思想下面模块是最重要的部分,模块其实是一个包含配置文件、函数文件和MVC文件(目录)的集合。
新版采用模块化的设计架构,下面是一个应用目录下面的模块目录结构,每个模块可以方便的卸载和部署,并且支持公共模块。1
2
3
4
5
6Application 默认应用目录(可以设置)
├─Common 公共模块(不能直接访问)
├─Home 前台模块
├─Admin 后台模块
├─... 其他更多模块
├─Runtime 默认运行时目录(可以设置)
每个模块是相对独立的,其目录结构如下:1
2
3
4
5
6
7
8
9├─Module 模块目录
│ ├─Conf 配置文件目录
│ ├─Common 公共函数目录
│ ├─Controller 控制器目录
│ ├─Model 模型目录
│ ├─Logic 逻辑目录(可选)
│ ├─Service Service目录(可选)
│ ... 更多分层目录可选
│ └─View 视图目录
公共模块
Common模块是一个特殊的模块,是应用的公共模块,访问所有的模块之前都会首先加载公共模块下面的配置文件(Conf/config.php)和公共函数文件(Common/function.php)。但Common模块本身不能通过URL直接访问,公共模块的其他文件则可以被其他模块继承或者调用。
公共模块的位置可以通过COMMON_PATH常量改变,我们可以在入口文件中重新定义COMMON_PATH如下:1
2
3define('COMMON_PATH','./Common/');
define('APP_PATH','./Application/');
require './ThinkPHP/ThinkPHP.php';
其应用目录结构变成:1
2
3
4
5
6
7www WEB部署目录(或者子目录)
├─index.php 入口文件
├─README.md README文件
├─Common 应用公共模块目录
├─Application 应用模块目录
├─Public 应用资源文件目录
└─ThinkPHP 框架目录
自动生成模块目录
例如,如果我们需要生成一个Admin模块用于后台应用,在应用入口文件中定义如下:1
2
3
4// 绑定Admin模块到当前入口文件
define('BIND_MODULE','Admin');
define('APP_PATH','./Application/');
require './ThinkPHP/ThinkPHP.php';
然后访问URL地址1
http://serverName/index.php
就会生成Admin模块的目录,并生成一个默认的控制器类Admin\Controller\IndexController。 如果需要生成更多的控制器类,可以定义BUILD_CONTROLLER_LIST常量,例如:1
2
3
4
5// 绑定Admin模块到当前入口文件
define('BIND_MODULE','Admin');
define('BUILD_CONTROLLER_LIST','Index,User,Menu');
define('APP_PATH','./Application/');
require './ThinkPHP/ThinkPHP.php';
访问后会自动生成三个指定的控制器类:1
2
3Admin\Controller\IndexController
Admin\Controller\UserController
Admin\Controller\MenuController
禁止访问模块1
2// 设置禁止访问的模块列表
'MODULE_DENY_LIST' => array('Common','Runtime','Api'),
设置后,Api模块不能通过URL直接访问,事实上,可能我们只是在该模块下面放置一些公共的接口文件,因此都是内部调用即可。
如果你的应用下面模块比较少,还可以设置允许访问列表和默认模块,这样可以简化默认模块的URL访问。1
2'MODULE_ALLOW_LIST' => array('Home','Admin','User'),
'DEFAULT_MODULE' => 'Home',
单模块设计
如果你的应用够简单,那么也许仅仅用一个模块就可以完成,那么可以直接设置:1
2
3// 关闭多模块访问
'MULTI_MODULE' => false,
'DEFAULT_MODULE' => 'Home',
一旦关闭多模块访问后,就只能访问默认模块(这里设置的是Home)。
多入口设计
可以给相同的应用及模块设置多个入口,不同的入口文件可以设置不同的应用模式或者绑定模块。1
2
3
4// 绑定Home模块到当前入口文件
define('BIND_MODULE','Home');
define('APP_PATH','./Application/');
require './ThinkPHP/ThinkPHP.php';
URL模式
ThinkPHP框架的URL是区分大小写(主要是针对模块、控制器和操作名,不包括应用参数)的,这一点非常关键,因为ThinkPHP的命名规范是采用驼峰法(首字母大写)的规则,而URL中的模块和控制器都是对应的文件,因此在Linux环境下面必然存在区分大小写的问题。
普通模式
普通模式也就是传统的GET传参方式来指定当前访问的模块和操作,例如: http://localhost/?m=home&c=user&a=login&var=value
m参数表示模块,c参数表示控制器,a参数表示操作(当然这些参数都是可以配置的),后面的表示其他GET参数。
如果默认的变量设置和你的应用变量有冲突的话,你需要重新设置系统配置,例如改成下面的:1
2
3'VAR_MODULE' => 'module', // 默认模块获取变量
'VAR_CONTROLLER' => 'controller', // 默认控制器获取变量
'VAR_ACTION' => 'action', // 默认操作获取变量
上面的访问地址则变成: http://localhost/?module=home&controller=user&action=login&var=value
PATHINFO模式
PATHINFO模式是系统的默认URL模式,提供了最好的SEO支持,系统内部已经做了环境的兼容处理,所以能够支持大多数的主机环境。对应上面的URL模式,PATHINFO模式下面的URL访问地址是: http://localhost/index.php/home/user/login/var/value/
PATHINFO模式下面,URL是可定制的,例如,通过下面的配置:1
2// 更改PATHINFO参数分隔符
'URL_PATHINFO_DEPR'=>'-',
REWRITE模式
REWRITE模式是在PATHINFO模式的基础上添加了重写规则的支持,可以去掉URL地址里面的入口文件index.php,但是需要额外配置WEB服务器的重写规则。
如果是Apache则需要在入口文件的同级添加.htaccess文件,内容如下:1
2
3
4
5
6<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php/$1 [QSA,PT,L]
</IfModule>
接下来,就可以用下面的URL地址访问了: http://localhost/home/user/login/var/value
兼容模式
可以更改兼容模式变量的名称定义,例如:1
'VAR_PATHINFO' => 'path'
PATHINFO参数分隔符对兼容模式依然有效,例如:1
2// 更改PATHINFO参数分隔符
'URL_PATHINFO_DEPR'=>'-',
使用以上配置的话,URL访问地址可以变成: http://localhost/?path=/home-user-login-var-value
兼容模式配合Web服务器重写规则的定义,可以达到和REWRITE模式一样的URL效果。
例如,我们在Apache下面的话,.htaccess文件改成如下内容:1
2
3
4
5
6<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php?s=/$1 [QSA,PT,L]
</IfModule>
就可以和REWRITE模式一样访问下面的URL地址访问了: http://localhost/home/user/login/var/value
………
http://document.thinkphp.cn/manual_3_2.html