本次修复解决了 casbin/webman-permission 在使用 think-orm 4.0+ 时出现的 WeakMap 兼容性问题。
- ✅
src/Model/RuleModel.php- 调整构造函数调用顺序
- ✅
tests/ThinkOrm4CompatibilityTest.php- think-orm 4.0 兼容性测试
think-orm 4.0 引入 WeakMap 机制存储模型数据,要求:
- 必须先调用
parent::__construct()初始化 WeakMap - 再通过
__set()设置属性
原代码在调用父类构造前设置属性,导致访问未初始化的 WeakMap。
// 修改前(错误)
public function __construct(array $data = [], ?string $driver = null)
{
$this->driver = $driver;
$this->connection = ...; // 触发 __set(),WeakMap 未初始化
parent::__construct($data);
}
// 修改后(正确)
public function __construct(array $data = [], ?string $driver = null)
{
$this->driver = $driver;
parent::__construct($data); // 先初始化 WeakMap
$this->connection = ...; // 再设置属性
}- ✅ think-orm 2.0.53+
- ✅ think-orm 3.x
- ✅ think-orm 4.0.30+
- PHP 8.3
- webman 2.2.0
- think-orm 4.0.51
- casbin/casbin 4.0.6
php vendor/bin/phpunit tests/ThinkOrm4CompatibilityTest.phpuse Casbin\WebmanPermission\Permission;
// 测试实例化
$model = new \Casbin\WebmanPermission\Model\RuleModel();
// 测试权限操作
Permission::addPermissionForUser('user-1', '/api/test', 'GET');
$permissions = Permission::getImplicitPermissionsForUser('user-1');- 使用 think-orm 4.0+ 的项目
- 调用任何需要实例化 RuleModel 的方法
- 所有权限查询、添加、删除操作
- 使用 think-orm 2.x/3.x 的项目(向后兼容)
- 使用 Laravel 数据库适配器的项目
- think-orm#814 - 类似问题报告
- 多个用户在 ThinkPHP 8 + Casbin 项目中遇到相同问题
- 发布新版本(v2.4.0)包含此修复
- 在 GitHub Release 中说明 think-orm 4.0 兼容性
- 更新 Packagist 文档