Я работаю над функцией, которая принимает ряд строк разрешений, менее 255 символов и присваивает их сущности. Каждая назначенная строка уникальна, но их так много, что они отбрасывают их в массив, сериализуют их и вставляют в базу данных, вытаскивая их позже и де-сериализуя их или пересчитывая из запроса каждый раз, когда нагрузка вызывает задержку проблемы. Особенно с унаследованными разрешениями.
Поэтому я подумывал взять строку, создав из нее маску, затем OR'ing в glob разрешения. По мере добавления дополнительных разрешений продолжайте их ИЛИ в glob. Затем, когда вам нужно проверить разрешение и строку против glob.
Вопрос в том, как сгенерировать маску. Сначала я думал только о хэшировании строки для уникальной маски, однако это возможно, но я не знаю, насколько вероятно, что, поскольку больше значений хэша OR'ed на glob, потенциал для заполнения glob в таком путь, и И-тест с разрешением, которого у них нет, но возвращаем истинное значение.
if($glob&&$test == $test)
Другим вариантом будет просто автоматическое число строк разрешений и их маска будет 2 ^ авто-номер. Но это ограничило бы число строк разрешений примерно до 64ish.
То, что я действительно хочу, это глобус, который я могу вытащить из базы данных один раз и связать его с пользователем. Затем проверьте этот glob на строку или связанное с ней значение, представляющее набор разрешений.
Я нашел интересное решение, но я не уверен, насколько логически это правильно, потому что я не очень хорошо разбираюсь в том, как PHP обрабатывает строковые данные. Я решил все отрезать и попытаться сделать это прямо без каких-либо хэширования или назначения или чего-то еще и просто побитовые операции над строками. Казалось, это сработало, но я не уверен, что смогу доказать свою логику достаточно.
$key1 = "Access to Black Box"; $key2 = "Managing Black Box"; $key3 = "Nothing too see here"; $key3a = "Nothingg B"; $key3b = "too see"; $glob = ""; $glob = $glob | $key1; if(($glob & $key1) == $key1){echo "<p>Key one exists in glob: " . $glob;} $glob = $glob | $key2; if(($glob & $key2) == $key2){echo "<p>Key one exists in glob: " . $glob;} if(($glob & $key3) == $key3){echo "<p>Key three exists in glob: " . $glob;} else{echo "<p>Key three does not exists in glob: " . $glob;} $glob = $glob | $key3; if(($glob & $key3) == $key3){echo "<p>Key three exists in glob: " . $glob;} if(($glob & $key3a) == $key3a){echo "<p>Key three a exists in glob: " . $glob;} if(($glob & $key3b) == $key3b){echo "<p>Key three b exists in glob: " . $glob;} else{echo "<p>Key three b does not exists in glob: " . $glob;}
Выходы:
Ключ один существует в glob: доступ к Black Box Ключ два существует в glob: Mcoew {nwobnmckkbox Ключ три не существует в glob: Mcoew {nwobnmckkbox Ключ три существует в глобусе: Oomowoomsooboze Ключ три a существует в glob: Oomowoomsooboze Ключ три b не существует в glob: Oomowoomsooboze
Так что это работает, но что бы я посмотрел на столкновение мудрым? С key3a я показал, что строка, которая имеет комбинацию символов, которые соответствуют позициям с символами в других клавишах, я могу получить ложный результат. Но могу ли я обойти его со строгими правилами в строках прав? Каждый тип ресурса именован, и каждый тип ресурса имеет ограниченное количество связанных разрешений. Итак, что-то вроде «Блог …. Написать сообщение», «Блог … Опубликовать сообщение», «Блог …. Умеренный пост», «Подкаст ……. Upload», «Podcast …. … Опубликовать ", чтобы компенсировать возрастающую вероятность столкновения, поскольку длина строки мало влияет на скорость PHP.
Существенная мысль здесь заключается в следующем:
Другим вариантом будет просто автоматическое число строк разрешений и их маска будет 2 ^ авто-номер. Но это ограничило бы число строк разрешений примерно до 64ish.
Если ваши строки полномочий действительно независимы друг от друга, то, очевидно, что бы вы ни делали, вам понадобится как минимум 1 бит, чтобы сохранить, существует ли разрешение. Нет никакого способа обойти это (это 1 бит фактической, независимой информации).
Возможным решением вашей проблемы было бы кодирование разрешений компактным образом (например, назначить Int16 каждому) и сохранить список разрешений пользователя как двоичный массив всех его разрешений. Это уродливое, но это смутно решит вашу проблему. В зависимости от БД вы можете иметь какие-то типы столбцов массива / коллекции, которые могли бы сделать это для вас.
Поскольку каждая строка уникальна, почему бы не загружать их из базы данных один раз в хэш-таблицу (или аналогичную) и кэшировать их в течение всего сеанса пользователя?