Вы можете иметь карту (кэшированную в memcache или в файле или в другой таблице) из directory_id и список parent_directory_id его родителей, поэтому для этой структуры:
1
┣━━━2
┃ ┗━━━4
┃ ┗━━━5
┗━━━3
Ваша карта будет выглядеть так:
$parents_map = [
1 => [],
2 => [1],
3 => [1],
4 => [2, 1],
5 => [4, 2, 1],
];
Всякий раз, когда вы добавляете новый дочерний каталог, ищите parent_map его родителя и добавляйте его на карту:
// new directory 6 whose parent is 3:
$new_id = 6;
$parent_id = 3;
$parents_map[$new_id] = array_merge([$parent_id], $parents_map[$parent_id]);
Затем, когда вам нужно проверить разрешения для каталога, найдите его на карте и посмотрите, есть ли у кого-либо из его родителей разрешение.
$directory_id = 6;
foreach($parents_map[$directory_id] as $parent_id) {
check_permissions($user_id, $parent_id);
}