一、ThinkPHP6 安装
ThinkPHP是一个免费开源的,快速、简单的面向对象的轻量级PHP开发框架,是为了敏捷WEB应用开发和简化 企业应用开发而诞生的。ThinkPHP从诞生以来一直秉承简洁实用的设计原则,在保持出色的性能和至简代码的 同时,更注重易用性。
- 6.0 版本开始,必须通过 Composer 方式安装和更新,所以你无法通过 Git 下载安装。
- PHP运行环境需要 >= 7.1.0
1.安装 Composer
下载并运行(Window 环境) Composer-Setup.exe
安装步骤如下:
第一步:双击下载好的composer运行程序
第二步:点击下一步
第三步:选择要安装的盘符
第四步:选择php版本。如果你是集成包环境,就到集成包里找php
第五步:全部下一步
第六步:
第七步:
2.设置 Composer 下载源
先设置 Composer
的下载源,也是镜像地址
在命令行窗口或控制台 输入
composer config -g repo.packagist composer https://packagist.phpcomposer.com
国外的网站速度慢,官网建议使用国内镜像(阿里云)
composer config -g repo.packagist composer https://mirrors.aliyun.com/composer
3.安装 Thinkphp6
- 先切换到你的
php
环境根目录www
d:
cd phpstudy_pro/WWW
- 在执行下载
Thinkphp6
命令(tp6 为下载Thinkphp6
的目录) - 最后的tp6,是新建个tp6目录,可更改为项目名称
composer create-project topthink/think tp6
安装出现错误:查看composer
目前安装环境(主要是查看下载源,然后恢复官方源)
composer config -g -l repo.packagist
composer config -g --unset repos.packagist
更新Thinkphp6核心
composer update topthink/framework
备:安装和更新命令所在的目录是不同的,更新必须在你的应用根目录下面执行
4、配置、运行 Thinkphp6
第一步:打开
phpstudy
集成软件 -> 站点域名管理
第二步:网站域名:www.zhang.com
第三步:网站目录:tp6/public
第四步:直接在浏览器上输入域名:www.zhang.com
注:如果无法打开站点,在 C:\Windows\System32\drivers\etc 目录下,打开 hosts文件
最后一行输入 127.0.0.1 www.zhang.com
5、目录结构
- 6.0版本目录结构的主要变化是核心框架纳入vendor目录,然后原来的application目录变成app目录。
- 安装后的目录结构就是一个单应用模式
- 在 mac 或者 linux 环境下面,注意需要设置 runtime 目录权限为777
├─app 应用目录
│ ├─controller 控制器目录
│ ├─model 模型目录
│ ├─view 视图目录
│ ├─ ... 更多类库目录
│ │
│ ├─AppService.php 应用服务类
│ ├─BaseController.php 默认基础控制器类
│ ├─common.php 全局公共函数文件
│ ├─event.php 全局事件定义文件
│ ├─ExceptionHandle.php 应用异常定义文件
│ ├─middleware.php 全局中间件定义文件
│ ├─provider.php 服务提供定义文件
│ ├─Request.php 应用请求对象
│ └─service.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 视图配置
│
├─extend 扩展类库目录
├─public WEB目录(对外访问目录)
│ ├─index.php 入口文件
│ ├─router.php 快速测试文件
│ └─.htaccess 用于apache的重写
│
├─route 路由定义目录
│ ├─route.php 路由定义文件
│ └─ ...
│
├─runtime 应用的运行时目录(可写,可定制)
├─vendor Composer类库目录
├─view 视图目录
├─.example.env 环境变量示例文件
├─composer.json composer 定义文件
├─LICENSE.txt 授权说明文件
├─README.md README 文件
├─think 命令行入口文件
二、框架介绍
ThinkPHP是一个免费开源的,快速、简单的面向对象的轻量级PHP开发框架,是为了敏捷WEB应用开发和简化 企业应用开发而诞生的。ThinkPHP从诞生以来一直秉承简洁实用的设计原则,在保持出色的性能和至简代码的 同时,更注重易用性。
1、MVC
支持传统的 MVC(Model-View-Controller)模式
- M:
Model
模型,专门负责数据操作,针对数据库部分的代码。一个模型(类)针对一张数据表 - V:
View
视图,专门负责结果数据渲染(HTML+CSS+Javascript)。 - C:
Controller
控制器,负责所有的业务处理。一个控制器控制(类)一类业务。
2、入口文件
- ThinkPHP6.0 采用单一入口模式进行项目部署和访问,一个应用都有一个统一(但不一定是唯一)的入口。入口文件位于
public
目录下面,最常见的入口文件就是index.php
,Thinkphp6
支持多应用多入口
- 静态资源存放在主文件目录下public/static文件中即可
- 任何页面的js和css文件路径配置从public文件下开始配置即可
3、完整 url
index.php
入口文件,是根目录下public/
下的index.php
index
控制器,目录下有一个controller
控制器目录的Index.php
index
操作,Index.php
控制器下的操作方法,操作方法是一个URL
访问的最小单元。
注意:官方的实例Index\index.php控制器中的hello方法就不能以这种方式访问,因为该控制器方法在路由中进行了设置,需要通过http://www.zhang.com/hello/zhang进行访问,
http://www.zhang.com/Index/hello是无法访问到的。
路由 route/app.php
Route::get('think', function () {
return 'hello,ThinkPHP6!';
});
Route::get('hello/:name', 'index/hello');
/* 访问地址
http://zhang.com/think
http://zhang.com/hello/zhang
*/
5、Apache
隐藏入口文件
1.一般访问项目:入口文件+应用名+控制器+函数即可访问到,后面可以根一些get访问参数
2.为了访问方便一般会隐藏入口文件,在主文件目录下public文件下找到.htaccess
配置隐藏入口文件
- httpd.conf 配置文件中加载了 mod_rewrite.so 模块
- AllowOverride None 将 None 改为 All
- 把下面的内容保存为
.htaccess
文件放到应用入口文件的同级目录下
<IfModule mod_rewrite.c>
Options +FollowSymlinks -Multiviews
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php?/$1 [QSA,PT,L]
# RewriteRule ^(.*)$ index.php?/$1 [QSA,PT,L]
# RewriteRule ^(.*)$ index.php [L,E=PATH_INFO:$1]
</IfModule>
6、Nginx
隐藏入口文件
- 把下面的内容保存为
nginx.htaccess
文件放到应用入口文件的同级目录下
- 把下面的内容保存为
location / {
if (!-e $request_filename) {
rewrite ^(.*)$ /index.php?s=/$1 last;
}
}
三、控制器
- 控制器文件通常放在 controller 下面,类名和文件名保持大小写一致,并采用驼峰命名(首字母大写)
1、命名空间
// 命名空间一般和文件夹路径一致,类名称和文件名称一致
namespace app\controller;
2、继承基础控制器
namespace app\controller;
use app\BaseController;
class Index extends BaseController
{
public function index()
{
echo '这是index操作';
}
public function php(){
echo '这是php操作';
}
}
浏览地址:
默认可以直接写成 http://zhang.com
如果我们需要对所有控制器进行统一操作,可以对其继承的父类BaseController进行设置。
3、多操作方法
在同一个控制器中,我们可以定义多个操作方法
namespace app\controller;
use app\BaseController;
class Index extends BaseController
{
public function index()
{
echo '这是index操作';
}
public function php()
{
echo '这是php操作';
}
}
4、多控制器
在controller目录下,我们也可以新建多个控制器文件
namespace app\controller;
use app\BaseController;
class Login extends BaseController
{
public function login()
{
echo '这是登录操作';
}
public function reg()
{
echo '这是注册操作';
}
}
四、安装视图
- 视图功能由
\think\View
类配合视图驱动(也即模板引擎驱动)类一起完成,新版仅内置了PHP原生模板引擎(主要用于内置的异常页面输出),如果需要使用其它的模板引擎需要单独安装相应的模板引擎扩展
ThinkPHP6已独立出一套模版,命名为:ThinkTemplate模板引擎;
使用think-template模板引擎,需安装think-view;
composer require topthink/think-view
1、安装视图
d:
cd phpstudy_pro/WWW/tp6
composer require topthink/think-view
2、使用视图类
- 要使用View,必须先引入
think\facade\View
门面类 - fetch 方法渲染页面
参数:静态页面的路径,默认对应的静态页面
app\controller\Index.php代码
namespace app\controller;
use app\BaseController;
use think\View;
class Index extends BaseController
{
public function index(View $view)
{
return $view->fetch();
}
}
think\facade\View
门面类
<?php
namespace app\controller;
use think\facade\View;
class Test
{
public function index(){
return View::fetch();
}
}
?>
事实上,依赖注入和使用Facade
代理的效果大多数情况下是一样的,都是从容器中获取对象实例。例如:
<?php
namespace app\index\controller;
use think\View;
class Index
{
public function index(View $view)
{
return $view->fetch();
}
}
和下面的作用是一样的
<?php
namespace app\index\controller;
use think\facade\View;
class Index
{
public function index()
{
return View::fetch();
}
}
依赖注入的优势是支持接口的注入,而Facade
则无法完成。
一定要注意两种方式的
use
引入类库的区别
3、创建视图模板
- 在
view
目录下,创建Index/index.html
文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>tp</title>
</head>
<body>
<h1>Hello World!</h1>
</body>
</html>
4、指定渲染模板
例如view\Index文件夹下有多个视图文件,index.html,demo.html
我们可以指定哪个html文件,默认是类名称对应视图目录,方法名称对应目录里html文件名称
namespace app\controller;
use app\BaseController;
use think\View;
class Index extends BaseController
{
public function index(View $view)
{
// 默认是渲染index.html,我们可以指定为demo.html
return $view->fetch('demo');
}
}
备:Index类对应view下面的目录 Index
备:index方法对应view下面的目录里的静态文件index.html
5、数据交互
app\controller\Index.php
namespace app\controller;
use app\BaseController;
use think\facade\View;
class Index extends BaseController
{
public function index()
{
View::assign([
'name' => 'zhangshuai',
'age' => 18
]);
return View::fetch();
}
}
app\view\Index\index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<h1>姓名:{$name}</h1>
<h1>年龄:{$age}</h1>
</body>
</html>
6、视图目录
view
目录 可以放根目录,也可有放到app
目录
五、视图标签
- 模板引擎支持
普通标签
和XML标签
方式两种标签定义,分别用于不同的目的
标签类型 | 描述 |
---|---|
普通标签 | 主要用于输出变量、函数过滤和做一些基本的运算操作 |
XML标签 | 也称为标签库标签,主要完成一些逻辑判断、控制和循环输出,并且可扩展 |
1、模板变量
- assign 方法赋值属于全局变量赋值
- 模版输出 {$name}全局变量
app\controller\Index.php代码
<?php
namespace app\controller;
use think\facade\View;
class Index
{
public function index()
{
// 模板变量赋值
// View:assign('name','zhang');
// View::assign('email','zhang@qq.com');
// 或者数组形式批量赋值
View::assign([
'name'=>'zhang',
'email'=>'zhang@qq.com'
]);
// 模板输出
return View::fetch();
}
}
view\Index\index.html代码
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>ThinkPHP6</title>
</head>
<body>
姓名:{$name}
<br>
邮箱:{$email}
</body>
</html>
2、运算符
运算符 | 示例 |
---|---|
+ | {$a+$b} |
- | {$a-$b} |
* | {$a*$b} |
/ | {$a/$b} |
% | {$a%$b} |
++ | {$a++} 或 {++$a} |
— | {$a—} 或{—$a} |
综合运算 | {$a+$b*10+$c} |
三元运算符 | {$a==$b ? ‘yes’ : ‘no’} |
这里我们新建
控制器 app\controller\Test.php
视图app\view\Test\index.html
app\controller\Test.php 文件
<?php
namespace app\controller;
use think\facade\View;
class Test
{
public function index()
{
View::assign('a',100);
View::assign('b',21);
return View::fetch();
}
}
?>
app\view\Test\index.html文件
<!DOCTYPE html>
<html>
<head>
<title>运算符</title>
</head>
<body>
<div>{$a+$b}</div>
<div>{$a-$b}</div>
<div>{$a*$b}</div>
<div>{$a/$b}</div>
<div>{$a%$b}</div>
<div>{$a++}</div>
<div>{++$a}</div>
<div>{$a--}</div>
<div>{--$a}</div>
<div>{$c ? '存在' : '不存在'}</div>
</body>
</html>
预览地址:http://zhang.com/index.php/Test/index
3、模版函数
方法 | 描述 |
---|---|
date | 日期格式化(支持各种时间类型) |
format | 字符串格式化 |
upper | 转换为大写 |
lower | 转换为小写 |
first | 输出数组的第一个元素 |
last | 输出数组的最后一个元素 |
default | 默认值 |
raw | 不使用(默认)转义 |
md5 | md5加密 |
substr | 截取字符串 |
- 可以多函数调用
controller文件
<?php
namespace app\controller;
use think\facade\View;
class Test
{
public function index(){
View::assign('time',1576048640);
View::assign('num',10.0032);
View::assign('str','OUyangKE');
View::assign('arr',['皮特朱','咩咩','欧阳克']);
return View::fetch();
}
}
?>
view文件
<!DOCTYPE html>
<html>
<head>
<title>模版函数 </title>
</head>
<body>
<div>日期格式化{$time|date='Y-m-d H:i:s'}</div>
<div>字符串格式化{$num|format='%02d'}</div>
<div>小写转大写{$str|upper}</div>
<div>大写转小写{$str|lower}</div>
<div>数组第一个{$arr|first}</div>
<div>数组最后一个{$arr|last}</div>
<div>默认值:{$default|default="该用户很懒,什么也没有留下!"}</div>
<div>字符串截取{$str|substr=0,3}</div>
<div>md5散列处理{$str|md5}</div>
<div>调用多个函数{$str|lower|substr=0,3}</div>
</body>
</html>
4、foreach循环标签
foreach
标签的用法和PHP语法非常接近,用于循环输出数组或者对象的属性
controller文件
<?php
namespace app\controller;
use think\facade\View;
class Test
{
public function index(){
$arr = [
['id'=>1,'name'=>'皮特朱'],
['id'=>2,'name'=>'咩咩'],
['id'=>3,'name'=>'欧阳克']
];
View::assign('arr',$arr);
return View::fetch();
}
}
?>
view文件
<!DOCTYPE html>
<html>
<head>
<title>循环标签</title>
</head>
<body>
{foreach $arr as $k=>$v}
<span>索引:{$k}--</span>
<span>ID:{$v['id']}--</span>
<span>姓名:{$v['name']}</span>
<br>
{/foreach}
</body>
</html>
5、volist 循环标签
- 二维数组的结果输出
- name 模板赋值的变量名称
- id 当前的循环变量,可以随意起名
- key 下标,从1开始,默认变量i
- offset 开始行数
- length 获取行数
- empty 如果数据为空,显示此文字
view文件
<!DOCTYPE html>
<html>
<head>
<title>循环标签</title>
</head>
<body>
{foreach $arr as $k=>$v}
<span>索引:{$k}--</span>
<span>ID:{$v['id']}--</span>
<span>姓名:{$v['name']}</span>
<br>
{/foreach}
<hr>
{volist name="arr" id="v" key="k" offset="0" length="3"}
<span>索引:{$k}</span>
<span>ID:{$v['id']}</span>
<span>姓名:{$v['name']}</span>
<br>
{/volist}
</body>
</html>
6、if 判断标签
if
标签的用法和PHP语法非常接近,用于条件判断
controller文件
<?php
namespace app\controller;
use think\facade\View;
class Test
{
public function index(){
View::assign('status',1);
View::assign('order_status',4);
return View::fetch();
}
}
?>
view文件
<!DOCTYPE html>
<html>
<head>
<title>if 判断标签</title>
</head>
<body>
{if $status == 1}
<span>请求成功</span>
{/if}
{if $status == 0}
<span>请求失败</span>
{else/}
<span>数据异常</span>
{/if}
{if $order_status == 0}
<span>未支付</span>
{elseif $order_status == 1/}
<span>已支付</span>
{elseif $order_status == 2/}
<span>已发货</span>
{elseif $order_status == 3/}
<span>已收货</span>
{elseif $order_status == 4/}
<span>已评论</span>
{/if}
</body>
</html>
7、switch 判断标签
switch
标签的用法和PHP语法非常接近,用于条件判断
view文件
<!DOCTYPE html>
<html>
<head>
<title>switch 判断标签</title>
</head>
<body>
{switch $order_status}
{case 0 }<div>未支付</div>{/case}
{case 1 }<div>已支付 待发货</div>{/case}
{case 2 }<div>已发货 待收货</div>{/case}
{case 3 }<div>已收货 待评论</div>{/case}
{case 4 }<div>已完成</div>{/case}
{/switch}
</body>
</html>
8、包含文件
include
标签,引入模版文件load
标签,引入资源文件(css、js)
view文件,把头部和尾部分文件
{include file="public/header" /}
{include file="public/left" /}
{load href="/static/layui/css/layui.css" /}
{load href="/static/layui/layui.js" /}
{include file="public/tail" /}
9、其他标签
1、条件标签
标签 | 描述 |
---|---|
in | 判断变量是否存在某些值 |
notin | 判断变量是否不存在某些值 |
between | 判断变量是否存在某些值 |
notbetween | 判断变量是否不存在某些范围值 |
present | 判断某个变量是否 已定义 |
notpresent | 判断某个变量是否 未定义 |
empty | 判断某个变量是否为空 |
notempty | 判断某个变量是否不为空 |
defined | 判断某个常量是否 已定义 |
notdefined | 判断某个常量是否 未定义 |
public function index(){
View::assign('number',100);
View::assign('string','');
return View::fetch();
}
{in name="number" value="99,100,101"}
number等于99,100,101任意一个值
{/in}
{notin name="number" value="99,100,101"}
number不等于99,100,101任意一个值
{/notin}
{between name="number" value="1,10"}
number等于1 到 10 之间的任意一个值
{/between}
{notbetween name="number" value="1,10"}
number不等于1 到 10 之间的任意一个值
{/notbetween}
{present name="number"}
number已经定义
{/present}
{notpresent name="n"}
n还没有定义
{/notpresent}
{empty name="string"}
name为空值
{/empty}
{notempty name="string"}
name有值
{/notempty}
{defined name="NAME"}
NAME常量已经定义
{/defined}
{notdefined name="NAME"}
NAME常量未定义
{/notdefined}
2、比较标签
标签 | 描述 |
---|---|
eq | 等于 |
neq | 不等于 |
gt | 大于 |
egt | 大于等于 |
lt | 小于 |
elt | 小于等于 |
heq | 恒等于 |
nheq | 不恒等于 |
public function index(){
View::assign("number",100);
View::assign("string","欧阳克");
return View::fetch();
}
{eq name="number" value="100"}
number 等于 100
{/eq}
{neq name="number" value="101"}
number 不等于 101
{/neq}
{gt name="number" value="33"}
number 大于 33
{/gt}
{egt name="number" value="100"}
number 大于等于 100
{/egt}
{lt name="number" value="200"}
number 小于 200
{/lt}
{elt name="number" value="100"}
number 小于等于 100
{/elt}
{heq name="string" value="欧阳克"}
string 恒等于 欧阳克
{/heq}
{heq name="string" value="朱老师"}
string 恒不等于 朱老师
{/heq}
3、循环标签
标签 | 描述 |
---|---|
for | 计数循环 |
- start:开始值
- end:结束值
- step:步进值,默认1
- name:循环变量名,默认i
{for start="1" end="50" step="5" name="i"}
{$i}<br/>
{/for}
4、杂项标签
标签 | 描述 |
---|---|
literal | 原样输出 |
php | 使用原生php代码 |
{literal}
{$name} 这里$name不会被当作变量,而是普通字符
{/literal}
{php}
echo '欧阳克';
{/php}
六、配置文件
- 根目录下的 config 目录下面就是所有的配置文件
├─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 视图配置
│ └─ ... 更多配置文件
1、项目配置
应用配置文件 app.php
show_error_msg
本地开启,上线后要关闭
return [
// 应用地址
'app_host' => env('app.host', ''),
// 应用的命名空间
'app_namespace' => '',
// 是否启用路由
'with_route' => true,
// 默认应用
'default_app' => 'index',
// 默认时区
'default_timezone' => 'Asia/Shanghai',
// 应用映射(自动多应用模式有效)
'app_map' => [],
// 域名绑定(自动多应用模式有效)
'domain_bind' => [],
// 禁止URL访问的应用列表(自动多应用模式有效)
'deny_app_list' => [],
// 异常页面的模板文件
'exception_tmpl' => app()->getThinkPath() . 'tpl/think_exception.tpl',
// 错误显示信息,非调试模式有效
'error_message' => '页面错误!请稍后再试~',
// 显示错误信息
'show_error_msg' => true,
];
‘show_error_msg’ => true 开启错误提示信息
<?php
namespace app\controller;
use think\facade\View;
class Test
{
public function index()
{
return View::fetch();
}
}
?>
渲染一个不存在的视图 模板文件view/Test/index.html
默认调错信息是关闭的,什么时候都提示’页面错误!请稍后再试~’
app\view\Test\index.html
<!DOCTYPE html>
<html>
<head>
<title>tp</title>
</head>
<body>
<h1>ThinkPHP</h1>
</body>
</html>
2、 视图配置
模版配置 view.php
return [
// 模板引擎类型使用Think
'type' => 'Think',
// 默认模板渲染规则 1 解析为小写+下划线 2 全部转换小写 3 保持操作方法
'auto_rule' => 1,
// 模板目录名
'view_dir_name' => 'view',
// 模板后缀
'view_suffix' => 'html',
// 模板文件名分隔符
'view_depr' => DIRECTORY_SEPARATOR,
// 模板引擎普通标签开始标记
'tpl_begin' => '{',
// 模板引擎普通标签结束标记
'tpl_end' => '}',
// 标签库标签开始标记
'taglib_begin' => '{',
// 标签库标签结束标记
'taglib_end' => '}',
];
- 模版后缀,改为php、htm、xml、aps试试
- 普通标签和XML标签的标记改变试试{{$name}}、{zs{$name}}、[$name]、&&$name&&、%$name%
3、数据库配置
return [
// 默认使用的数据库连接配置
'default' => env('database.driver', 'mysql'),
// 自定义时间查询规则
'time_query_rule' => [],
// 自动写入时间戳字段
// true为自动识别类型 false关闭
// 字符串则明确指定时间字段类型 支持 int timestamp datetime date
'auto_timestamp' => true,
// 时间字段取出后的默认时间格式
'datetime_format' => 'Y-m-d H:i:s',
// 数据库连接配置信息
'connections' => [
'mysql' => [
// 数据库类型
'type' => env('database.type', 'mysql'),
// 服务器地址
'hostname' => env('database.hostname', '127.0.0.1'),
// 数据库名
'database' => env('database.database', 'mydb'),
// 用户名
'username' => env('database.username', 'root'),
// 密码
'password' => env('database.password', 'root'),
// 端口
'hostport' => env('database.hostport', '3306'),
// 数据库连接参数
'params' => [],
// 数据库编码默认采用utf8
'charset' => env('database.charset', 'utf8'),
// 数据库表前缀
'prefix' => env('database.prefix', ''),
// 数据库部署方式:0 集中式(单一服务器),1 分布式(主从服务器)
'deploy' => 0,
// 数据库读写是否分离 主从式有效
'rw_separate' => false,
// 读写分离后 主服务器数量
'master_num' => 1,
// 指定从服务器序号
'slave_no' => '',
// 是否严格检查字段是否存在
'fields_strict' => true,
// 是否需要断线重连
'break_reconnect' => false,
// 监听SQL
'trigger_sql' => env('app_debug', true),
// 开启字段缓存
'fields_cache' => false,
],
// 更多的数据库配置信息
],
];
4、env
环境变量定义
配置 .env
- 默认安装后的根目录有一个.example.env 环境变量示例文件,如果要使用你可以直接改成.env 文件后进行修改配置
APP_DEBUG = true
[APP]
DEFAULT_TIMEZONE = Asia/Shanghai
[DATABASE]
TYPE = mysql
HOSTNAME = 127.0.0.1
DATABASE = mydb
USERNAME = username
PASSWORD = password
HOSTPORT = 3306
CHARSET = utf8
DEBUG = true
[LANG]
default_lang = zh-cn
七、使用 tp
核心功能
序号 | (动态)系统类库 | 容器绑定标识 | (门面)Facade 类 | 助手函数 |
---|---|---|---|---|
1 | think\App | app | think\facade\App | app |
2 | think\Cache | cache | think\facade\Cache | cache |
3 | think\Config | config | think\facade\Config | config |
4 | think\Cookie | cookie | think\facade\Cookie | cookie |
5 | think\Console | console | ||
6 | think\Db | db | think\facade\Db | |
7 | think\Debug | debug | ||
8 | think\Env | env | think\facade\Env | env |
9 | think\Event | event | think\facade\Event | event |
10 | think\Http | http | ||
11 | think\Lang | lang | think\facade\Lang | lang |
12 | think\Log | log | think\facade\Log | |
13 | think\Middleware | middleware | think\facade\Middleware | |
14 | think\Request | request | think\facade\Request | request |
15 | think\Response | response | response | |
16 | think\Filesystem | filesystem | think\facade\Filesystem | |
17 | think\Route | route | think\facade\Route | |
18 | think\Session | session | think\facade\Session | session |
19 | think\Validate | validate | think\facade\Validate | validate |
20 | think\View | view | think\facade\View | view |
1、系统库类
https://www.kancloud.cn/manual/thinkphp6_0/1037489
- 绑定标识调用的时候区分大小写,系统已经内置绑定了核心常用类库,无需重复绑定
namespace app\controller;
use app\BaseController;
use think\View;
use think\Config;
class Index extends BaseController
{
// 使用时,需要通过参数依赖注入到方法体中
public function index(View $view,Config $config)
{
print_r($config->get('app'));
print_r($config->get('database.connections'));
$view->assign([
'name' => 'zhangshuai'
]);
return $view->fetch('index');
}
}
2、(门面) Facade 类
https://www.kancloud.cn/manual/thinkphp6_0/1037491
namespace app\controller;
use app\BaseController;
use think\facade\View;
use think\facade\Config;
class Index extends BaseController
{
public function index()
{
// 无需依赖注入参数,直接通过容器绑定标识::静态调用方法
print_r(Config::get('app'));
print_r(Config::get('database.connections'));
View::assign([
'name' => 'zhangshuai'
]);
return View::fetch('index');
}
}
3、助手函数
https://www.kancloud.cn/manual/thinkphp6_0/1037653
namespace app\controller;
use app\BaseController;
class Index extends BaseController
{
public function index()
{
print_r(config('app'));
print_r(config('database.connections'));
return view('index', [
'name' => 'zhangshuai'
]);
}
}
八、数据库操作
查询构造器:https://www.kancloud.cn/manual/thinkphp6_0/1037532
1、数据表
CREATE TABLE `boke` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID',
`title` varchar(300) DEFAULT NULL COMMENT '标题',
`img` varchar(300) DEFAULT NULL COMMENT '图片',
`content` text COMMENT '内容',
`date` date DEFAULT NULL COMMENT '时间',
`cat` varchar(50) DEFAULT NULL COMMENT '类型',
`num` int(10) unsigned DEFAULT '0' COMMENT '浏览量',
`hot` tinyint(1) unsigned DEFAULT '0' COMMENT '热门 1是 0否',
`status` tinyint(1) unsigned DEFAULT '1' COMMENT '状态 1开启 0关闭',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8;
INSERT INTO `boke` VALUES ('1', '《天龙八部》系列课程', 'https://img.php.cn/upload/course/000/000/001/5d242759adb88970.jpg', 'PHP中文网因专业的讲师水平和高效的视频质量,推出的各种视频课程系列一直以来都深受大家喜爱。特别是《天龙八部》系列、《独孤九贱》系列、《玉女心经》系列的原创课程在行业内更是具有强大的影响力,好评不断!为了让大家能更快速方便的寻找到相关教程资源,我们在这篇文章中特意将《天龙八部》系列课程整理出来供大家有针对性得学习!', '2021-02-18', 'PHP', '0', '0', '1');
INSERT INTO `boke` VALUES ('2', 'php中文网《玉女心经》公益PHP WEB培训系列课程汇总', 'https://img.php.cn/upload/course/000/126/153/5aa23f0ded921649.jpg', 'php中文网近期推出的《独孤九贱》系列、《天龙八部》系列、《玉女心经》原创视频课程,好评如潮!由于《玉女心经》系列课程没有做成专题,所以大家找起来有点费劲,为了更好的服务广大php中文网粉丝们,特把课程整理汇总给大家!', '2021-02-11', 'PHP', '0', '0', '1');
INSERT INTO `boke` VALUES ('3', 'html5中submit是按钮么', null, 'html5中submit是按钮,它是button的一个特例,它把提交这个动作自动集成了。submit会自动将表单的数据提交,使用submit时需要验证要加return', '2021-02-10', '前端', '0', '0', '1');
INSERT INTO `boke` VALUES ('4', 'css如何去除下划线', null, 'css去除下划线的方法:首先创建一个HTML示例文件;然后在body中定义一个a标签;最后通过css属性为“a{text-decoration:none}”去除下划线即可。', '2021-02-01', '前端', '0', '0', '1');
INSERT INTO `boke` VALUES ('5', 'linux如何查看进程', 'https://img.php.cn/upload/article/202102/24/2021022409272725770.jpg', 'windows defender是windows系统自带的一款杀毒软件,对于很多人来说,这款软件不仅没有起到保护电脑的作用,还增加了很多不必要的麻烦。比如我们安装了一些破解版软件,windows defender就会杀这些破解软件,很让人讨厌。', '2021-02-01', '服务器', '1', '0', '1');
INSERT INTO `boke` VALUES ('6', 'Ubuntu20.04/18.04下安装或更新至PHP8', 'https://img.php.cn/upload/article/000/000/020/2c02ff679ec7afab974a691aac09d535-0.png', '本指南让你了解如何安装最新的 php 版本 8,并在你的任何 VPS、云服务器、专用主机上的 Ubuntu 20.0 或 18.04 系统中升级到最新版本,并将其配置为 Apache 和 Nginx。', '2021-02-01', 'PHP', '5', '0', '1');
INSERT INTO `boke` VALUES ('7', 'PHP 8新特性之JIT对PHP应用性能的影响', null, '即将发布的 PHP 8 最受大家关注的新特性就是引入了对 JIT 的支持,我已经简单介绍了 JIT 是什么,以及与 Opcache 的区别', '2021-02-01', 'PHP', '97', '0', '1');
INSERT INTO `boke` VALUES ('8', '详解PHP7中的zval结构和引用计数机制', 'https://img.php.cn/upload/article/000/000/024/6053286f637d2966.jpg', '最近在查阅 PHP7 垃圾回收的资料的时候,网上的一些代码示例在本地环境下运行时出现了不同的结果,使我一度非常迷惑。 仔细一想不难发现问题所在:这些文章大多是 PHP5.x 时代的,而 PHP7 发布后,采用了新的 zval 结构,相关的资料也比较贫瘠,所以我结合一些资料做了一个总结,主要侧重于解释新 zval 容器中的引用计数机制,如有谬误,还望不吝指教。', '2021-01-01', 'PHP', '185', '0', '1');
INSERT INTO `boke` VALUES ('9', 'php登录失败怎么处理', 'https://img.php.cn/upload/article/202103/19/2021031909102812621.jpg', 'php登录失败的处理方法:首先创建一个表负责记录用户登录的信息;然后从user_login_info表查询最近30分钟内有没有相关密码错误的记录;接着统计记录总条数是否达到设定的错误次数;最后设置登录密码错误次数限制即可。', '2021-01-01', 'PHP', '0', '0', '1');
INSERT INTO `boke` VALUES ('10', 'php如何去掉字符串末尾字符', 'https://img.php.cn/upload/article/000/000/024/6053250623ecf930.jpg', 'php去掉字符串末尾字符的方法:1、直接使用substr()函数倒序裁掉最后一位字符,语法“substr(string,0,-1)”;2、使用rtrim()函数,语法“rtrim(string,charlist)”。', '2021-01-01', 'PHP', '0', '0', '1');
INSERT INTO `boke` VALUES ('11', 'php异常和错误的区别是什么', 'https://img.php.cn/upload/article/202103/18/2021031817511956954.jpg', 'php异常和错误的区别:1、PHP错误是属于php程序自身的问题,一般是由非法的语法,环境问题导致的;2、PHP异常一般是业务逻辑上出现的不合预期、与正常流程不同的状况,不是语法错误。', '2021-01-01', 'PHP', '0', '0', '1');
INSERT INTO `boke` VALUES ('12', 'linux下如何查看php-fpm是否安装', 'https://img.php.cn/upload/article/000/000/024/60532042dd48f908.jpg', 'linux下查看php-fpm是否安装的方法:打开终端,执行“whereis php-fpm”或者“find / -name php-fpm”命令,如果成功输出php-fpm的安装位置,则表示有安装。', '2021-01-01', 'PHP', '0', '0', '1');
INSERT INTO `boke` VALUES ('13', 'php的数据库修改语句是什么', 'https://img.php.cn/upload/article/202103/18/2021031817353472746.jpg', 'php的数据库修改语句是UPDATE,用于更新数据库表中已存在的记录,语法为【UPDATE table_name SET column1=value, column2=value2,...WHERE some_column=some 】。', '2021-01-01', 'PHP', '0', '0', '1');
INSERT INTO `boke` VALUES ('14', 'php怎么设置状态码', 'https://img.php.cn/upload/article/000/000/024/60531da39e7a2975.jpg', '在php中,可以使用http_response_code()函数来设置状态码,该函数用于设置响应的HTTP状态码,语法格式“http_response_code (状态码) ”。', '2021-01-01', 'PHP', '0', '0', '1');
INSERT INTO `boke` VALUES ('15', 'excel怎么冻结选定区域', 'https://img.php.cn/upload/article/202103/18/2021031817270344979.jpg', 'excel冻结选定区域的方法:首先选定你想固定不变的位置;然后点击表格最上面的菜单栏“视图”那里,再点击“冻结窗格”下方的“冻结窗格”即可。', '2021-01-01', 'PHP', '0', '0', '1');
2、查询语句
查询单个数据使用find
方法:
// table方法必须指定完整的数据表名
Db::table('think_user')->where('id', 1)->find();
最终生成的SQL语句可能是:
SELECT * FROM `think_user` WHERE `id` = 1 LIMIT 1
find
方法查询结果不存在,返回null
,否则返回结果数组
查询多个数据(数据集)使用select
方法:
Db::table('think_user')->where('status', 1)->select();
最终生成的SQL语句可能是:
SELECT * FROM `think_user` WHERE `status` = 1
select
方法查询结果是一个数据集对象,如果需要转换为数组可以使用
查询某个字段的值可以用
// 返回某个字段的值
Db::table('think_user')->where('id', 1)->value('name');
value 方法查询结果不存在,返回 null
查询某一列的值可以用
// 返回数组
Db::table('think_user')->where('status',1)->column('name');
// 指定id字段的值作为索引
Db::table('think_user')->where('status',1)->column('name', 'id');
如果要返回完整数据,并且添加一个索引值的话,可以使用
// 指定id字段的值作为索引 返回所有数据
Db::table('think_user')->where('status',1)->column('*','id');
column
方法查询结果不存在,返回空数组
举例演示:
find
方法查询单条数据,结果返回一维数组,数据不存在,返回null
<?php
namespace app\controller;
use think\facade\Db;
class Index
{
public function index()
{
// 查询第五行内容
$find = Db::table('boke')->find(1);
echo "<pre>";
print_r($find);
}
}
?>
select
方法查询多条数据,结果返回对象,数据不存在,返回空对象
<?php
namespace app\controller;
use think\facade\Db;
class Index
{
public function index()
{
$select = Db::table('boke')->select();
echo "<pre>";
print_r($select);
}
}
?>
value
查询某个字段的值,结果返回文本,数据不存在,返回null
public function index(){
// 查询id为6的文章标题,不加条件默认返回第一条
$value = Db::table('boke')->where(['id'=>6])->value('title');
print_r($value);
}
column
查询某一列的值,结果返回一维数组,数据不存在,返回空数组
public function index(){
echo "<pre>";
// 默认返回索引数组
$column = Db::table('boke')->column('title');
print_r($column);
// 指定键值 返回关联数组
// 注意:指定的键名不能重复,否则只返回第一条
$column = Db::table('boke')->column('title','id');
print_r($column);
// *还代替字段名称返回所有字段
$column = Db::table('boke')->column('*','id');
print_r($column);
}
3、添加语句
insert
1、添加一条数据,成功返回条数
public function index(){
$data = [
'title'=>'在线考试系统实战【公益直播】',
'img'=>'https://img.php.cn/upload/course/000/000/001/60862c6ba99af257.png',
'content'=>'三天大型公益直播课《模仿驾校考试系统实战开发》,使用框架: bootstrap、jquery、ThinkPHP6.0',
'date'=>'2021-05-06',
'cat'=>'PHP'
];
$insert = Db::table('boke')->insert($data);
print_r($insert);
}
insertGetId
添加一条数据,成功返回自增主键
public function index(){
$data = [
'title'=>'新版APP全新上线,打造最佳学习体验',
'img'=>'https://img.php.cn/upload/article/000/000/003/6093abebf1766794.jpg',
'content'=>'程序员梦开始的地方,支持视频课程、直播课堂、手册等学习功能',
'date'=>'2021-05-08',
'cat'=>'APP'
];
$insert = Db::table('boke')->insertGetId($data);
print_r($insert);
}
insertAll
添加多条数据,成功返回条数
public function index(){
$data = [
[
'title'=>'在线报名系统(移动端)实战【公益直播】',
'img'=>'https://img.php.cn/upload/course/000/000/001/6072932baeb4e177.png',
'content'=>'大型公益课,2021.4.12号晚上20:00开始,连续5晚,全程直播,一起开发一个中小学兴趣班报名系统!',
'date'=>'2021-04-23',
'cat'=>'PHP'
],
[
'title'=>'Vue.js开发基础',
'img'=>'https://img.php.cn/upload/course/000/000/015/6077fb8677ac6448.png',
'content'=>'Vue.js是非常流行的一个前端开发框架,采用渐进式底层向上开发模式,使用了主流的MVVM设计框架。本课以Vue.js开发的核心理念与常用技术为背景,让您在最短的时间内理解并掌握Vue.js框架的核心知识,为进一步深造打下良好的基础。',
'date'=>'2021-04-28',
'cat'=>'JS'
]
];
$insert = Db::table('boke')->insertAll($data);
print_r($insert);
}
4、修改语句
更多使用:https://www.kancloud.cn/manual/thinkphp6_0/1037535
update
修改数据,成功返回条数
public function index(){
$data = ['title'=>'修改后的标题'];
$update = Db::table('boke')->where('id',1)->update($data);
print_r($update);
}
inc
自增字段的值
public function index(){
# 字段的值增加1
$inc = Db::table('boke')->where('id',5)->inc('num')->update();
print_r($inc);
# 字段的值增加5
$inc = Db::table('boke')->where('id',6)->inc('num',5)->update();
print_r($inc);
}
dec
自减字段的值
public function index(){
# 字段的值减去1
$dec = Db::table('boke')->where('id',7)->dec('num')->update();
print_r($dec);
# 字段的值减去5
$dec = Db::table('boke')->where('id',8)->dec('num',5)->update();
print_r($dec);
}
5、删除语句
// 根据主键删除
Db::table('think_user')->delete(1);
Db::table('think_user')->delete([1,2,3]);
// 条件删除
Db::table('think_user')->where('id',1)->delete();
Db::table('think_user')->where('id','<',10)->delete();
最终生成的SQL语句可能是:
DELETE FROM `think_user` WHERE `id` = 1
DELETE FROM `think_user` WHERE `id` IN (1,2,3)
DELETE FROM `think_user` WHERE `id` = 1
DELETE FROM `think_user` WHERE `id` < 10
delete
方法返回影响数据的条数,没有删除返回 0
如果不带任何条件调用delete
方法会提示错误,如果你确实需要删除所有数据,可以使用
// 无条件删除所有数据
Db::name('user')->delete(true);
最终生成的SQL语句是(删除了表的所有数据):
DELETE FROM `think_user`
一般情况下,业务数据不建议真实删除数据,系统提供了软删除机制(模型中使用软删除更为方便)。
// 软删除数据 使用delete_time字段标记删除
Db::name('user')
->where('id', 1)
->useSoftDelete('delete_time',time())
->delete();
实际生成的SQL语句可能如下(执行的是UPDATE
操作):
UPDATE `think_user` SET `delete_time` = '1515745214' WHERE `id` = 1
useSoftDelete
方法表示使用软删除,并且指定软删除字段为delete_time
,写入数据为当前的时间戳。
delete
删除数据,成功返回条数,没有删除返回 0
public function index(){
# 根据条件删除数据
$delete = Db::table('boke')->where('id',1)->delete();
print_r($delete);
# 删除主键为2的数据
$delete = Db::table('boke')->delete(2);
print_r($delete);
# 删除整表数据
$delete = Db::table('boke')->delete(true);
print_r($delete);
}
useSoftDelete
软删除,不建议真实删除数据,TP 系统提供了软删除机制
public function index(){
# 软删除
$delete = Db::table('boke')->useSoftDelete('status',9)->delete();
print_r($delete);
}
6.总结
Db::table('表面')
// 查询语句
find() 单条查询
select() 查询全部
value() 查询某字段的值
column() 查询某列字段
// 添加语句
insert() 添加单条数据 返回条数
insertGetId() 添加单条数据 返回主键
insertAll() 添加多条数据 返回条数
// 修改语句
update(array)
inc() 某字段的值+1
dec() 某字段的值-1
// 删除语句
delete() 删除数据
useSoftDelete('static',0) 软删除 相当于修改static的值
// 删除和修改语句都必须在前面进行where条件限定,否者tp的保护机制是禁止操作全部数据的。
// 条件语句
// 注意:条件操作语句必须在增删改查语句的前面,不能放置在最后
https://www.kancloud.cn/manual/thinkphp6_0/1037538
八、实战案例
1、获取数据
namespace app\controller;
use app\BaseController;
use think\facade\Db;
use think\facade\View;
class Index extends BaseController
{
public function index()
{
$select = Db::table('boke')->select();
View::assign([
'select' => $select
]);
return View::fetch('index');
}
}
2、前后端交互
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
{foreach($select as $select_v)}
<div id="content" role="main">
<article>
<header class="entry-header">
<h1 class="entry-title">
<a href="/details.html" title="构建Nginx和PHP镜像" rel="bookmark">{$select_v['title']}</a>
</h1>
</header>
<div class="entry-content">{$select_v['title']}</div>
<footer class="entry-meta">
发布于
<a href="/index.html?time=2020-10-02" title="2020-10-02" rel="bookmark">
<time class="entry-date" datetime="2020-10-02">{$select_v['date']}</time>
</a>
属于<a href="/index.html?cate=4" title="查看 Linux中的全部文章" rel="category">{$select_v['cat']}</a>分类
</footer>
</article>
</div>
{/foreach}
</body>
</html>
rint_r($delete);
}
------
#### 6.总结
```php
Db::table('表面')
// 查询语句
find() 单条查询
select() 查询全部
value() 查询某字段的值
column() 查询某列字段
// 添加语句
insert() 添加单条数据 返回条数
insertGetId() 添加单条数据 返回主键
insertAll() 添加多条数据 返回条数
// 修改语句
update(array)
inc() 某字段的值+1
dec() 某字段的值-1
// 删除语句
delete() 删除数据
useSoftDelete('static',0) 软删除 相当于修改static的值
// 删除和修改语句都必须在前面进行where条件限定,否者tp的保护机制是禁止操作全部数据的。
// 条件语句
// 注意:条件操作语句必须在增删改查语句的前面,不能放置在最后
https://www.kancloud.cn/manual/thinkphp6_0/1037538
八、实战案例
1、获取数据
namespace app\controller;
use app\BaseController;
use think\facade\Db;
use think\facade\View;
class Index extends BaseController
{
public function index()
{
$select = Db::table('boke')->select();
View::assign([
'select' => $select
]);
return View::fetch('index');
}
}
2、前后端交互
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
{foreach($select as $select_v)}
<div id="content" role="main">
<article>
<header class="entry-header">
<h1 class="entry-title">
<a href="/details.html" title="构建Nginx和PHP镜像" rel="bookmark">{$select_v['title']}</a>
</h1>
</header>
<div class="entry-content">{$select_v['title']}</div>
<footer class="entry-meta">
发布于
<a href="/index.html?time=2020-10-02" title="2020-10-02" rel="bookmark">
<time class="entry-date" datetime="2020-10-02">{$select_v['date']}</time>
</a>
属于<a href="/index.html?cate=4" title="查看 Linux中的全部文章" rel="category">{$select_v['cat']}</a>分类
</footer>
</article>
</div>
{/foreach}
</body>
</html>