ThinkPhp5.0
目录结构
project 应用部署目录
├─application 应用目录(可设置)
│ ├─common 公共模块目录(可更改)
│ ├─index 模块目录(可更改)
│ │ ├─config.php 模块配置文件
│ │ ├─common.php 模块函数文件
│ │ ├─controller 控制器目录⭐️
│ │ ├─model 模型目录⭐️
│ │ ├─view 视图目录⭐️
│ │ └─ ... 更多类库目录
│ ├─command.php 命令行工具配置文件
│ ├─common.php 应用公共(函数)文件
│ ├─config.php 应用(公共)配置文件
│ ├─database.php 数据库配置文件
│ ├─tags.php 应用行为扩展定义文件
│ └─route.php 路由配置文件
├─extend 扩展类库目录(可定义)
├─public WEB 部署目录(对外访问目录)
│ ├─static 静态资源存放目录(css,js,image)
│ ├─index.php 应用入口文件⭐️
│ ├─router.php 快速测试文件
│ └─.htaccess 用于 apache 的重写
├─runtime 应用的运行时目录(可写,可设置)
├─vendor 第三方类库目录(Composer)
├─thinkphp 框架系统目录
│ ├─lang 语言包目录
│ ├─library 框架核心类库目录
│ │ ├─think Think 类库包目录
│ │ └─traits 系统 Traits 目录
│ ├─tpl 系统模板目录
│ ├─.htaccess 用于 apache 的重写
│ ├─.travis.yml CI 定义文件
│ ├─base.php 基础定义文件
│ ├─composer.json composer 定义文件
│ ├─console.php 控制台入口文件
│ ├─convention.php 惯例配置文件
│ ├─helper.php 助手函数文件(可选)
│ ├─LICENSE.txt 授权说明文件
│ ├─phpunit.xml 单元测试配置文件
│ ├─README.md README 文件
│ └─start.php 框架引导文件
├─build.php 自动生成定义文件(参考)
├─composer.json composer 定义文件
├─LICENSE.txt 授权说明文件
├─README.md README 文件
├─think 命令行入口文件
架构
模型-视图-控制器
thinkphp5.0 is based on mvc
一个控制器包含多个操作(方法),操作方法是一个URL访问的最小单元。
http: //serverName/index.php(或者其它应用入口文件)/模块/控制器/操作/[参数名/参数值...]
eg: localhost:8080/in`dex.php/index/method
模型类通常完成实际的业务逻辑和数据封装,并返回和格式无关的数据。
ThinkPHP的模型层支持多层设计,可以将模型更加细分,例如把模型层分为逻辑层/服务层/事件层等等。
控制器调用模型类后返回的数据通过视图组装成不同格式的输出
5.0的URL访问受路由决定,如果关闭路由或者没有匹配路由的情况下,则是基于
http: //serverName/index.php(或者其它应用入口文件)/模块/控制器/操作/参数/值…
应用与模块
一个典型的应用是由多个模块组成的,这些模块通常都是应用目录下面的一个子目录,每个模块都有自己独立的配置文件、公共文件和类库文件。如上index/test/test2为三个模块
行为Behavior
行为(Behavior)是在预先定义好的一个应用位置执行的一些操作。
发生作用的位置称之为钩子,当应用程序运行到这个钩子的时候,就会被拦截下来,统一执行相关的行为。给某一个钩子绑定相关行为就成了一种类 AOP编程的思想。
在应用程序中进行行为侦听
// 在app_init位置侦听行为
\think\Hook::listen('app_init');
然后对某个位置进行行为绑定:
// 绑定行为到app_init位置
\think\Hook::add('app_init','\app\index\behavior\Test');
入口文件和引导文件
入口文件
入口文件位置的设计是为了让应用部署更安全,public
目录为web可访问目录,其他的文件都可以放到非WEB访问目录下面。
一般路径在../public/index.php
Index.php
// 应用入口文件
// 定义项目路径
define('APP_PATH', __DIR__ . '/../application/');
// 加载框架引导文件
require __DIR__ . '/../thinkphp/start.php';
引导文件
start.php
文件就是系统默认的一个引导文件。在引导文件中,会依次执行下面操作:
加载系统常量定义;加载环境变量定义文件;注册自动加载机制;注册错误和异常处理机制;加载惯例配置文件;执行应用;
不要管细枝末节,往下看吧
分发请求
模块/控制器/操作
这是默认的分发请求机制,系统会根据URL或者路由地址来判断当前请求的模块、控制器和操作名,并自动调用相应的访问控制器类,执行操作对应的方法。
控制器的所有操作方法都是
return
返回而不是直接输出,系统会调用Response::send
方法将最终的应用返回的数据输出到页面或者客户端,并自动转换成default_return_type
参数配置的格式。所以,应用执行的数据输出只需要返回一个正常的PHP数据即可。
一句话概括:
controller用return就完事了,系统会帮你把返回的数据格式搞好然后输出给页面/客户端
URL
默认情况下,URL
是不区分大小写的,也就是说 URL
里面的模块/控制器/操作名会自动转换为小写,控制器在最后调用的时候会转换为驼峰法处理。
如果希望URL
访问严格区分大小写,可以在应用配置文件中设置:
// 关闭URL中控制器和操作名的自动转换
'url_convert' => false,
关闭后就变成大小写敏感了
模块设计
├─application 应用目录(可设置)
│ ├─common 公共模块目录(可选)
│ ├─common.php 公共函数文件
│ ├─route.php 路由配置文件
│ ├─database.php 数据库配置文件
│ ├─config.php 应用配置文件
│ ├─module1 模块1目录
│ │ ├─config.php 模块配置文件
│ │ ├─common.php 模块函数文件
│ │ ├─controller 控制器目录
│ │ ├─model 模型目录(可选)
│ │ ├─view 视图目录(可选)
│ │ └─ ... 更多类库目录
│ │
│ ├─module2 模块2目录
│ │ ├─config.php 模块配置文件
│ │ ├─common.php 模块函数文件
│ │ ├─controller 控制器目录
│ │ ├─model 模型目录(可选)
│ │ ├─view 视图目录(可选)
│ │ └─ ... 更多类库目录
命名空间
有效的解决了多模块和Composer
类库之间的命名空间冲突问题,并且实现了更加高效的类库自动加载机制。
$studentModel = new Student(✘)
//正确写法
$studentModel = new \app\index\model\Student
or
use app\index\model\Student
$studentModel = new Student
Traits
作为一种扩展机制,可以方便的实现一个类库的多继承问题。(看不懂)
数据输出
新版的控制器输出采用Response
类统一处理
通过设置
default_return_type
或者动态设置不同类型的Response
输出就可以自动进行数据转换处理
例如设为json:
'default_return_type'=>'json'
namespace app\index\controller;
class Index
{
public function index()
{
$data = ['name'=>'thinkphp','url'=>'thinkphp.cn'];
return ['data'=>$data,'code'=>1,'message'=>'操作完成'];
}
}
请求URL地址后返回
{"data":{"name":"thinkphp","url":"thinkphp.cn"},
"code":1,
"message":"\u64cd\u4f5c\u5b8c\u6210"}
配置
默认配置定义格式是返回php数组:
//项目配置文件
return [
// 默认模块名
'default_module' => 'index',
// 默认控制器名
'default_controller' => 'Index',
// 默认操作名
'default_action' => 'index',
//更多配置参数
//...
];
路由
5.0的路由是针对应用而不是针对模块,因此路由的设置也是针对应用下面的所有模块,如果希望不同的模块区分不同的设置(例如某些模块需要关闭路由,某些模块需要强制路由等),需要给该模块增加单独的入口文件,并作如下修改:
// 定义项目路径
define('APP_PATH', __DIR__ . '/../application/');
// 加载框架基础文件
require __DIR__ . '/../thinkphp/base.php';
// 绑定当前入口文件到admin模块
\think\Route::bind('admin');
// 关闭admin模块的路由
\think\App::route(false);
// 执行应用
\think\App::run()->send();
注册路由规则:
use think\Route;
// 注册路由到index模块的News控制器的read操作
Route::rule('new/:id','index/News/read');
//'路由规则','路由地址和参数'
我们访问:
http://serverName/new/5
会自动路由到:
http://serverName/index/news/read/id/5
并且原来的访问地址会自动失效。
批量注册路由:
Route::rule(['new/:id'=>'News/read','blog/:name'=>'Blog/detail']);
//指定请求类型,不指定的话默认为任何请求类型
Route::get(['new/:id'=>'News/read','blog/:name'=>'Blog/detail']);
Route::post(['new/:id'=>'News/update','blog/:name'=>'Blog/detail']);
默认情况下,只会加载一个路由配置文件route.php
,如果你需要定义多个路由文件,可以修改route_config_file
配置参数,例如:
// 定义路由配置文件(数组)
'route_config_file' => ['route', '模块1/route1', '模块2/route2'],
因为看的有点蒙,所以部分路由内容以后再看吧
控制器Controller
渲染输出页面
① view助手函数渲染模板输出
namespace app\index\controller;
class Index
{
public function index()
{
return view('index');
}
}
② 继承了think\Controller
namespace app\index\controller;
use think\Controller;
class Index extends Controller
{
public function index()
{
// 获取包含域名的完整URL地址
$this->assign('domain',$this->request->url(true));
return $this->fetch('index');
}
}
控制器初始化
在控制器中加入
public function _initialize()
{
echo 'init
';
}
执行控制器中的action之前会先执行_initialize()方法
前置操作
设置 beforeActionList
属性可以指定某个方法为其他方法的前置操作
namespace app\index\controller;
use think\Controller;
class Index extends Controller
{
protected $beforeActionList = [
'first',
'second' => ['except'=>'hello'],
'three' => ['only'=>'hello,data'],
];
/*first方法为所有action的前置操作
second为出了hello的其他方法的前置操作
three为hello,data方法的前置操作*/
protected function first()
{
echo 'first
';
}
protected function second()
{
echo 'second
';
}
protected function three()
{
echo 'three
';
}
public function hello()
{
return 'hello';
}
public function data()
{
return 'data';
}
}
访问 http: //localhost/index.php/index/Index/hello
输出为
first
three
hello
页面跳转与重定向
内置跳转:success/error
$this->success('新增成功', 'index');
重定向:
$this->redirect('/index/student/test');
index为模块名,student为Controller,test为controller下的方法
一定不要忘记index前的'\'符号,不然就默认访问$this所在控制器下的方法
空操作
系统在找不到指定的操作方法的时候,会定位到空操作(_empty
)方法来执行
public function _empty($action_name)
{
return $this->view('index');
}
空控制器
系统找不到指定的控制器名称的时候,系统会尝试定位空控制器(Error)
controller();
return $this->city($cityName);
}
//注意 city方法 本身是 protected 方法
protected function city($name)
{
//和$name这个城市相关的处理
return '当前城市' . $name;
}
}
输入
http://serverName/index/beijing/
http://serverName/index/shanghai/
http://serverName/index/shenzhen/
返回
当前城市:beijing
当前城市:Shanghai
当前城市:shenzhen
多级控制器
controller下面还有controller
namespace app\index\controller\one;⚠️
use think\Controller;
class Blog extends Controller
{
public function index()
{
return $this->fetch();
}
}
该控制器类的文件位置为:
application/index/controller/one/Blog.php
访问地址可以使用
http://serverName/index.php/index/one.blog/index
thinkphp中的namespace和java中的包概念是有区别的哟,java包还暗含了文件的物理地址,而namespace是指示的是逻辑地址
资源控制器
生成index模块的blog资源控制器
terminal中进入对应项目然后执行:
php think make:controller index/Blog
然后为资源控制器注册一个资源路由
Route::resource('blog','index/Blog');
设置后会自动注册7个路由规则,如下:
请求类型 | 生成路由规则 | 对应操作方法 |
---|---|---|
GET | blog |
index |
GET | blog/create |
create |
POST | blog |
save |
GET | blog/:id |
read |
GET | blog/:id/edit |
edit |
PUT | blog/:id |
update |
DELETE | blog/:id |
delete |
请求
请求信息
获取当前的请求信息
$request = Request::instance();
变量获取
get/post/put类型用param就对啦
// 获取当前请求的name变量
Request::instance()->param('name');
// 获取当前请求的所有变量(经过过滤)
Request::instance()->param();
// 获取当前请求的所有变量(原始数据)
Request::instance()->param(false);
// 获取当前请求的所有变量(包含上传文件)
Request::instance()->param(true);
方法 | 描述 |
---|---|
param | 获取当前请求的变量 |
get | 获取 $_GET 变量 |
post | 获取 $_POST 变量 |
put | 获取 PUT 变量 |
delete | 获取 DELETE 变量 |
session | 获取 $_SESSION 变量 |
cookie | 获取 $_COOKIE 变量 |
request | 获取 $_REQUEST 变量 |
server | 获取 $_SERVER 变量 |
env | 获取 $_ENV 变量 |
route | 获取 路由(包括PATHINFO) 变量 |
file | 获取 $_FILES 变量 |
变量修饰符
Request::instance()->变量类型('变量名/修饰符');
可以更好的过滤变量
修饰符 | 作用 |
---|---|
s | 强制转换为字符串类型 |
d | 强制转换为整型类型 |
b | 强制转换为布尔类型 |
a | 强制转换为数组类型 |
f | 强制转换为浮点类型 |
如果你要获取的数据为数组,请一定注意要加上
/a
修饰符才能正确获取到。