Php ORM中的表连接
我正在尝试用Kohana编写自己的RBAC模块。 我不想使用现有的模块,我只是想学习 我的表是:users、roles、permission和users\u roles、roles\u permissions(因为usersroles和rolespermission之间存在多对多关系) 我的用户模型:Php ORM中的表连接,php,mysql,orm,kohana,Php,Mysql,Orm,Kohana,我正在尝试用Kohana编写自己的RBAC模块。 我不想使用现有的模块,我只是想学习 我的表是:users、roles、permission和users\u roles、roles\u permissions(因为usersroles和rolespermission之间存在多对多关系) 我的用户模型: class Model_User extends ORM { protected $_primary_key = 'user_id'; protected $_has_many
class Model_User extends ORM {
protected $_primary_key = 'user_id';
protected $_has_many = array(
'roles' => array(
'model' => 'role',
'through' => 'users_roles',
),
);
}
我的榜样:
class Model_Role extends ORM {
protected $_primary_key = 'role_id';
protected $_has_many = array(
'users' => array(
'model' => 'user',
'through' => 'users_roles',
),
'permissions' => array(
'model' => 'permission',
'through' => 'roles_permissions',
),
);
}
和我的权限模型:
class Model_Permission extends ORM {
protected $_primary_key = 'permission_id';
protected $_has_many = array(
'roles' => array(
'model' => 'role',
'through' => 'roles_permissions',
),
);
}
我创建用户:
$user = ORM::factory('user');
$user->username = 'johndoe';
$user->email = 'john@doe.com';
//etc
$user.save();
我创建角色:
$author = ORM::factory('role');
$author->name = 'author';
$author->save();
我创建权限:
$read = ORM::factory('permission');
$read->name = 'read';
$read->description = 'can read posts';
$read->save();
$write = ORM::factory('permission');
$write->name = 'write';
$write->description = 'can write posts';
$write->save();
我向用户添加角色:
$user->add('roles', $author);
我向角色添加权限:
$author->add('permissions', $read);
$author->add('permissions', $write);
一切正常
但是,我的问题是如何检查用户是否有给定的权限:在这种情况下,如何检查johndoe是否有写文章的权限
谢谢你的帮助 我在一个查询中找到了一个解决方案:
$count = ORM::factory('permission')
->join('roles_permissions')
->on('permission.permission_id', '=', 'roles_permissions.permission_id')
->join('roles')
->on('roles.role_id', '=', 'roles_permissions.role_id')
->join('users_roles')
->on('roles.role_id', '=', 'users_roles.role_id')
->join('users')
->on('users.user_id', '=', 'users_roles.user_id')
->on('users.user_id', '=', DB::expr($user->user_id))
->where('permission.name', '=', 'write')
->find_all()
->count();
如果$count>0
,则表示$user具有写入权限
有更简单的解决方案吗?与前面的答案相比,有一个查询,但只有两个联接
class Model_User extends ORM {
// ... some stuff here
public function has_permission($permission_name)
{
return (bool) ORM::factory('permission')
->where('permission.name', '=', $permission_name)
->join('roles_permissions')
->on('roles_permissions.permission_id', '=', 'permision.permission_id')
->join('roles_users')
->on('roles_users.role_id', '=', 'roles_permissions.role_id')
->on('roles_users.user_id', '=', DB::expr((int) $this->user_id))
->count_all();
}
}这里有一个更好的解决方案,当提供主键或模型实例时,它将执行更快的查询:
<?php
class Model_User extends ORM {
// ...
/**
* Check if a user is allowed to perform an action based on permissions
* attached to the user's roles.
*
* @param int|string|Model_Permission $permission name, primary key or instance of permission
* @return boolean TRUE if allowed; FALSE otherwise
*/
public function is_allowed_to($permission)
{
// We have a permission name
if (is_string($permission) AND ! is_numeric($permission))
return (bool) ORM::factory('permission')
->where('permission.name', '=', $permission)
->join('roles_permissions')
->on('roles_permissions.permission_id', '=', 'permission.permission_id')
->join('roles_users')
->on('roles_users.role_id', '=', 'roles_permissions.role_id')
->where('roles_users.user_id', '=', $this->pk())
->count_all();
// We can get the permission primary key
// to perform a faster query
$permission_id = ($permission instanceof Model_Permission)
? $permission->pk()
: $permission;
return (bool) DB::select(array(DB::expr('COUNT(*)'), 'records_found'))
->from('roles_permissions')
->join('roles_users')
->on('roles_users.role_id', '=', 'roles_permissions.role_id')
->where('roles_permissions.permission_id', '=', $permission_id)
->where('roles_users.user_id', '=', $this->pk())
->execute()
->get('records_found');
}
// ...
}
获取所有author权限,然后查看这些权限,并查看写入权限是否在该权限对象集中。我想检查$user是否具有写入权限,而不是$author是否具有写入权限。然后,您首先需要获取该用户的角色,然后查看这些权限是否已授予。这有什么复杂的?没错,但没有更优雅的解决方案。我不能在单个查询中执行此操作吗?您正在使用ORM。据我所知,在使用ORM提供的接口时,您不应该关心查询。当你想自己写你的ORM时,好吧,ORM做你让它做的事情。由于您不想使用现成的解决方案(这通常是高度建议的,因为ORM是一个复杂的软件),所以请使用您现有的解决方案。如果你对如何自己创建一个复杂的ORM感兴趣,有很多书详细描述了这一点。但是,正如所写的,这个主题是复杂的,所以在开始编写代码之前,应该先阅读几千页。