我正在尝试为我的用户创建一个简单的访问检查。基本上,我有一个像trial
、paid
、admin
等组的数组,定义如下:
$levels = ['trial' => [], 'enterprise' => ['admin'], 'paid' => ['trial'],
'admin' => ['paid', 'editor'], 'editor' => []];
看看paid
组。paid
组的数组中有trial
组,这意味着paid
组用户也可以访问trial
组。
类似地,admin
组可以访问paid
、editor
和trial
组,因为admin
的数组中有paid
组,而paid
的数组中也有trial
组(我想需要递归)。
我的函数是这样的(但我无法计算递归部分):
<?php
public function hasAccess($requiredLevel, $myLevel) {
global $levels;
return (($myLevel == $requiredLevel) || (in_array($requiredLevel, $levels[$myLevel]));
}
当级别直接存在于阵列中但无法进行关联时,例如,当级别像admin => paid => trial
一样连接时,这会起作用
如何修改此函数,使其能够以最简单的方式递归检查
附言:它们的存储顺序也不是固定的。
这应该做到:
public function hasAccess($requiredLevel, $levels, $myLevel) {
// Check if $myLevel matches $requiredLevel
if ($requiredLevel === $myLevel) {
return true;
}
// Iterate through all levels under $myLevel
foreach ($levels[$myLevel] as $level) {
// If any of those levels has access, return true
if ($this->hasAccess($requiredLevel, $levels, $level)) {
return true;
}
}
return false;
}
我希望这些评论对你来说足够清楚。
我还建议您将$levels
作为参数传入,而不是使用全局变量,因为它允许更大的灵活性,而全局变量通常是一种糟糕的做法。
你唯一应该注意的是循环引用,在那里你会得到一个无休止的循环。要解决此问题,只需将已访问级别的数组作为可选参数:
public function hasAccess($requiredLevel, $levels, $myLevel, $visited = []) {
// Check if $myLevel matches $requiredLevel
if ($requiredLevel === $myLevel) {
return true;
}
// Add the current level to the visited array
$visited[] = $myLevel;
// Iterate through all levels under $myLevel
foreach ($levels[$myLevel] as $level) {
// Return true if any of those levels has access,
// and hasn't been visited before
if (
!in_array($level, $visited) &&
$this->hasAccess($requiredLevel, $levels, $level, $visited)
) {
return true;
}
}
return false;
}