1. 2017年4月27日,ThinkPHP5.1-beta.1发布
2. 2017年12月31日, ThinkPHP5.1.0发布标志着快速进入迭代期
3. 2019年3月3日, ThinkPHP5.1已更新迭代到第35个版本(5.1.35)
4. 2019年3月22日, ThinkPHP5.2的dev开发版本也发布了
5. 5.2 改名为6.0
1. 全面支持采用PHP7强类型特性
2. 全面支持几乎所有PSR开发规范
3. 实现了多应用支持
4. 全面引入事件系统替代行为
5. 全新的应用服务架构
6. 视图和模板弓|擎分离,项目配置更灵活
7. IDE助手,使编辑器智能提示更准确
8. 对原来版本的一些函数和类方法进行了统一和精简
1. 环境要求: PHP 7.1+
2. 众所周知,从ThinkPHP5.1开始,官方网站已不再提供框架源码下载啦
3. 所以, ThinkPHP6.0(以下简称TP6)当然也不能从官网下载
4. Composer 和Git
5. 下面以最常用,也是官方推荐的Composer方式来下载框架源码
先切换到php环境根目录
cd d:/phpstudy/www
在执行下载Thinkphp6
命令。最后的tp,是新建个tp目录,可更改
composer create-project topthink/think tp
更新Thinkphp6
核心
composer update topthink/framework
现在只需要做最后一步来验证是否正常运行。
进入命令行下面,执行下面指令
php think run
在浏览器中输入地址:
http://localhost:8000/
会看到欢迎页面。恭喜你,现在已经完成ThinkPHP6.0
的安装!
如果你本地80端口没有被占用的话,也可以直接使用
php think run -p 80
然后就可以直接访问:
http://localhost/
1. 目录使用小写+下划线;
2. 类库、函数文件统一以`.php`为后缀;
3. 类的文件名均以命名空间定义,并且命名空间的路径和类库文件所在路径一致;
4. 类(包含接口和Trait)文件采用驼峰法命名(首字母大写),其它文件采用小写+下划线命名;
5. 类名(包括接口和Trait)和文件名保持一致,统一采用驼峰法命名(首字母大写);
7. 类的命名采用驼峰法(首字母大写),例如 `User`、`UserType`;
8. 函数的命名使用小写字母和下划线(小写字母开头)的方式,例如 `get_client_ip`;
9. 方法的命名使用驼峰法(首字母小写),例如 `getUserName`;
10. 属性的命名使用驼峰法(首字母小写),例如 `tableName`、`instance`;
11. 特例:以双下划线`__`打头的函数或方法作为魔术方法,例如 `__call` 和 `__autoload`;
1. 常量以大写字母和下划线命名,例如 `APP_PATH`;
2. 配置参数以小写字母和下划线命名,例如 `url_route_on` 和`url_convert`;
3. 环境变量定义使用大写字母和下划线命名,例如`APP_DEBUG`;
1. 数据表和字段采用小写加下划线方式命名,并注意字段名不要以下划线开头;
2. 例如 `think_user` 表和 `user_name`字段,不建议使用驼峰和中文作为数据表及字段命名。
├─app 应用目录
│ ├─controller 控制器目录
│ ├─model 模型目录
│ ├─ ... 更多类库目录
│ │
│ ├─common.php 公共函数文件、用户自定函数、可以在模板中快速调用
│ └─event.php 事件定义文件
│
├─config 配置目录
│ ├─app.php 应用配置
│ ├─cache.php 缓存配置
│ ├─console.php 控制台配置
│ ├─cookie.php Cookie配置
│ ├─database.php 数据库配置
│ ├─filesystem.php 文件磁盘配置
│ ├─lang.php 多语言配置
│ ├─log.php 日志配置
│ ├─middleware.php 中间件配置
│ ├─route.php URL和路由配置
│ ├─session.php Session配置
│ ├─trace.php Trace配置
│ └─view.php 视图配置
│
├─view 视图目录
├─route 路由定义目录
│ ├─route.php 路由定义文件
│ └─ ...
│
├─public WEB目录(对外访问目录)
│ ├─index.php 入口文件
│ ├─router.php 快速测试文件
│ └─.htaccess 用于apache的重写
│
├─extend 扩展类库目录
├─runtime 应用的运行时目录(可写,可定制)
├─vendor Composer类库目录
├─.example.env 环境变量示例文件
├─composer.json composer 定义文件
├─LICENSE.txt 授权说明文件
├─README.md README 文件
├─think 命令行入口文件
topthink 顶想科技
├─framework 框架
│ ├─src
│ │ ├─lang 语言包
│ │ ├─think 整个框架的源代码
│ │ ├─tpl 模板页面
│ │ └─helper.php 助手函数
├─think-helper
├─think-orm
└─think-trace
#ThinkPHP 6.0系统配置
推荐使用环境变量进行统一的配置 .env
使用框架内置的环境变量管理器:think\Facade\Env 【静态方式调用、省去实力化】
手动创建 .evn 文件,是一个隐藏文件
可以粘贴复制 .example.env 文件
注释 ;
每行结束不需要 ;
开启跟踪模式/调试模式:app_trace
数据库配置
配置格式
; 数据库配置项
database.type = mysql
database.hostname = 127.0.0.1
database.database = tp6
database.username = root
database.password = root
database.charset = utf8
database.hostport = 3306
database.debug = true
配置格式
[DATABASE]
TYPE = mysql
HOSTNAME = 127.0.0.1
DATABASE = test
USERNAME = username
PASSWORD = password
HOSTPORT = 3306
CHARSET = utf8
DEBUG = true
然后修改数据库配置文件:config/database.php
控制器获取配置文件信息
. 入口文件
应用入口文件 index.php
控制台入口文件 think
URL重写
Apache(不做讲解、知道就OK)
Nginx(重点讲解)
location / { // …..省略部分代码
if (!-e $request_filename) {
rewrite ^(.*)$ /index.php?s=/$1 last;
}
}
命名空间
参考地址:
定义
知识点
重载
接口:
使用接口(interface),可以指定某个类必须实现哪些方法,但不需要定义这些方法的具体内容。
接口是通过 interface 关键字来定义的,就像定义一个标准的类一样,但其中定义所有的方法都是空的。
接口中定义的所有方法都必须是公有,这是接口的特性。
要实现一个接口,使用 implements 操作符。类中必须实现接口中定义的所有方法,否则会报一个致命错误。类可以实现多个接口,用逗号来分隔多个接口的名称。
// 声明一个'iTemplate'接口
interface iTemplate
{
public function setVariable($name, $var);
public function getHtml($template);
}
// 实现接口
class Template implements iTemplate
{
private $vars = array();
public function setVariable($name, $var)
{
$this->vars[$name] = $var;
}
public function getHtml($template)
{
foreach($this->vars as $name => $value) {
$template = str_replace('{' . $name . '}', $value, $template);
}
return $template;
}
}
抽象类:abstract
任何一个类,如果它里面至少有一个方法是被声明为抽象的,那么这个类就必须被声明为抽象的。
定义为抽象的类不能被实例化。
被定义为抽象的方法只是声明了其调用方式(参数),不能定义其具体的功能实现。
继承一个抽象类的时候,子类必须定义父类中的所有抽象方法;
另外,这些方法的访问控制必须和父类中一样(或者更为宽松)。
例如某个抽象方法被声明为受保护的,那么子类中实现的方法就应该声明为受保护的或者公有的,
而不能定义为私有的。
路由简介
路由的作用就是让URL地址更加的规范和优雅,或者说更加简洁;
设置路由对URL的检测、验证等一系列操作提供了极大的便利性;
路由是默认开启的,如果想要关闭路由,在config/app.php配置;
// 是否启用路由
'with_route' => true,
路由的配置
route目录下的定义文件的文件名随机,都有效,或多个均有效果;
路由定义
最基础的路由定义方法:
Route::rule('路由表达式', '路由地址', '请求类型');
// 我们访问:http://serverName/new/5
// 会跳转到:http://serverName/news/read/id/5
// 原本的访问地址不能在访问
可以在rule方法中指定请求类型,不指定的话默认为任何请求类型有效;
注意:请求类型参数不区分大小写。
// 表示定义的路由规则在`POST`请求下才有效。
Route::rule('new/:id', 'News/update', 'POST');
// 表示支持 GET 和 POST 请求
Route::rule('new/:id','News/read','GET|POST');
请求快捷方法
类型 | 描述 | 快捷方法 |
---|---|---|
GET | GET请求 | get |
POST | POST请求 | post |
PUT | PUT请求 | put |
DELETE | DELETE请求 | delete |
PATCH | PATCH请求 | patch |
* | 任何请求类型 | any |
快捷注册方法的用法为:
Route::快捷方法名('路由表达式', '路由地址');
使用案例:
// 定义GET请求路由规则
Route::get('new/' ,'News/read');
// 定义POST请求路由规则
Route::post('new/' ,'News/update');
// 定义PUT请求路由规则
Route::put('new/:id','News/update');
// 定义DELETE请求路由规则
Route::delete('new/:id','News/delete');
// 所有请求都支持的路由规则
Route::any('new/:id','News/read');
规则表达式
规则表达式通常包含静态规则和动态规则,以及两种规则的结合;
// 首页访问路由
Route::rule('/', 'index');
// 静态地址路由
Route::rule('my', 'Member/myinfo');
// 静态地址和动态地址结合
Route::rule('blog/:id', 'Blog/read');
// 静态地址和动态地址结合
Route::rule('new/:year/:month/:day', 'News/read');
// 全动态地址
Route::rule(':user/:blog_id', 'Blog/read');
变量规则
系统默认的变量规则设置是\w+
,只会匹配字母、数字、中文和下划线字符,并不会匹配特殊符号以及其它字符,需要定义变量规则或者调整默认变量规则。
每个参数中可以包括动态变量,例如:变量
或者<变量>
都表示动态变量(新版推荐使用第二种方式,更利于混合变量定义),并且会自动绑定到操作方法的对应参数。
局部变量规则
仅在当前路由有效
如果我们需要对于具体的变量进行单独的规则设置,则需要通过pattern()方法;
// 将details方法里的id传值,严格限制必须只能是数字\d+;
Route::rule('details/:id', 'Address/details')->pattern(['id'=>'\d+']);
// 也可以设置search方法的两个值的规则,通过数组的方式传递参数;
Route::rule('search/:id/:uid', 'Address/search') ->pattern([ 'id' => '\d+', 'uid' => '\d+' ]);
全局变量规则
直接在app.php设置;
全部路由有效
Route::pattern( [
'id' => '\d+',
'uid' => '\d+',
'name' => '\w+'
]);
组合变量规则
如果你的路由规则比较特殊,可以在路由定义的时候使用组合变量。
Route::rule('details--' , 'address/detail')
->pattern([
'name' => '\w+',
'id'=>'\d+'
]);
组合变量的优势是路由规则中没有固定的分隔符,可以随意组合需要的变量规则和分割符,
例如路由规则改成如下一样可以支持:
Route::get('item' , 'product/detail')
->pattern([
'name' => '[a-zA-Z]+',
'id' => '\d+'
]);
Route::get('item@-' , 'product/detail')
->pattern([
'name' => '\w+',
'id' => '\d+'
]);
动态路由
路由地址
路由到控制器/操作
// 路由到blog控制器
Route::get('blog/:id','Blog/read');
路由到类的方法
// 路由地址的格式为:
// 1、\完整类名@方法名
// 2、\完整类名::方法名
// 执行 \app\index\service\Blog 类的 read 方法。
Route::get('blog/:id','\app\index\service\Blog@read');
// 执行 \app\index\service\Blog 类的 静态 read 方法。
Route::get('blog/:id','\app\index\service\Blog::read');
重定向路由
Route::redirect('blog/:id', 'http://blog.thinkphp.cn/read/:id', 302);
路由到模板
// 路由到模板文件 直接渲染模板输出。
// 表示该路由会渲染当前应用下面的view/index/hello.html模板文件输出。
Route::view('hello/:name', 'index/hello');
// 模板文件中可以直接输出当前请求的param变量,如果需要增加额外的模板变量,可以使用:
Route::view('hello/:name', 'index/hello', ['city'=>'shanghai']);
// 在模板中可以输出name和city两个变量。Hello,{$name}--{$city}!
路由到响应对象
Route::get('hello/:name', response()
->data('Hello,ThinkPHP')
->code(200)
->contentType('text/plain'));
路由到闭包
Route::get('hello', function () {
return 'hello,world!';
});
路由参数
参数 | 说明 | 方法名 |
---|---|---|
ext | URL后缀检测,支持匹配多个后缀 | ext |
deny_ext | URL禁止后缀检测,支持匹配多个后缀 | denyExt |
https | 检测是否https请求 | https |
domain | 域名检测 | domain |
complete_match | 是否完整匹配路由 | completeMatch |
model | 绑定模型 | model |
cache | 请求缓存 | cache |
ajax | Ajax检测 | ajax |
pjax | Pjax检测 | pjax |
json | JSON检测 | json |
validate | 绑定验证器类进行数据验证 | validate |
append | 追加额外的参数 | append |
middleware | 注册路由中间件 | middleware |
filter | 请求变量过滤 | filter |
路由中间件
路由分组
// 使用Route类的group方法进行注册,给分组路由定义一些公用的路由设置参数,例如:
Route::group('blog', function () {
Route::rule(':id', 'blog/read');
Route::rule(':name', 'blog/read');
})->ext('html')->pattern(['id' => '\d+', 'name' => '\w+']);
资源路由
支持设置RESTFul
请求的资源路由,方式如下:
Route::resource('blog', 'Blog');
表示注册了一个名称为blog
的资源路由到Blog
控制器,系统会自动注册7个路由规则,如下:
标识 | 请求类型 | 生成路由规则 | 对应操作方法(默认) |
---|---|---|---|
index | GET | blog |
index |
create | GET | blog/create |
create |
save | POST | blog |
save |
read | GET | blog/:id |
read |
edit | GET | blog/:id/edit |
edit |
update | PUT | blog/:id |
update |
delete | DELETE | blog/:id |
delete |
具体指向的控制器由路由地址决定,你只需要为Blog
控制器创建以上对应的操作方法就可以支持下面的URL访问:
http://serverName/blog/
http://serverName/blog/128
http://serverName/blog/28/edit