ThinkPHP5.0.11Day04 MVC架构,Controller控制器(_initialize,前置操作,空控制器,多级控制器)

0x00MVC架构:

tp框架是基于MVC架构的:
M:Model 层操作数据库
V:View 视图层,就是web页面
C:Controller 控制器,相当于大脑
MVC原理图

0x01Controller

两个命名空间:
think 对应 thinkphp/library/think 目录 loader.php中可以添加修改
app 对应 application 目录 public/index.php中定义的
Loader.php:
在这里插入图片描述
public/index.php:
在这里插入图片描述
thinkphp/Library/think/App.php
在这里插入图片描述现在APP_NAMESPACE对应的是app
如果要修改,可以在入口文件public/index.php下添加:

define('APP_NAMESPACE','Rerere');

这样就将原来的命名空间app修改为了Rerere

0x02 控制器的定义方式

在application目录下创建一个模块(目录),在模块下创建一个controller(目录),在controller下创建控制器文件。
注意:
1.控制器名首字母大写,例如:Index.php User.php Article.php
2.或者建议这样命名:IndexController.php UserController.php
2.控制器文件中,命名空间和目录结构相对应,创建一个和控制器文件同名的类:

<?php
namespace app\模块名\controller;
class 控制器文件名{
	public function ....(){
		return ....
	}
}

建议该类继承 Controller类,这样就可以使用Controller类中定义的方法
例如:

<?php
namespace app\模块名\controller;
use think/Controller;
class 控制器文件名 extends Controller{
	public function ....(){
		return ....
	}
}

0x03 _initialize()与__construct()

__contruct()是php原生的构造函数
_initialize()是tp框架带的构造函数,该函数里面调用了__construct()函数
当控制器的类中同时写了两种方法会调用__contruct()方法。
只要是类中方法运行之前,需要运行的代码,都放在_initialize()函数中就可以,例如:判断用户是否登录。
_initialize()用来初始化业务。
初始化类的话,就用__contruct()

<?php
namespace app\index\controller;
use think\Controller;
class Index extends Controller
{
  public function _initialize(){
      dump("this is init");
  }
  public function __construct(){
      dump("this is construct");
  }
  public function index(Request $request){
      return "hello world";
  } 

}

继承了Controller类后,能继承的方法:
initialize()
assign()
fetch()
display()
validate()

Controeller类继承了Jump类:
success(显示的信息,跳转到url,返回的数据,等多长时间)方法:用户登录成功后可以调用该方法

    /**
     * 操作成功跳转的快捷方法
     * @access protected
     * @param mixed  $msg    提示信息
     * @param string $url    跳转的 URL 地址
     * @param mixed  $data   返回的数据
     * @param int    $wait   跳转等待时间
     * @param array  $header 发送的 Header 信息
     * @return void
     * @throws HttpResponseException
     */
    protected function success($msg = '', $url = null, $data = '', $wait = 3, array $header = [])
    {
        if (is_null($url) && !is_null(Request::instance()->server('HTTP_REFERER'))) {
            $url = Request::instance()->server('HTTP_REFERER');
        } elseif ('' !== $url && !strpos($url, '://') && 0 !== strpos($url, '/')) {
            $url = Url::build($url);
        }

        $type = $this->getResponseType();
        $result = [
            'code' => 1,
            'msg'  => $msg,
            'data' => $data,
            'url'  => $url,
            'wait' => $wait,
        ];

        if ('html' == strtolower($type)) {
            $template = Config::get('template');
            $view = Config::get('view_replace_str');

            $result = ViewTemplate::instance($template, $view)
                ->fetch(Config::get('dispatch_success_tmpl'), $result);
        }

        $response = Response::create($result, $type)->header($header);

        throw new HttpResponseException($response);
    }

error()
redirect()

演示:
登录成功:

  public function index(){
      $this->success('登录成功!','https://www.baidu.com','','6');
  } 

登录失败:

  public function index(){
      $this->error('登录失败!','https://www.baidu.com','','6');
  } 

直接重定向:

  public function index(){
      $this->redirect('https://www.baidu.com');
  } 

准备工作:
修改域名:https://jeevin.cn/index.php/post/61.html
修改网站根目录为tp框架的public目录:https://www.cnblogs.com/xinxin1994/p/10145825.html
隐藏入口文件index.php:https://www.kancloud.cn/manual/thinkphp5/177576
配置路由:

Route::get('index/loginsuc','index/Index/loginSuc');

index.php

  public function index(){
      $this->success("登录成功","/index/loginsuc");
  } 
  public function loginSuc(){
      return "登录成功跳转到此地";
  }

跳转前:
在这里插入图片描述跳转后:
在这里插入图片描述

0x05 前置操作:

将需要前置操作的方法名,放在beforeActionList这前置方法列表中,就可以实现在调用某个方法前,先调用对应的前置方法的效果。
beforeAcitonList是定义在Controller.php中的一个成员属性,Controller类在构造函数中会查看该列表。
源码:

    /**
     * 构造方法
     * @access public
     * @param Request $request Request 对象
     */
    public function __construct(Request $request = null)
    {
        $this->view    = View::instance(Config::get('template'), Config::get('view_replace_str'));
        $this->request = is_null($request) ? Request::instance() : $request;

        // 控制器初始化
        $this->_initialize();

        // 前置操作方法
        if ($this->beforeActionList) {
            foreach ($this->beforeActionList as $method => $options) {
                is_numeric($method) ?
                $this->beforeAction($options) :
                $this->beforeAction($method, $options);
            }
        }
    

使用示范:
入口函数index.php

<?php
namespace app\index\controller;
use think\Controller;
class Index extends Controller
{
  // 首先,将需要前置的方法名都放在该列表中、
  protected $beforeActionList = [
    'allAction',//这样直接写表示以下所有方法在调用前都会调用该方法
    'onlyAction'=>['only'=>'index'],//用only可以限定,只有index方法调用前会调用该方法
    'exceptAction'=>['except'=>'index']//用except可以限定,除了index方法其他方法调用前都会调用该方法。
  ];
  public function index(){
    dump("this is index");
  } 
  public function allAction(){
    dump("this is allAction");
  }
  public function onlyAction(){
    dump("this is onlyAction");
  }
  public function exceptAction(){
    dump("除了index方法,其他方法都会调用该函数。");
  }
  public function test(){
    dump("this is test");
  }
}

0x06 空控制器

如果你配置路由时,配置了一个根本不存在的控制器名
例如:少了一个x

Route::any('index','index/inde/index',['method'=>'get | post']);

那么就会自动进入到一个名为Error.php的控制器下,去寻找相应的方法
当然前提是你要在对应的模块下创建一个Error.php,并写好对应的方法:

 <?php
namespace app\index\controller;
class Error{
    public function index(){
        dump("this is error controller");
    }
}

如果没有定义Error.php方法,那么就会提示没有此控制器。

0x07多级控制器

如果想更进一步细分业务就需要用到多级控制器:即可也在Controller文件夹下再创建文件夹,然后再创建控制器。
在这里插入图片描述演示:

<?php
namespace app\index\controller\article;
class NewsController{
    public function index(){
        return "this is NC controller";
    }
}

如何给多级控制器配置路由呢:用点表示法来表示控制器即可

Route::get('index/news','index/article.NewsController/index');
发布了156 篇原创文章 · 获赞 19 · 访问量 8915

猜你喜欢

转载自blog.csdn.net/weixin_43415644/article/details/104324299