一、url解析
1、thinkPHP框架的许多操作都是通过url来实现的,官方是这么介绍的:
6.0的URL访问受路由影响,如果在没有定义或匹配路由的情况下(并且没有开启强制路由模式的话),则是基于:
http://serverName/index.php(或者其它入口文件)/控制器/操作/参数/值…
如果使用自动多应用模式的话,URL一般是
http://serverName/index.php/应用/控制器/操作/参数/值...
我们的实际操作是
2、单应用http://tp.com/index.php/控制器/方法/参数/值...
多应用http://tp.com/index.php/应用/控制器/方法/参数/值...
3、先讲单应用:这里http://tp.com是指域名地址,比如 127.0.0.1:8000 或 localhost/Tp60-learning/,index.php是应用根目录public下的index.php即入口文件,
控制器 我们在应用根目录app目录下的controller控制器文件夹下新建admin.php控制器文件。地址则写为admin。
方法 例如admin控制器的hello方法,
参数和值 例如hello方法的默认参数name 和空值
4、那么完整的地址则为 http://tp.com/index.php/admin/hello/name/world 网页输出“hello,world”
5、多应用:由于thinkPHP默认是单应用模式,多应用的话需要作为扩展安装。
6、URL重写:可以通过URL重写隐藏应用的入口文件index.php(也可以是其它的入口文件,但URL重写通常只能设置一个入口文件),下面是相关服务器的配置参考:
在httpd.conf 配置文件中加载了 mod_rewrite.so 模块
将AllowOverride None 将选项 None 改为 All ;
7、对于 Apache还需要把下面的内容保存为.htaccess文件放到应用入口文件的同级目录下(一般来说如果你是通过Composer安装,这些配置是框架默认配置,无需修改)
<IfModule mod_rewrite.c>
Options +FollowSymlinks -Multiviews
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php/$1 [QSA,PT,L]
</IfModule>
8、做完上边步骤,重启apache后则可以:http://tp.com/admin/hello/name/worid 访问了
二、兼容模式
以上已经了解url的访问,通过admin控制器的讲解
如果上面url重写不支持,或服务器不支持PATHINFO,也可以使用兼容模式
http://tp.com/?s=admin/hello/name/worid
如果提示:No input file specified.
解决办法是打开public下的.htaccess文件,
把:RewriteRule ^(.*)$ index.php/$1 [QSA,PT,L]
改为:RewriteRule ^(.*)$ index.php [L,E=PATH_INFO:$1]
三、控制器定义
1、控制器,就是 controller ,控制器文件存放在 controller 目录下
2、如果想改变系统默认的控制器文件目录,可以在 config 下 route.php 配置文件找到:
// 访问控制器层名称
'controller_layer' => 'controller',
//例如修改为
'controller_layer' => 'controllersite',
3、类名和文件名大小写保持一致,并采用驼峰式(首字母大写)
<?php
namespace app\controller;
class Site
{
public function index(){
return "hello worid";
}
}
4、从上面得知 Site .php 的实际位置为:app\controller\Site.php, 访问URL地址是(假设没有定义路由的情况下)http://tp.com/site/index
5、我们接着创建一个hello方法
<?php
namespace app\controller;
class Site
{
public function index(){
return "hello worid";
}
public function hello(){
return "123";
}
}
6、Site 控制器 两个方法 index( 默认 ) 和 hello ,访问 URL 如下:
http://tp.com/site (由于每个控制器的index方法是默认方法,此时访问index方法可以免写)
http://tp.com/site/hello
7、如果我们创建双单词控制器该如何访问,我们创建一个hello world,和一个默认index方法
<?php
namespace app\controller;
class HelloWorld
{
public function index(){
return 'hello world';
}
}
访问方式如下
http://tp.com/helloworld
http://tp.com/hello_world
8、如果你想避免引入同类名时的冲突,可以 route.php 设置控制器后缀开启,
// 操作方法后缀
'action_suffix' => '',
//打开设置
'action_suffix' => 'true',
设置此选项是因为,后边使用模型的时候模型名和控制器名相同,为了避免混淆使用,此设置打开后就需要为控制器增加Controller后缀,比如前面的Site控制器就需要更名为SiteController.php
四、渲染输出
ThinkPHP 直接采用方法内 return 返回的方式直接就输出
public function index(){
return 'hello world';
}
如果返回值为数组,则需要使用json函数转换输出
<?php
namespace app\controller;
class HelloWorld
{
public function index(){
return 'hello world';
}
public function date(){
$date = array('a'=>1, 'b'=>2, 'c'=>3);
return json($date);
}
}
渲染模板输出,暂且放到后边讲。
如果在开发过程,需要调试中断,可以使用halt(),不推荐使用die、exit、等方法中断输出
<?php
namespace app\controller;
class HelloWorid
{
public function index(){
return 'hello worid';
}
public function date(){
$date = array('a'=>1, 'b'=>2, 'c'=>3);
$data = 'abc';
halt('测试');
return json($date);
}
}
五、基础控制器
一般来说,创建控制器后,推荐继承基础控制器app\BaseController来获得更多的方法,基础控制器仅仅提供了控制器验证功能,并注入了think\App和think\Request,这两个对象后面会有章节详细讲解,下面我们继承并简单使用一下:
返回当前实际路径
<?php
namespace app\controller;
use app\BaseController;
class Basics extends BaseController
{
public function index() {
//返回实际路径
return $this->app->getBasePath();
}
}
返回当前方法名
<?php
namespace app\controller;
use app\BaseController;
class Basics extends BaseController
{
public function index() {
//返回实际路径
//return $this->app->getBasePath();
// //返回当前方法名
return $this->request->action();
}
}
控制器验证,我们来写一个test方法
<?php
namespace app\controller;
use app\BaseController;
use think\exception\ValidateException;
class Basics extends BaseController
{
public function index() {
//返回实际路径
// return $this->app->getBasePath();
// //返回当前方法名
return $this->request->action();
}
//验证方法,验证定义值是否合法
public function test(){
try {
$this->validate( [
'name' => 'thinkphp',
'email' => 'thinkphp@qq.com',
], 'app\validate\User');
} catch (ValidateException $e) {
// 验证失败 输出错误信息
dump($e->getError());
}
}
}
访问地址:http://tp.com/Basics/test 提示错误,那是因为我没有设置验证器
在app目录下创建 validate目录,并创建user验证器user.php文件
<?php
namespace app\validate;
use think\Validate;
class User extends Validate
{
protected $rule = [
//设置规则
//name 不能为空,长度为25
'name' => 'require|max:25',
'age' => 'number|between:1,120',
'email' => 'email',
];
}
我们在次访问:http://tp.com/Basics/test,没有报错,也没有输出,我们把test方法的name设置为空再试一下,页面输出“^ "name不能为空"”
我们可以再完善一下自定义错误提示信息
<?php
namespace app\validate;
use think\Validate;
class User extends Validate
{
protected $rule = [
//设置规则
//name 不能为空,长度为25
'name' => 'require|max:25',
'age' => 'number|between:1,120',
'email' => 'email',
];
protected $message = [
'name.require' => '名字都不填,食屎呀雷',
'name.max' => '名称最多不能超过25个字符',
'age.number' => '年龄必须是数字',
'age.between' => '年龄只能在1-120之间',
'email' => '邮箱格式错误',
];
}
我们刷新一下,错误信息提示“^ "名字都不填,食屎呀雷"”
六、空控制器
空控制器的概念是指当系统找不到指定的控制器名称的时候,系统会尝试定位当前应用下的空控制器(Error)类,利用这个机制我们可以用来定制错误页面和进行URL的优化
在单应用模式下,我们可以给项目定义一个 Error 控制器类,来提醒错误;
<?php
namespace app\controller;
class Error
{
public function index(){
return '当前控制器不存在';
}
}
此时我们访问一个不存在的控制器如user控制器
http://tp.com/user
系统会自动跳转到Error控制器,并执行返回定义的内容
七、多级控制器
1、所谓多级控制器,就是在控制器 controller 目录下再建立目录并创建控制器,
2、个人理解,其实除了命名空间需要修改,引用路径不同和访问方式不同,其他和正常控制无太大差异
3、现在我们就在 controller 目录下建立user 目录,并创建username .php 控制器
<?php
namespace app\controller\user;
class UserName
{
public function user(){
return 'index';
}
}
4、我们需要访问的地址为
http://tp.com/user.username/user
只需用点连接controlle下的user目录和user目录的username控制器即可