1、简述
因之前用的tp5,漏洞太多,然后我尝试用tp8,然而,不管我怎么设置,我发现服务器端的session文件目录始终是空的,这意味着,session并没有自动保存,但是调试过程中也没有报错。最后查阅官方文档以及大量资料才发现,要在app/middleware.php 里面配置开启session,而不是config/middleware.php,于是,问题已成功解决!至于原因,我认为有可能是BUG。下面我就把解决过程中所有重要操作都写一下,送给有缘人。
2、区别一下config与app目录下的两个middleware.php
①、作用范围
文件 | 作用范围 | 适用场景 |
---|---|---|
config/middleware.php | 全局中间件(对所有应用生效) | 跨应用共享的中间件(如日志、跨域处理) |
app/middleware.php | 应用中间件(仅对当前应用生效) | 特定应用的中间件(如权限校验、Session) |
②、执行顺序
- 全局中间件 (
config/middleware.php
):在应用中间件之前执行,优先级更高。
// config/middleware.php(全局)
return [
\app\middleware\GlobalMiddleware::class, // 先执行
];
- 应用中间件 (
app/middleware.php
):在全局中间件之后执行,优先级较低。
// app/middleware.php(应用级)
return [
\think\middleware\SessionInit::class, // 后执行
];
③、典型配置差异
- 全局中间件示例 (
config/middleware.php
)
// 全局中间件,影响所有应用
return [
// 跨域处理中间件(所有应用生效)
\think\middleware\AllowCrossDomain::class,
// 全局请求日志中间件
\app\middleware\LogRequest::class,
];
- 应用中间件示例 (
app/middleware.php
)
// 应用中间件,仅当前应用生效
return [
// Session初始化(仅当前应用需要Session时加载)
\think\middleware\SessionInit::class,
// 用户权限校验(如Admin应用独有)
\app\admin\middleware\AuthCheck::class,
];
④、多应用模式下的差异
模式 | config/middleware.php | app/middleware.php |
---|---|---|
单应用模式 | 等同于全局中间件,所有请求强制加载 | 应用级中间件,但优先级低于全局中间件 |
多应用模式 | 对所有子应用生效(如 app/admin 、app/api ) | 仅对当前子应用生效(如 app/api 的中间件) |
3、调试技巧
如果无法判断是哪个文件生效或者要想知道文件的执行顺序,那么:
查看中间件加载顺序:在入口文件或控制器中输出中间件堆栈:
use think\facade\Middleware;
dump(Middleware::getMiddlewareStack());
验证执行顺序:在中间件的 handle
方法中添加日志:
public function handle($request, \Closure $next) {
Log::write('GlobalMiddleware executed');
return $next($request);
}
4、其它解决过程
- 官方文档指出
Session
功能默认是没有开启的,如果你需要使用Seesion
,需要在全局的中间件定义文件中加上下面的中间件定义:'think\middleware\SessionInit'
:
<?php
//单应用:app/middleware.php, 全局:config/middleware.php
// 全局中间件定义文件
return [
// 全局请求缓存
// \think\middleware\CheckRequestCache::class,
// 多语言加载
// \think\middleware\LoadLangPack::class,
// Session初始化
\think\middleware\SessionInit::class
];
- 配置config/session.php
<?php
// +----------------------------------------------------------------------
// | 会话设置
// +----------------------------------------------------------------------
return [
// session name
'name' => 'PHPSESSID',
// SESSION_ID的提交变量,解决flash上传跨域
'var_session_id' => '',
// 驱动方式 支持file cache
'type' => 'file',
// 存储连接标识 当type使用cache的时候有效
'store' => null,
// 过期时间
'expire' => 1440,
// 前缀
'prefix' => '',
// 是否自动开启 session
'auto_start' => true,
// session 保存路径
'save_path' => '/temp/thinkphp8/runtime/session',
];
- 服务器端:
php.ini 中的 session.save_path 要开启,并且与thinkphp 的session配置要一致。
session.save_path = "/temp/thinkphp8/runtime/session"
- 配置session目录的权限
//配置属组,应于apache或nginx、php的运行用户数组要一致,例如:
chown -R www:www /temp/thinkphp8/runtime/session
//配置权限
chmod -R 755 /temp/thinkphp8/runtime/session