0x00MVC架构:
tp框架是基于MVC架构的:
M:Model 层操作数据库
V:View 视图层,就是web页面
C:Controller 控制器,相当于大脑
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');