I'm trying to create a simple access check for my users. Basically I have an array of groups like trial
, paid
, admin
, etc defined like this:
$levels = ['trial' => [], 'enterprise' => ['admin'], 'paid' => ['trial'],
'admin' => ['paid', 'editor'], 'editor' => []];
Take a look at the paid
group. paid
group has trial
group in it's array meaning paid
group users can access trial
group too.
Similarly admin
group can access paid
, editor
and trial
group because admin
has paid
group in its array and paid
group has trial
group in its array (needs recursion I guess).
My function is like this (but I can't figure out the recursion part ):
<?php
public function hasAccess($requiredLevel, $myLevel) {
global $levels;
return (($myLevel == $requiredLevel) || (in_array($requiredLevel, $levels[$myLevel]));
}
This works when the level is directly present in array but fails to make the associations, eg when levels are connected like admin => paid => trial
How to modify this function so it can check this recursively in simplest way possible?
PS The order in which they are stored is also not fixed.
This should do it:
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;
}
I hope the comments clear it up enough for you.
I also advise you to pass $levels
in as an argument instead of using a global variable as it allows for more flexibility, and globals are generally a bad practice.
The only thing you should watch out for are circular references, where you would end up with an endless loop. To solve this, simply pass the array of already visited levels as an optional argument:
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;
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.