还不会创建ThinkPHP V5.1专案的朋友们可以先去看看创建ThinkPHP V5.1专案。
何谓MVC?
所谓的MVC指的是分离资料、介面和操作等业务,让分工可以更加细化。
MVC展开来看就是Model-View-Controller。
ThinkPHP V5.1 里的MVC目录结构
ThinkPHP V5.1里的MVC相关文件一般都放在application目录里。
这里分成两种情况:
支持多模组(预设)
支持多模组的情况下,要新增控制器就必须要在application下面新增一个模组资料夹。这个资料夹下面再有model、view、controller三个资料夹,而我们的控制器文件就放在controller目录下。
比如添加一个含有Reader控制器的module模组:application/module/controller/Reader.php
同理,也会有:
application/module/view/
application/module/model/
这两个部分以后会详述,今天的关注重点放在控制器上。
单一模组
如果网页程式特别单纯,只需要一个控制器模组不需要多个模组,可以到config资料夹里的app.php
文件里将'app_multi_module' => false,
改成'app_multi_module' => true,
。这样一来,可以直接在application目录下加上controller目录,不需要再套一层模组资料夹(我们往后的说明都採用单模组,今天是为了演示模组跟控制器的关係,所以採用预设的多模组)。
application/controller/Reader.php
控制器文件规範
控制器在设计方面有一些硬性规定:
文件名称必须大写开头,所以上面的Reader.php都是大写开头。必须声明命名空间namespace。比如上述
application/module/controller/Reader.php
的Reader.php会有这么一行:namespace app\module\controller;
app
对应的是application目录,module
对应模组名称,controller
对应controller目录。那么,在单一模组的情况下,
application/controller/Reader.php
的namespace会是这样:namespace app\controller;
一个控制器文件里面只能有一个类别,且类别必须与文件同名。每个类别中都要有一个index函数,如果网址没有输入方法名,预设呼叫index方法。所以,Reader.php里面只会有一个Reader类,最好也跟文件名一样大写开头:
application/module/controller/Reader.php<?phpnamespace app\module\controller;class Reader{ public function index() { ... }}
控制器名称与访问方法
驼峰命名法所谓驼峰命名法指的是,当把多个单词连接起来时,每个词的开头用大写表示分界,例如hello world是两个词彙,把它们组合起来就要变成helloWorld。假设我们在module模组下面增加一个HelloWorld控制器:
application/module/controller/HelloWorld.php
application/module/controller/HelloWorld.php<?phpnamespace app\module\controller;class HelloWorld{ public function index() { ... }}
大概很多人会疑惑,这不是一种命名惯例而已吗?为何要专门挑出来说?
这是因为当你要在网址中呼叫某个控制器时,预设是不能输入大写字母的。
比如我要访问Reader控制器的index方法,我在网址列中要输入域名/public/module/reader/index
,那么要访问HelloWorld控制器是不是直接改成域名/public/module/helloworld/index
就行了?
答案是否定的,如果这么写会报错,因为域名/public/module/helloworld/index
对应的是Helloworld控制器,而非HelloWorld控制器。
那要怎么正确访问HelloWorld控制器呢?方法有两个:
把非开头大写字母改成_
加对应小写字母在这个例子中,把网址改成
域名/public/module/hello_world/index/
就可以访问HelloWorld控制器了。修改配置文件配置文件指的是放在专案根目录下的config目录里的app.php。
在文件里会有一个
'url_convert' => true
,把这一行改成'url_convert' => false
,这样网址就不会转变大小写了,可以直接输入原定名称来访问。但一般不建议这么做。继承控制器基类Controller
一般的MVC程式在实作控制器的时候都会继承控制器基类,ThinkPHP也不例外。
要继承控制器的方法是加上一行use think\Controller;
,然后在类别名称后面加上extends Controller。use think\Controller;
意思是引用thinkphp/library/think/Controller.php
。这里定义了Controller基类的内容,有兴趣的读者们可以自己去阅读代码。在引用了控制器基类后,使用extends关键字来继承。
如果Reader控制器要继承Controller,代码就会如下:
application/module/controller/Reader.php<?phpnamespace app\module\controller;use think\Controller;class Reader extends Controller{ public function index() { ... }}
事实上,在ThinkPHP里面并没有强制控制器一定要继承基类。有很多灵活的方法可以在不继承基类的情况下实现一样的功能。
控制器命名空间配置
相信有些小伙伴会有一个疑惑:
模组明明是放在根目录/application/
下面,为何控制器里的命名空间却是写成app
?
比如,application/module/controller/Reader.php
的命名空间为何要写成namespace app\module\controller;
,而不是namespace application\module\controller;
?
app
是预设的写法。
如果不习惯,想改成其他写法的话,可以在专案根目录下新增一个.env
文件。
内容是一个用等号隔开的键值对:配置选项=配置内容。控制器命名空间的键名是app_namespace
,如果想要让命名空间的app
变成application
(我知道你并不想),文件内容如下:
app_namespace=application
内容不需要用引号包裹,就是这么单纯。
这样,以后命名空间都必须写成namespace application\module\controller;
了。
下一篇,我会来介绍控制器的使用方法。