zoukankan      html  css  js  c++  java
  • ThinkPHP3.2.3学习笔记1---控制器

    ThinkPHP是为了简化企业级应用开发和敏捷WEB应用开发而诞生的。最早诞生于2006年初,2007年元旦正式更名为ThinkPHP,并且遵循Apache2开源协议发布。ThinkPHP从诞生以来一直秉承简洁实用的设计原则,在保持出色的性能和至简的代码的同时,也注重易用性。并且拥有众多原创功能和特性,在社区团队的积极参与下,在易用性、扩展性和性能方面不断优化和改进。

    ThinkPHP是一个快速、兼容而且简单的轻量级国产PHP开发框架,诞生于2006年初,原名FCS,2007年元旦正式更名为ThinkPHP,遵循Apache2开源协议发布,从Struts结构移植过来并做了改进和完善,同时也借鉴了国外很多优秀的框架和模式,使用面向对象的开发结构和MVC模式,融合了Struts的思想和TagLib(标签库)、RoR的ORM映射和ActiveRecord模式。

    ThinkPHP可以支持windows/Unix/Linux等服务器环境,正式版需要PHP5.0以上版本支持,支持MySql、PgSQL、Sqlite以及PDO等多种数据库,ThinkPHP框架本身没有什么特别模块要求,具体的应用系统运行环境要求视开发所涉及的模块。

    作为一个整体开发解决方案,ThinkPHP能够解决应用开发中的大多数需要,因为其自身包含了底层架构、兼容处理、基类库、数据库访问层、模板引擎、缓存机制、插件机制、角色认证、表单处理等常用的组件,并且对于跨版本、跨平台和跨数据库移植都比较方便。并且每个组件都是精心设计和完善的,应用开发过程仅仅需要关注您的业务逻辑。

    Via: http://baike.baidu.com/view/908071.htm

    ThinkPHP3.2完全开发手册网址:http://document.thinkphp.cn/, TP框架的开发手册写得比较详细,只要静下心来学习,学会使用问题不大,如果想更加深入的学习,TP框架的源代码最好能看懂,如果能做二次开发就更好了。

    学习的时候心要安静很重要,不能三心二意,心态不能浮躁,坚持下去,一定会有所收获的。

    一、定义控制器
    Application/Home/Controller/IndexController.class.php

     1 <?php
     2 namespace HomeController;
     3 use ThinkController;
     4 class UserController extends Controller {
     5     public function index(){
     6         //HomeControllerUserController::index this is news controller HomeControllerUserController
     7         echo __METHOD__ . ' this is news controller ' . __CLASS__;
     8     }
     9 }
    10 ?>

    HomeUserController类就代表了Home模块下的User控制器,而index操作就是HomeIndexController类的index(公共)方法。
    当访问 http://serverName/Home/User/index or http://serverName/index.php/Home/User/index 后会输出:
    HomeControllerUserController::index this is news controller HomeControllerUserController


    控制器的名称采用驼峰法命名(首字母大写), 操作方法的定义必须是公共方法,否则会报操作错误


    二、设置操作方法的后缀
    因为操作方法就是控制器的一个方法,所以遇到有和系统的关键字冲突的方法可能就不能定义了,这个时候我们可以设置操作方法的后缀来解决,例如:
    'ACTION_SUFFIX' => 'Action', // 操作方法后缀

    将'ACTION_SUFFIX' => 'Action',加入到文件Application/Home/Conf/config.php中

    Application/Home/Controller/TestController.class.php

     1 <?php
     2 namespace HomeController;
     3 use ThinkController;
     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
    输出HomeControllerTestController::helloAction hello

    访问http://localhost:81/research/thinkphp_3.2.3_full/Home/Test/test
    输出HomeControllerTestController::testAction test


    注意,将ACTION_SUFFIX设置为Action以后('ACTION_SUFFIX' => 'Action'),如果控制器类中的方法名称后面不是Action,则访问时系统会报错。

    例如
    文件Application/Home/Controller/UserController.class.php内容如下:

     1 <?php
     2 namespace HomeController;
     3 use ThinkController;
     4 class UserController extends Controller {
     5     public function index(){
     6         //HomeControllerUserController::index this is news controller HomeControllerUserController
     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 esearch hinkphp_3.2.3_fullThinkPHPLibraryThinkController.class.php  LINE: 170
    TRACE
    #0 E:myphp esearch hinkphp_3.2.3_fullThinkPHPLibraryThinkController.class.php(170): E('????????????:in...')
    #1 [internal function]: ThinkController->__call('indexAction', '')
    #2 E:myphp esearch hinkphp_3.2.3_fullThinkPHPLibraryThinkApp.class.php(115): ReflectionMethod->invokeArgs(Object(HomeControllerUserController), Array)
    #3 E:myphp esearch hinkphp_3.2.3_fullThinkPHPLibraryThinkApp.class.php(205): ThinkApp::exec()
    #4 E:myphp esearch hinkphp_3.2.3_fullThinkPHPLibraryThinkThink.class.php(120): ThinkApp::run()
    #5 E:myphp esearch hinkphp_3.2.3_fullThinkPHPThinkPHP.php(97): ThinkThink::start()
    #6 E:myphp esearch hinkphp_3.2.3_fullindex.php(24): require('E:myphp esear...')
    #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 HomeControllerUserController::indexAction this is news controller HomeControllerUserController

    总结:也就是说,控制器的方法名称后面要么全部带有Action,要么全部没有Action,要统一, 将ACTION_SUFFIX设置为Action以后,不被url直接访问的控制器名称可以没有Action,如上面的getUser方法。


    三、多级控制器

    多级控制器
    多级控制器是指控制器可以通过子目录把某个控制器层分组存放,首先需要设置控制器的分级层次,例如,我们设置2级目录的控制器层:

    'CONTROLLER_LEVEL' => 2,

    将'CONTROLLER_LEVEL' => 2,加入到文件Application/Home/Conf/config.php中

    Application/Home/Controller/News/NewsController.class.php

     1 <?php
     2 namespace HomeControllerNews;
     3 use ThinkController;
     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
    输出HomeControllerNewsNewsController hello

    将CONTROLLER_LEVEL设为2以后,原来放到控制根目录(Application/Home/Controller)下的文件访问的时候会报错

    访问http://localhost:81/research/thinkphp_3.2.3_full/Home/Test/hello
    会报如下的错误
    ---------
    无法加载控制器:Test/hello
    错误位置
    FILE: E:myphp esearch hinkphp_3.2.3_fullThinkPHPLibraryThinkApp.class.php  LINE: 102
    TRACE
    #0 E:myphp esearch hinkphp_3.2.3_fullThinkPHPLibraryThinkApp.class.php(102): E('???????????????...')
    #1 E:myphp esearch hinkphp_3.2.3_fullThinkPHPLibraryThinkApp.class.php(205): ThinkApp::exec()
    #2 E:myphp esearch hinkphp_3.2.3_fullThinkPHPLibraryThinkThink.class.php(120): ThinkApp::run()
    #3 E:myphp esearch hinkphp_3.2.3_fullThinkPHPThinkPHP.php(97): ThinkThink::start()
    #4 E:myphp esearch hinkphp_3.2.3_fullindex.php(24): require('E:myphp esear...')
    #5 {main}
    ThinkPHP3.2.3 { Fast & Simple OOP PHP Framework } -- [ WE CAN DO IT JUST THINK ]
    ---------

    总结:也就是说,控制器要么全部放在一级目录下,要么放在二级目录下,要统一。

    四、实例化控制器
    访问控制器的实例化通常是自动完成的,系统会根据URL地址解析出访问的控制器名称自动实例化,并且调用相关的操作方法。

    如果你需要跨控制器调用的话,则可以单独实例化:

    Application/Home/Controller/UserController.class.php

     1 <?php
     2 namespace HomeController;
     3 use ThinkController;
     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         //HomeControllerUserController::index this is news controller HomeControllerUserController
    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 HomeController;
     3 use ThinkController;
     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 HomeControllerUserController();
    16         $user = A('User');
    17         echo 'inner ' . __METHOD__ . ' the name is ' . $user->getUser();
    18     }
    19 }
    20 ?>

    系统为上面的控制器实例化提供了一个快捷调用方法A,$user = new HomeControllerUserController();可以简化为$user = A('User');

    访问:http://localhost:81/research/thinkphp_3.2.3_full/Home/Test/instanceCon
    输出:inner HomeControllerTestController::instanceConAction the name is inner HomeControllerUserController::getUser zhangsan


    五、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 HomeController;
     3 use ThinkController;
     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 "
    ";
    20         echo 'get.year:' . I('get.year') . ' get.month:' . I('get.month');
    21         echo "
    ";
    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


    六、输入变量

    虽然你仍然可以在开发过程中使用传统方式获取各种系统变量,例如:
    $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 HomeController;
     3 use ThinkController;
     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 "
    ";
    20         echo 'get.year:' . I('get.year') . ' get.month:' . I('get.month');
    21         echo "
    ";
    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
    )


    七、空操作
    空操作是指系统在找不到请求的操作方法的时候,会定位到空操作(_empty)方法来执行,利用这个机制,我们可以实现错误页面和一些URL的优化。

    Application/Home/Controller/CityController.class.php

     1 <?php
     2 namespace HomeController;
     3 use ThinkController;
     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


    八、空控制器
    空控制器的概念是指当系统找不到请求的控制器名称的时候,系统会尝试定位空控制器(EmptyController),利用这个机制我们可以用来定制错误页面和进行URL的优化。

    Application/Home/Controller/EmptyController.class.php

     1 <?php
     2 namespace HomeController;
     3 use ThinkController;
     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

  • 相关阅读:
    oracel 复制A列的内容到列
    视图转为表
    面向对象
    银弹效应
    解决linux删除文件后空间没有释放问题
    HttpAnalyzerStdV7安装教程
    HttpUploader6.2-process版本
    Chrome浏览器控件安装方法
    Firefox浏览器控件安装方法
    通达OA整合教程
  • 原文地址:https://www.cnblogs.com/caihuafeng/p/5327603.html
Copyright © 2011-2022 走看看