一、控制器
按照ThinkPHP的架构设计,所有的URL请求(无论是否采用了路由),最终都会定位到控制器(也许实际的类不一定是控制器类,但也属于广义范畴的控制器)。控制器的层可能有很多,为了便于区分就把通过URL访问的控制器称之为访问控制器(通常意义上我们所说的控制器就是指访问控制器)。
ThinkPHP V5.1的控制器定义比较灵活,可以无需继承任何的基础类,也可以继承官方封装的\think\Controller类或者其他的控制器类,或者根据业务需求封装自己的基础控制器类。
控制器文件通常放在application/module/controller下面,类名和文件名保持大小写一致,并采用驼峰命名(首字母大写)。为了更方便使用,控制器类建议继承系统的控制器基类think\Controller,虽然无需继承也可以使用。
控制器类文件的实际位置是
application\index\controller\Index.php
访问URL地址是(假设没有定义路由的情况下)
http://localhost/index.php/index
1.控制器的命名空间
控制器类的所在命名空间为app\module\controller,其中根命名空间app为系统默认,并且只能通过环境变量设置更改,例如我们可以在.env配置文件中设置:
APP_NAMESPACE = application
只是命名空间改变了,但实际的文件位置和文件名并没有改变。
2.单一模块控制器
在应用配置文件app.php中设置
// 是否支持多模块
'app_multi_module' => false,
可以启用单一模块,那么控制器的命名空间中不需要模块名了,类的定义就变成了
<?php
namespace app\controller;
class Index {
public function index()
{
return 'index';
}
}
控制器类文件的实际位置则变成
application\controller\Index.php
3.渲染输出
默认情况下,控制器的输出全部采用return的方式,无需进行任何的手动输出,系统会自动完成渲染内容的输出。
下面都是有效的输出方式:
<?phpnamespace app\index\controller;
class Index {
public function hello()
{
// 输出hello,world!
return 'hello,world!';
}
public function json()
{
// 输出JSON
return json_encode($data);
}
public function read()
{
// 渲染默认模板输出
return view();
}
}
控制器一般不需要任何输出,直接return即可。
4.控制器初始化
如果你的控制器类继承了系统控制器基类(\think\Controller)的话,可以定义控制器初始化方法initialize,该方法会在调用控制器的方法之前首先执行,如非必要,不建议直接修改控制器的架构函数。
当前的请求对象由think\Request类负责,在很多场合下并不需要实例化调用,通常使用依赖注入即可。在其它场合(例如模板输出等)则可以使用think\facade\Request静态类操作。
二、请求对象调用
在控制器中通常情况下有两种方式进行依赖注入。
1.构造方法注入
<?php
namespace app\index\controller;
use think\Request;
class Index {
/**
* @var \think\Request Request实例
*/
protected $request;
/**
* 构造方法
* @param Request $request Request对象
* @access public
*/
public function __construct(Request $request)
{
$this->request = $request;
}
public function index()
{
return $this->request->param('name');
}
}
如果你继承了系统的控制器基类think\Controller的话,系统已经自动完成了请求对象的构造方法注入了,你可以直接使用$this->request属性调用当前的请求对象。
<?php
namespace app\index\controller;
use think\Controller;
class Index extends Controller{
public function index()
{
return $this->request->param('name');
}
}
2.操作方法注入
另外一种选择是在每个方法中使用依赖注入。
<?php
namespace app\index\controller;
use think\Controller;use think\Request;
class Index extends Controller{
public function index(Request $request)
{
return $request->param('name');
}
}
无论是否继承系统的控制器基类,都可以使用操作方法注入。
3.Facade调用
在没有使用依赖注入的场合,可以通过Facade机制来静态调用请求对象的方法(注意use引入的类库区别)。
<?php
namespace app\index\controller;
use think\Controller;use think\facade\Request;
class Index extends Controller{
public function index()
{
return Request::param('name');
}
}
该方法也同样适用于依赖注入无法使用的场合。
4.助手函数
为了简化调用,系统还提供了request助手函数,可以在任何需要的时候直接调用当前请求对象。
<?php
namespace app\index\controller;
use think\Controller;
class Index extends Controller{
public function index()
{
return request()->param('name');
}
}
三、实例演示依赖注入(构造器与普通方法)
代码如下:
<?php //用实例演示依赖注入(用构造器和普通方法) class Girl { public function work(){ return '会做饭'; } public function hobby(){ return '爱购物'; } } /** * 1.用构造方法进行依赖注入 */ class boy { private $girl1=null; public function __construct(Girl $girl) { $this->girl1=$girl; } public function getInfo(){ return '我的女朋友'.$this->girl1->work(); } } $girl=new Girl; $boy1=new boy($girl); echo $boy1->getInfo(); echo '<hr>'; /** * 2.用普通操作方法进行依赖注入 */ class Boy2 { public function buy(Girl $girl) { return '我的女朋友'.$girl->hobby(); } } $girl2=new Girl; $boy2=new Boy2; echo $boy2->buy($girl2);
点击 "运行实例" 按钮查看在线实例
2.运行结果