ThinkPHP是为了简化企业级应用开发和敏捷WEB应用开发而诞生的。最先诞生于2006年初,2007年元旦正式改名为ThinkPHP,而且遵循Apache2开源协议发布。ThinkPHP从诞生以来一直秉承简洁实用的设计原则,在保持出色的性能和至简的代码的同时,也注重易用性。而且拥有众多原创功能和特性,在社区团队的积极参与下,在易用性、扩展性和性能方面不断优化和改进。php
ThinkPHP是一个快速、兼容并且简单的轻量级国产PHP开发框架,诞生于2006年初,原名FCS,2007年元旦正式改名为ThinkPHP,遵循Apache2开源协议发布,从Struts结构移植过来并作了改进和完善,同时也借鉴了国外不少优秀的框架和模式,使用面向对象的开发结构和MVC模式,融合了Struts的思想和TagLib(标签库)、RoR的ORM映射和ActiveRecord模式。thinkphp
ThinkPHP能够支持windows/Unix/Linux等服务器环境,正式版须要PHP5.0以上版本支持,支持MySql、PgSQL、Sqlite以及PDO等多种数据库,ThinkPHP框架自己没有什么特别模块要求,具体的应用系统运行环境要求视开发所涉及的模块。数据库
做为一个总体开发解决方案,ThinkPHP可以解决应用开发中的大多数须要,由于其自身包含了底层架构、兼容处理、基类库、数据库访问层、模板引擎、缓存机制、插件机制、角色认证、表单处理等经常使用的组件,而且对于跨版本、跨平台和跨数据库移植都比较方便。而且每一个组件都是精心设计和完善的,应用开发过程仅仅须要关注您的业务逻辑。windows
Via: http://baike.baidu.com/view/908071.htm浏览器
ThinkPHP3.2彻底开发手册网址:http://document.thinkphp.cn/, TP框架的开发手册写得比较详细,只要静下心来学习,学会使用问题不大,若是想更加深刻的学习,TP框架的源代码最好能看懂,若是能作二次开发就更好了。缓存
学习的时候心要安静很重要,不能三心二意,心态不能浮躁,坚持下去,必定会有所收获的。安全
1、定义控制器
Application/Home/Controller/IndexController.class.php服务器
1 <?php 2 namespace Home\Controller; 3 use Think\Controller; 4 class UserController extends Controller { 5 public function index(){ 6 //Home\Controller\UserController::index this is news controller Home\Controller\UserController 7 echo __METHOD__ . ' this is news controller ' . __CLASS__; 8 } 9 } 10 ?>
Home\UserController类就表明了Home模块下的User控制器,而index操做就是Home\IndexController类的index(公共)方法。
当访问 http://serverName/Home/User/index or http://serverName/index.php/Home/User/index 后会输出:
Home\Controller\UserController::index this is news controller Home\Controller\UserControllercookie
控制器的名称采用驼峰法命名(首字母大写), 操做方法的定义必须是公共方法,不然会报操做错误session
2、设置操做方法的后缀
由于操做方法就是控制器的一个方法,因此遇到有和系统的关键字冲突的方法可能就不能定义了,这个时候咱们能够设置操做方法的后缀来解决,例如:
'ACTION_SUFFIX' => 'Action', // 操做方法后缀
将'ACTION_SUFFIX' => 'Action',加入到文件Application/Home/Conf/config.php中
Application/Home/Controller/TestController.class.php
1 <?php 2 namespace Home\Controller; 3 use Think\Controller; 4 class TestController extends Controller { 5 //http://localhost:81/research/thinkphp_3.2.3_full/Home/Test/hello 6 public function helloAction(){ 7 echo __METHOD__ . ' hello'; 8 } 9 10 //http://localhost:81/research/thinkphp_3.2.3_full/Home/Test/test 11 public function testAction(){ 12 echo __METHOD__ . ' test'; 13 } 14 } 15 ?>
操做方法的后缀设置只是影响控制器类的定义,对URL访问没有影响。
访问http://localhost:81/research/thinkphp_3.2.3_full/Home/Test/hello
输出Home\Controller\TestController::helloAction hello
访问http://localhost:81/research/thinkphp_3.2.3_full/Home/Test/test
输出Home\Controller\TestController::testAction test
注意,将ACTION_SUFFIX设置为Action之后('ACTION_SUFFIX' => 'Action'),若是控制器类中的方法名称后面不是Action,则访问时系统会报错。
例如
文件Application/Home/Controller/UserController.class.php内容以下:
1 <?php 2 namespace Home\Controller; 3 use Think\Controller; 4 class UserController extends Controller { 5 public function index(){ 6 //Home\Controller\UserController::index this is news controller Home\Controller\UserController 7 $str = 'inner ' . __METHOD__ . ' this is news controller ' . __CLASS__; 8 echo $str; 9 } 10 11 public function getUser() { 12 return 'inner ' . __METHOD__ . ' zhangsan'; 13 } 14 } 15 ?>
访问http://localhost:81/research/thinkphp_3.2.3_full/Home/User/index
则报以下的错误:
--------
非法操做:index
错误位置
FILE: E:\myphp\research\thinkphp_3.2.3_full\ThinkPHP\Library\Think\Controller.class.php LINE: 170
TRACE
#0 E:\myphp\research\thinkphp_3.2.3_full\ThinkPHP\Library\Think\Controller.class.php(170): E('????????????:in...')
#1 [internal function]: Think\Controller->__call('indexAction', '')
#2 E:\myphp\research\thinkphp_3.2.3_full\ThinkPHP\Library\Think\App.class.php(115): ReflectionMethod->invokeArgs(Object(Home\Controller\UserController), Array)
#3 E:\myphp\research\thinkphp_3.2.3_full\ThinkPHP\Library\Think\App.class.php(205): Think\App::exec()
#4 E:\myphp\research\thinkphp_3.2.3_full\ThinkPHP\Library\Think\Think.class.php(120): Think\App::run()
#5 E:\myphp\research\thinkphp_3.2.3_full\ThinkPHP\ThinkPHP.php(97): Think\Think::start()
#6 E:\myphp\research\thinkphp_3.2.3_full\index.php(24): require('E:\myphp\resear...')
#7 {main}
ThinkPHP3.2.3 { Fast & Simple OOP PHP Framework } -- [ WE CAN DO IT JUST THINK ]
--------
将方法名称由index改成indexAction
访问http://localhost:81/research/thinkphp_3.2.3_full/Home/User/index
输出inner Home\Controller\UserController::indexAction this is news controller Home\Controller\UserController
总结:也就是说,控制器的方法名称后面要么所有带有Action,要么所有没有Action,要统一, 将ACTION_SUFFIX设置为Action之后,不被url直接访问的控制器名称能够没有Action,如上面的getUser方法。
3、多级控制器
多级控制器
多级控制器是指控制器能够经过子目录把某个控制器层分组存放,首先须要设置控制器的分级层次,例如,咱们设置2级目录的控制器层:
'CONTROLLER_LEVEL' => 2,
将'CONTROLLER_LEVEL' => 2,加入到文件Application/Home/Conf/config.php中
Application/Home/Controller/News/NewsController.class.php
1 <?php 2 namespace Home\Controller\News; 3 use Think\Controller; 4 class NewsController extends Controller { 5 public function helloAction(){ 6 echo __CLASS__ . ' hello'; 7 } 8 9 public function testAction(){ 10 echo __CLASS__ . ' test'; 11 } 12 } 13 ?>
下面的url中第一个News表示目录路径,第二个News表示控制器名称
访问http://localhost:81/research/thinkphp_3.2.3_full/Home/News/News/hello
输出Home\Controller\News\NewsController hello
将CONTROLLER_LEVEL设为2之后,原来放到控制根目录(Application/Home/Controller)下的文件访问的时候会报错
访问http://localhost:81/research/thinkphp_3.2.3_full/Home/Test/hello
会报以下的错误
---------
没法加载控制器:Test/hello
错误位置
FILE: E:\myphp\research\thinkphp_3.2.3_full\ThinkPHP\Library\Think\App.class.php LINE: 102
TRACE
#0 E:\myphp\research\thinkphp_3.2.3_full\ThinkPHP\Library\Think\App.class.php(102): E('???????????????...')
#1 E:\myphp\research\thinkphp_3.2.3_full\ThinkPHP\Library\Think\App.class.php(205): Think\App::exec()
#2 E:\myphp\research\thinkphp_3.2.3_full\ThinkPHP\Library\Think\Think.class.php(120): Think\App::run()
#3 E:\myphp\research\thinkphp_3.2.3_full\ThinkPHP\ThinkPHP.php(97): Think\Think::start()
#4 E:\myphp\research\thinkphp_3.2.3_full\index.php(24): require('E:\myphp\resear...')
#5 {main}
ThinkPHP3.2.3 { Fast & Simple OOP PHP Framework } -- [ WE CAN DO IT JUST THINK ]
---------
总结:也就是说,控制器要么所有放在一级目录下,要么放在二级目录下,要统一。
4、实例化控制器
访问控制器的实例化一般是自动完成的,系统会根据URL地址解析出访问的控制器名称自动实例化,而且调用相关的操做方法。
若是你须要跨控制器调用的话,则能够单独实例化:
Application/Home/Controller/UserController.class.php
1 <?php 2 namespace Home\Controller; 3 use Think\Controller; 4 class UserController extends Controller { 5 public function indexAction(){ 6 /* 7 2016-3-23 8 用如下两种形式都可以访问,加不加index.php都可以访问 9 http://localhost:81/research/thinkphp_3.2.3_full/home/user/index 10 http://localhost:81/research/thinkphp_3.2.3_full/index.php/home/user/index 11 */ 12 //Home\Controller\UserController::index this is news controller Home\Controller\UserController 13 $str = 'inner ' . __METHOD__ . ' this is news controller ' . __CLASS__; 14 echo $str; 15 } 16 17 public function getUser() { 18 return 'inner ' . __METHOD__ . ' zhangsan'; 19 } 20 } 21 ?>
Application/Home/Controller/TestController.class.php
1 <?php 2 namespace Home\Controller; 3 use Think\Controller; 4 class TestController extends Controller { 5 public function helloAction(){ 6 echo __METHOD__ . ' hello'; 7 } 8 9 public function testAction(){ 10 echo __METHOD__ . ' test'; 11 } 12 13 public function instanceConAction() { 14 //下面这两种方式都可以实现化 15 //$user = new \Home\Controller\UserController(); 16 $user = A('User'); 17 echo 'inner ' . __METHOD__ . ' the name is ' . $user->getUser(); 18 } 19 } 20 ?>
系统为上面的控制器实例化提供了一个快捷调用方法A,$user = new \Home\Controller\UserController();能够简化为$user = A('User');
访问:http://localhost:81/research/thinkphp_3.2.3_full/Home/Test/instanceCon
输出:inner Home\Controller\TestController::instanceConAction the name is inner Home\Controller\UserController::getUser zhangsan
5、Action参数绑定
参数绑定是经过直接绑定URL地址中的变量做为操做方法的参数,能够简化方法的定义甚至路由的解析。
参数绑定功能默认是开启的,其原理是把URL中的参数(不包括模块、控制器和操做名)和操做方法中的参数进行绑定。
1.按变量名绑定
要启用参数绑定功能,首先确保你开启了URL_PARAMS_BIND设置:
'URL_PARAMS_BIND' => true, // URL变量绑定到操做方法做为参数
访问:http://localhost:81/research/thinkphp_3.2.3_full/Home/Blog/read/id/5
输出:id=5
访问http://localhost:81/research/thinkphp_3.2.3_full/Home/Blog/archive/year/2016/month/03
输出year=2016&month=03
按照变量名进行参数绑定的参数必须和URL中传入的变量名称一致,可是参数顺序不须要一致。也就是说
访问:http://localhost:81/research/thinkphp_3.2.3_full/Home/Blog/archive/month/03/year/2016(输出year=2016&month=03)
和上面的访问结果是一致的,URL中的参数顺序和操做方法中的参数顺序均可以随意调整,关键是确保参数名称一致便可。
下面的内容是ThinkPHP/conf/convention.php中的配置
'VAR_PATHINFO' => 's', // 兼容模式PATHINFO获取变量例如 ?s=/module/action/id/1 后面的参数取决于URL_PATHINFO_DEPR
'URL_PATHINFO_DEPR' => '/', // PATHINFO模式下,各参数之间的分割符号
若是使用下面的URL地址进行访问,参数绑定仍然有效:
http://localhost:81/research/thinkphp_3.2.3_full/index.php?s=/Home/Blog/read/id/5
http://localhost:81/research/thinkphp_3.2.3_full/index.php?s=/Home/Blog/archive/year/2013/month/11
http://localhost:81/research/thinkphp_3.2.3_full/index.php?c=Blog&a=read&id=5
http://localhost:81/research/thinkphp_3.2.3_full/index.php?c=Blog&a=archive&year=2013&month=11
Application/Home/Controller/BlogController.class.php
1 <?php 2 namespace Home\Controller; 3 use Think\Controller; 4 class BlogController extends Controller{ 5 public function read($id = 3){ 6 echo 'id='.$id; 7 } 8 9 public function archive($year='2013', $month='01'){ 10 echo 'year='.$year.'&month='.$month; 11 } 12 13 /** 14 * http://localhost:81/research/thinkphp_3.2.3_full/Home/Blog/input/year/2016/month/03 15 * path.1:input path.2:year path.3:2016 16 */ 17 public function input() { 18 echo 'path.0: ' . I('path.0') . ' path.1: ' . I('path.1') . ' path.2: ' . I('path.2') . ' path.3: ' . I('path.3'); 19 echo "\n"; 20 echo 'get.year:' . I('get.year') . ' get.month:' . I('get.month'); 21 echo "\n"; 22 23 print_r($_GET); 24 } 25 } 26 ?>
2.按变量顺序绑定
第二种方式是按照变量的顺序绑定,这种状况下URL地址中的参数顺序很是重要,不能随意调整。要按照变量顺序进行绑定,必须先设置URL_PARAMS_BIND_TYPE为1:
'URL_PARAMS_BIND_TYPE' => 1, // 设置参数绑定按照变量顺序绑定
将'URL_PARAMS_BIND_TYPE' => 1,加入到文件Application/Home/Conf/config.php中
访问:http://localhost:81/research/thinkphp_3.2.3_full/Home/Blog/read/5
输出: id=5
访问:http://localhost:81/research/thinkphp_3.2.3_full/Home/Blog/archive/2016/03
输出:year=2016&month=03
当设置URL_PARAMS_BIND_TYPE为1时,若是url中传递的参数仍然是按照变量名绑定,则输出的结果不是咱们想要的数据
访问:http://localhost:81/research/thinkphp_3.2.3_full/Home/Blog/read/id/5
输出: id=id
访问:http://localhost:81/research/thinkphp_3.2.3_full/Home/Blog/archive/year/2016/month/03
输出:year=year&month=2016
按变量顺序绑定的方式目前仅对PATHINFO地址有效,因此下面的URL访问参数绑定会失效:
http://localhost:81/research/thinkphp_3.2.3_full/index.php?c=Blog&a=read&id=5
http://localhost:81/research/thinkphp_3.2.3_full/index.php?c=Blog&a=archive&year=2013&month=11
可是,兼容模式URL地址访问依然有效:
http://localhost:81/research/thinkphp_3.2.3_full/index.php?s=/Home/Blog/read/5
http://localhost:81/research/thinkphp_3.2.3_full/index.php?s=/Home/Blog/archive/2013/11
6、输入变量
虽然你仍然能够在开发过程当中使用传统方式获取各类系统变量,例如:
$id = $_GET['id']; // 获取get变量
$name = $_POST['name']; // 获取post变量
$value = $_SESSION['var']; // 获取session变量
$name = $_COOKIE['name']; // 获取cookie变量
$file = $_SERVER['PHP_SELF']; // 获取server变量
可是咱们不建议直接使用传统方式获取,由于没有统一的安全处理机制,后期若是调整的话,改起来会比较麻烦。因此,更好的方式是在框架中统一使用I函数进行变量获取和过滤。
path类型变量能够用于获取URL参数(必须是PATHINFO模式参数有效,不管是GET仍是POST方式都有效)
Application/Home/Controller/BlogController.class.php
1 <?php 2 namespace Home\Controller; 3 use Think\Controller; 4 class BlogController extends Controller{ 5 public function read($id = 3){ 6 echo 'id='.$id; 7 } 8 9 public function archive($year='2013', $month='01'){ 10 echo 'year='.$year.'&month='.$month; 11 } 12 13 /** 14 * http://localhost:81/research/thinkphp_3.2.3_full/Home/Blog/input/year/2016/month/03 15 * path.1:input path.2:year path.3:2016 16 */ 17 public function input() { 18 echo 'path.0: ' . I('path.0') . ' path.1: ' . I('path.1') . ' path.2: ' . I('path.2') . ' path.3: ' . I('path.3'); 19 echo "\n"; 20 echo 'get.year:' . I('get.year') . ' get.month:' . I('get.month'); 21 echo "\n"; 22 23 print_r($_GET); 24 } 25 } 26 ?>
访问:http://localhost:81/research/thinkphp_3.2.3_full/index.php?m=Home&c=Blog&a=input&year=2016&month=03
输出:
path.0: path.1: path.2: path.3:
get.year:2016 get.month:03
Array
(
[year] => 2016
[month] => 03
)
访问:http://localhost:81/research/thinkphp_3.2.3_full/Home/Blog/input/2016/03
输出:
path.0: Blog path.1: input path.2: 2016 path.3: 03
get.year: get.month:
Array
(
[0] => 2016
[1] => 03
)
7、空操做
空操做是指系统在找不到请求的操做方法的时候,会定位到空操做(_empty)方法来执行,利用这个机制,咱们能够实现错误页面和一些URL的优化。
Application/Home/Controller/CityController.class.php
1 <?php 2 namespace Home\Controller; 3 use Think\Controller; 4 class CityController extends Controller{ 5 public function _empty($name){ 6 //把全部城市的操做解析到city方法 7 $this->city($name); 8 } 9 10 //注意 city方法 自己是 protected 方法 11 protected function city($name){ 12 //和$name这个城市相关的处理 13 echo '当前城市' . $name; 14 } 15 } 16 ?>
接下来,咱们就能够在浏览器里面输入
http://localhost:81/research/thinkphp_3.2.3_full/Home/City/beijing/
http://localhost:81/research/thinkphp_3.2.3_full/Home/City/shanghai/
http://localhost:81/research/thinkphp_3.2.3_full/Home/City/shenzhen/
因为City控制器并无定义beijing、shanghai或者shenzhen操做方法,所以系统会定位到空操做方法 _empty中去解析,_empty方法的参数就是当前URL里面的操做名,所以会看到依次输出的结果是:
当前城市:beijing
当前城市:shanghai
当前城市:shenzhen
8、空控制器
空控制器的概念是指当系统找不到请求的控制器名称的时候,系统会尝试定位空控制器(EmptyController),利用这个机制咱们能够用来定制错误页面和进行URL的优化。
Application/Home/Controller/EmptyController.class.php
1 <?php 2 namespace Home\Controller; 3 use Think\Controller; 4 class EmptyController extends Controller{ 5 public function index(){ 6 //根据当前控制器名来判断要执行那个城市的操做 7 $cityName = CONTROLLER_NAME; 8 /* 9 访问:http://localhost:81/research/thinkphp_3.2.3_full/Home/beijing/ 10 CONTROLLER_NAME的值为Beijing 11 */ 12 //echo 'CONTROLLER_NAME:' . CONTROLLER_NAME; 13 $this->city($cityName); 14 } 15 16 //注意 city方法 自己是 protected 方法 17 protected function city($name){ 18 //和$name这个城市相关的处理 19 echo '当前城市' . $name; 20 } 21 } 22 ?>
接下来,咱们就能够在浏览器里面输入
http://localhost:81/research/thinkphp_3.2.3_full/Home/beijing/
http://localhost:81/research/thinkphp_3.2.3_full/Home/shanghai/
http://localhost:81/research/thinkphp_3.2.3_full/Home/shenzhen/
因为系统并不存在beijing、shanghai或者shenzhen控制器,所以会定位到空控制器(EmptyController)去执行,会看到依次输出的结果是:
当前城市:beijing
当前城市:shanghai
当前城市:shenzhen