Я пытаюсь придумать функцию, чтобы получить некоторые конкретные данные из массива. Это часть системы разрешений, которую я делаю для страницы.
Вот массив данных, который у меня есть:
[views] => Array
(
[0] => SimpleXMLElement Object
(
[permItem] => viewOriginalFeedback
[actions] => SimpleXMLElement Object
(
[view] => 0
[edit] => 0
)
)
[1] => SimpleXMLElement Object
(
[permItem] => viewTarget
[actions] => SimpleXMLElement Object
(
[view] => 0
[edit] => 0
)
)
)
)
То, что я пытаюсь сделать, это создать функцию, в которой я могу пройти, передать ей элемент perm и действие, подобное этому. if(myFunction('viewOriginalFeedback', 'view'))
если это возвращает 1, я показываю контент, если его 0, то я знаю, чтобы его не показывать.
Проблема в том, что эти views
могут вообще не существовать в массиве, поэтому в этом случае он будет false
как если бы действие было установлено на 0
.
Я играл с чем-то подобным, но я чувствую, что есть более элегантный способ его завершить.
// Permission Check
function checkPerm($permItem, $action){
foreach($permissions->data->views as $view){
if($view->permItem == $permItem){
if($view->actions == $action){
return $view->actions->$action;
}
}
}
}
Было бы проще и не требовать цикла для использования ассоциативного массива:
Array
(
[viewOriginalFeedback] => Array
(
[view] => 0
[edit] => 0
)
[viewTarget] => Array
(
[view] => 0
[edit] => 0
)
)
Тогда это просто:
if(isset($permissions[$permItem][$action])) {
return (bool)$permissions[$permItem][$action];
}
return false;
Вы можете поддерживать использование объектов и по-прежнему сохранять их простым строковым ключом:
[viewOriginalFeedback] => SimpleXMLElement Object
(
[permItem] => viewOriginalFeedback
[actions] => SimpleXMLElement Object
(
[view] => 0
[edit] => 0
)
)
С той же проверкой:
if(isset($permissions[$permItem]->actions->$action)) {
return (bool)$permissions[$permItem]->actions->$action;
}
return false;
С вашим текущим массивом объектов ваш нынешний подход, вероятно, является способом выхода, но более похожим:
foreach($permissions->data->views as $view){
if($view->permItem == $permItem){
if(isset($view->actions->$action)){
return (bool)$view->actions->$action;
} else {
return false;
}
}
}
Я просто использую array_filter, чтобы сократить код. Это предполагает, что вы не можете конвертировать в использование ассоциативного массива, например, предложенного AbraCadaver. Он также немного менее эффективен, чем ваш собственный код, потому что array_filter будет перемещаться по остальной части массива, даже после того, как он найдет первое совпадение.
function checkPerm($permItem, $action){
$val = array_filter($permissions->data->views, function($v) {
return $v->permItem === $permItem;
});
return isset($vals[0]->$action) && (bool) $vals[0]->$action;
}
if(isset($view->actions->$action))
и я бы, вероятно, пошел за ассоциативный массив вместо массива объектов.