ThinkPHP 3.2.3 学习
ThinkPHP 3.2.3 学习
环境要求
PHP版本要求
- PHP5.3以上版本(注意:PHP5.3dev版本和PHP6均不支持)
ThinkPHP目录结构
下载官方的ThinkPHP后目录如下
www WEB部署目录(或者子目录)
├─index.php 入口文件
├─README.md README文件
├─Application 应用目录
├─Public 资源文件目录
└─ThinkPHP 框架目录
开发人员可以在这个基础之上灵活调整。其中,Application
和Public
目录下面都是空的。
README.md文件仅用于说明,实际部署的时候可以删除。
上面的目录结构和名称是可以改变的,这取决于你的入口文件和配置参数。
Application目录默认是空的,但是第一次访问入口文件会自动生成,参考后面的入口文件部分。
ThinkPHP框架目录如下
├─ThinkPHP 框架系统目录(可以部署在非web目录下面)
│ ├─Common 核心公共函数目录
│ ├─Conf 核心配置目录
│ ├─Lang 核心语言包目录
│ ├─Library 框架类库目录
│ │ ├─Think 核心Think类库包目录
│ │ ├─Behavior 行为类库目录
│ │ ├─Org Org类库包目录
│ │ ├─Vendor 第三方类库目录
│ │ ├─ ... 更多类库目录
│ ├─Mode 框架应用模式目录
│ ├─Tpl 系统模板目录
│ ├─LICENSE.txt 框架授权协议文件
│ ├─logo.png 框架LOGO文件
│ ├─README.txt 框架README文件
│ └─ThinkPHP.php 框架入口文件
入口文件
入口文件定义
入口文件主要完成:
- 定义框架路径、项目路径(可选)
- 定义调试模式和应用模式(可选)
- 定义系统相关常量(可选)
- 载入框架入口文件(必须)
默认情况下,框架已经自带了一个应用入口文件(以及默认的目录结构),内容如下:
define('APP_PATH','./Application/');
require './ThinkPHP/ThinkPHP.php';
如果你改变了项目目录(例如把Application
更改为Apps
),只需要在入口文件更改APP_PATH常量定义即可:
define('APP_PATH','./Apps/');
require './ThinkPHP/ThinkPHP.php';
注意:APP_PATH的定义支持相对路径和绝对路径,但必须以“/”结束
如果你调整了框架核心目录的位置或者目录名,只需要这样修改:
define('APP_PATH','./Application/');
require './Think/ThinkPHP.php';
也可以单独定义一个THINK_PATH常量用于引入:
define('APP_PATH','./Application/');
define('THINK_PATH',realpath('../Think').'/');
require THINK_PATH.'ThinkPHP.php';
和APP_PATH一样THINK_PATH路径定义也必须以“/”结尾。
给THINK_PATH和APP_PATH定义绝对路径会提高系统的加载效率。
入口文件中的其他定义
一般不建议在入口文件中做过多的操作,但可以重新定义一些系统常量,入口文件中支持定义(建议)的一些系统常量包括:
常量 描述THINK_PATH 框架目录APP_PATH 应用目录RUNTIME_PATH 应用运行时目录(可写)APP_DEBUG 应用调试模式 (默认为false)STORAGE_TYPE 存储类型(默认为File)APP_MODE 应用模式(默认为common)> 注意:所有路径常量都必须以“/”结尾
例如,我们可以在入口文件中重新定义相关目录并且开启调试模式:
// 定义应用目录
define('APP_PATH','./Apps/');
// 定义运行时目录
define('RUNTIME_PATH','./Runtime/');
// 开启调试模式
define('APP_DEBUG',True);
// 定义插件目录
define('ADDON_PATH', './Addons/');
// 定义模板目录
define('THEMES_PATH', './Theme/');
// 缓存目录
define('RUNTIME_PATH', './Data/Runtime/' );
// 更名框架目录名称,并载入框架入口文件
require './Think/ThinkPHP.php';
这样最终的应用目录结构如下:
www WEB部署目录(或者子目录)
├─index.php 应用入口文件
├─Apps 应用目录 //或Application
├─Public 资源文件目录
├─Runtime 运行时目录
└─Think 框架目录
Application
Application目录结构
Application
├─Common 应用公共模块
│ ├─Common 应用公共函数目录
│ └─Conf 应用公共配置文件目录
├─Home 默认生成的Home模块
│ ├─Conf 模块配置文件目录
│ ├─Common 模块函数公共目录
│ ├─Controller 模块控制器目录
│ ├─Model 模块模型目录
│ └─View 模块视图文件目录
├─Runtime 运行时目录
│ ├─Cache 模版缓存目录
│ ├─Data 数据目录
│ ├─Logs 日志目录
│ └─Temp 缓存目录
如果你不是Windows环境下面的话,需要对应用目录Application
设置可写权限才能自动生成。
如果不是调试模式的话,会在Runtime目录下面生成common~runtime.php
文件(应用编译缓存文件)。
下载后的框架自带了一个应用目录结构,并且带了一个默认的应用入口文件,方便部署和测试,默认的应用目录是Application(实际部署过程中可以随意设置),应用目录只有一个,因为大多数情况下,我们都可以通过多模块化以及多入口的设计来解决应用的扩展需求。
模块设计
新版采用模块化的设计架构,下面是一个应用目录下面的模块目录结构,每个模块可以方便的卸载和部署,并且支持公共模块。
Application 默认应用目录(可以设置)
├─Common 公共模块(不能直接访问)
├─Home 前台模块
├─Admin 后台模块
├─... 其他更多模块
├─Runtime 默认运行时目录(可以设置)
每个模块是相对独立的,其目录结构如下:
├─Module 模块目录
│ ├─Conf 配置文件目录
│ ├─Common 公共函数目录
│ ├─Controller 控制器目录
│ ├─Model 模型目录
│ ├─Logic 逻辑目录(可选)
│ ├─Service Service目录(可选)
│ ... 更多分层目录可选
│ └─View 视图目录
由于采用多层的MVC机制,除了Conf和Common目录外,每个模块下面的目录结构可以根据需要灵活设置和添加,所以并不拘泥于上面展现的目录
模块映射
模板和操作映射功能是3.1.2版本支持的对模块和操作设置的映射机制,由于可以通过改变配置动态改变(实际真正改变,并非别名)URL访问地址,加强了应用的安全性,而且,映射机制具有URL不区分大小写访问的特性,对于应用的迁移也有很大的帮助。
要定义模块映射,我们只需要在配置文件中定义:
'URL_MODULE_MAP'=>array(
'user' => 'Member',
'blog' => 'Info',
)
URL_MODULE_MAP是一个数组,每个数组项表示:
'模块映射名'=>'实际模块名'
映射名称不区分大小写,所以设置后,URL访问从原来的:
http://serverName/index.php/Member/index
http://serverName/index.php/Info/index
变成了:
http://serverName/index.php/user/index
http://serverName/index.php/blog/index
并且原来的访问URL是失效的,这也是和定义路由方式改变URL的区别之一。没有定义映射的模块访问不变。
定义了模块映射后,可以通过MODULE_ALIAS常量读取当前模块的URL名称。
控制器
我们可以在自动生成的Application/Home/Controller目录下面找到一个 IndexController.class.php
文件,这就是默认的Index控制器文件。
控制器类的命名方式是:控制器名(驼峰法,首字母大写)+Controller
比如IndexController.class.php
控制器名:Index
控制器文件的命名方式是:类名+class.php(类文件后缀)
默认的欢迎页面其实就是访问的Home模块下面的Index控制器类的index操作方法 我们修改默认的index操作方法如下:
namespace Home\Controller;
use Think\Controller;
class IndexController extends Controller {
public function index(){
echo 'hello,world!';
}
}
再次运行应用入口文件,浏览器会显示:hello,world!
。
我们再来看下控制器类,IndexController控制器类的开头是命名空间定义:
namespace Home\Controller;
这是系统的规范要求,表示当前类是Home模块下的控制器类,命名空间和实际的控制器文件所在的路径是一致的,也就是说: Home\Controller\IndexController
类 对应的控制器文件位于应用目录下面的 Home/Controller/IndexController.class.php
,如果你改变了当前的模块名,那么这个控制器类的命名空间也需要随之修改。
注意:命名空间定义必须写在所有的PHP代码之前声明,而且之前不能有任何输出,否则会出错
use Think\Controller;
表示引入 Think\Controller 类库便于直接使用。 所以,
namespace Home\Controller;
use Think\Controller;
class IndexController extends Controller
等同于使用:
namespace Home\Controller;
class IndexController extends \Think\Controller
配置文件
TP3中一个配置文件就可以实现很多信息的配置,如数据库信息的配置,路由规则配置等都会放在一个文件中。在TP5中则是通过专门的文件去配置不同的需求,如路由配置文件专门负责配置路由,数据库配置文件专门负责配置数据库信息。也可以翻翻模型代码,可能会有意外收获在TP 3中实例化模型的时候可以使用dns连接数据库。
在ThinkPHP中,一般来说应用的配置文件是自动加载的,加载的顺序是:
惯例配置->应用配置->模式配置->调试配置->状态配置->模块配置->扩展配置->动态配置
以上是配置文件的加载顺序,后面的配置会覆盖之前的同名配置
惯例配置
惯例重于配置是系统遵循的一个重要思想,框架内置有一个惯例配置文件(位于ThinkPHP/Conf/convention.php
)
应用配置
应用配置文件也就是调用所有模块之前都会首先加载的公共配置文件(默认位于Application/Common/Conf/config.php
)
模块配置
每个模块会自动加载自己的配置文件(位于Application/当前模块名/Conf/config.php
)。
路由
ThinkPHP的路由功能包括:
- 正则路由
- 规则路由
- 静态路由(URL映射)
- 闭包支持
配置文件Application/Common/Conf/config.php
启用路由
要使用路由功能,前提是你的URL支持PATH_INFO(或者兼容URL模式也可以,采用普通URL模式的情况下不支持路由功能),并且在应用(或者模块)配置文件中开启路由:
// 开启路由
'URL_ROUTER_ON' => true,
路由功能可以针对模块,也可以针对全局,针对模块的路由则需要在模块配置文件中开启和设置路由,如果是针对全局的路由,则是在公共模块的配置文件中开启和设置(后面我们以模块路由定义为例)。
然后就是配置路由规则了,在模块的配置文件中使用URL_ROUTE_RULES参数进行配置,配置格式是一个数组,每个元素都代表一个路由规则,例如:
'URL_ROUTE_RULES'=>array(
'news/:year/:month/:day' => array('News/archive', 'status=1'),
'news/:id' => 'News/read',
'news/read/:id' => '/news/:1',
),
系统会按定义的顺序依次匹配路由规则,一旦匹配到的话,就会定位到路由定义中的控制器和操作方法去执行(可以传入其他的参数),并且后面的规则不会继续匹配。
URL规则:
默认情况下可以使用PATHINFO模式、普通模式进行url访问
路由访问方式
在配置文件中可以通过URL_MODEL
设置访问方式
thinkPHP还支持几种URL模式,可以通过设置URL_MODEL
参数改变URL模式:
pathinfo模式
一个典型的URL访问规则是 (pathinfo模式)
http://serverName/index.php/模块/控制器/操作/[参数名/参数值...]
公共模块是一个特殊模块,访问所有的模块之前都会首先加载公共模块下的配置文件(Application/Common/conf/config.php)和公共函数文件(Application/Common/Common/function.php)。但是公共模块本身不能通过URL直接访问。
普通模式
使用GET传参的方式来指定当前访问的模块和操作
m
参数表示模块,c
参数表示控制器,a
表示操作 后面接形参
http://localhost/?m=home&c=user&a=login&var1=value1&var2=value2
http://localhost/index.php?m=home&c=user&a=login&var1=value1&var2=value2
REWRITE模式
在PATHINFO的基础上去掉入口文件
兼容方式
例如:
http://servername/index.php?s=/index/Index/index
http://servername/index.php?s=Actionlog/Backend/index
其中变量s
的名称的可以配置的。
router.php
也需要注意Application\
目录下的各个模块的Conf/router.php
文件,里面会定义一些具体的路由请求方式
例如
'home_list/:id' => 'Home/Index/home_list',
// 分类详细
'home_detail/:id' => 'Home/Index/home_detail',
//上传头像
'member/image/upload' => 'Home/Member/iamgeupload',
这时比如想走入Home/Index/home_list
也就是home_list
方法内,则需要访问home_list/:id
才可以
快捷方法
TP 3 对一些经常使用操作封装成了快捷方法,目的在于使程序更加简单安全
在TP 3官方文档中并没有做系统的介绍,不过在TP 5中就有系统整理,并且还给了一个规范命名:助手函数。
快捷方法一般位于ThinkPHP/Common/functions.php
I方法
PHP 程序一般使用$_GET, $_POST
等全局变量获取外部数据, 在ThinkPHP封装了一个I方法可以更加方便和安全的获取外部变量,可以用于任何地方,用法格式如下:
I('变量类型.变量名/修饰符',['默认值'],['过滤方法或正则'],['额外数据源'])
示例:
echo I('get.id'); // 相当于 $_GET['id']
echo I('get.name'); // 相当于 $_GET['name']
echo I('get.'); // 获取整个$_GET 数组
echo I('get.name','','htmlspecialchars'); // 采用htmlspecialchars方法对$_GET['name'] 进行过滤,如果不存在则返回空字符串
I方法的所有获取变量如果没有设置过滤方法的话都会进行htmlspecialchars过滤,那么:
// 等同于 htmlspecialchars($_GET['name'])I('get.name');
C方法
读取已有的配置,配置文件里面的数据就可以通过C方法读取
// 读取当前的URL模式配置参数
$model = C('URL_MODEL');
M方法/D方法
用于数据模型的实例化操作,具体这两个方法怎么实现,有什么区别,暂时就不多关注了,只用知道通过这两个快捷方法能快速实例化一个数据模型对象,从而操作数据库
//实例化模型
// 相当于 $User = new \Home\Model\UserModel();
$User = D('User');
// 和用法 $User = new \Think\Model('User'); 等效$User = M('User');
权限控制
需要找具体是哪个controller做的登陆控制。那么被use
或继承于这个controller的类都会鉴权