Pull to refresh

Comments 47

Можно я ещё покритикую?
Лучше сделать ваши экшны user_edit, user_delete и т.п. не строчками, а дефайнами.
Это позволит уже на этапе компиляции видеть ошибки синтаксиса. И позволит избежать долгой отладки для ошибок набора вроде user_edlt и т.п.
А чтобы еще красивее было, можно методами через __call — $user->checkUserEdit(), $user->chickUserDelete(). Правда, чуть медленее будет работать, думаю, чем просто передача строк
Вы предлагаете отлавливать ошибки на этапе исполнения, а не компиляции как предлагаю я.
Что в этом случае — зло.
А еще лучше константами какого-нибудь подходящего класса.
Вот в этой статье есть очень интересный взгляд на систему прав, там, в частности, ваш подход критикуется: php.russofile.ru/ru/translate/rights/phpgacl/
phpgacl штука все-таки более масштабная, не всегда это нужно.
Когда вам оно станет нужно — вы замучаетесь переделывать. Я придерживаюсь мнения, что лучше сразу думать о будущем. Что до конкретно гакла — да — он немного сложен, но всегда можно написать самому по проще, но подход в гакле более интересный.
Иерархичные группы для человека, бесспорно, самое удобное представление. Когда система/сервис развивается, рано или поздно придется к ней прийти. Тут я вас поддерживаю. Но требуются значительные накладные расходы. Становится весьма трудоемко (для процессора) определить права пользователя на объект: надо проверить соответствующие группы, исправить конфликты (определить какие права были выданы позже), проверить исключения.

Я как раз сейчас (не не прямо сейчас, а в ближайшие дни) думаю перейти к такой иерархичной системе. Назрело. Но я рад что не стал применять ее с самого начала, иначе бы просто закопался. А так система работает и у меня есть время сделать рефакторинг.
Подход чем-то похож на <a href=«en.wikipedia.org/wiki/Radix_tree»"">RADIX_TREE
Может автор статьи попробует написать класс для высоконагурженых систем, в которых битовые матрицы не совсем применимы (например системы с >1 миллиона юзеров)
А по вашему phpGacl не класс? :-) Он очень быстро работает и я думаю что с высокими нагрузками справится — там довольно быстрые выборки ну и + кэширование
Ну если уж человек взялся за оптимизацию, почему бы её до конца не довести? Тем более он хорошо всё объясняет =)

ПС. В любом случае вам + к карме, ибо ссылка реально полезная
Вы недочитали до конца… Во втором примере с serialize какраз рассматривается этот способ.
В общем сериализация, по моему мнению, не самое лучшее решение.Да, это будет работать быстро, но в плане поддержки это будет не очень удобно. Когда вам надо будет что-то поменять, или например, сделать выборку из базы всех людей, с определенными права только для одного объекта, придется чуток парится. Если вам надо будет это выводить на странице — это будет очень тяжелым запросом.
Прочитайте прошлую статью. С этого всё начиналось.
Релизация с битами требует конкретного определения разрешено/запрещено, что исключает возможность наследования прав при древовидной структуре групп юзеров, как у Zend_Acl.
По хорошему, все property класса долдны быть не public, ибо нарушает инкапсуляцию.
>> Для любителей более человечных названий групп, ничего не потребуется для того, чтобы все GroupID сменить с int на string.

на фиг. просто делается таблица справочник GroupID, Name, Description.
Метод мне не нравится по двум причинам:
1. Невозможность использования пользователя в нескольки групах. Покольку имхо, у политик прав должно быть 3 значения; разрешено, не разрешено, и установлено. Ну и приоритет запрета больше чем разрешения, например нам нужно сделать пользователя админом. Тоесть по умолчанию он есть в групе пользователи, где доступ к админке не определен (а по приоритету получается запрещен), просто добавляем пользователя в групу администраторы где доступ к админке явно разрешен, тоесть установлен, это имеет больший приоритет чем не установленое значение. Ну вобщем раздача прав пользователя сводится добавления его в групы и выкидыванием его из них. Если например есть три части сайта к которым нужны права доступа, то создается 3 групы в каждой разрешено только доступ к одной части, и можем легко давать пользователю доступ в любые части, простым присоидинением его в групу ту или другую или несколько. А если например есть та часть сайта при доступе к которой мы обязательно хотим запретить доступ к другим, то устанавливанием правила запрещено на групу, при любых других групах доступ он не получит. Тоесть получается такое унаследование. Что в вашем методе сделать нельзя. Тоесть у вас фактически нужно задавать права разрешения и запрета. А не просто разрешить то что можно. Все остальное и так запрещено по дефолту.
2. Расширение, например если добавился еще один метод. Тоесть к каждому полю с правами нужно добавлять еще по биту, а если после чего-то отказались в процесе модернизации сайта, то бит уже не удалишь так просто из середины. Он останется, в результате у вас будет куча ненужного мусора в базе.
1. Просто тут система будет работать по другому. Если вы хотите локализовать доступ, то устанавливайте в этом локальном участке новую группу. Ну а администратор — просто обязан видеть всё вне зависимости от запретов и групп в которых он состоит.
2. Вы не дочитали статью до конца. Во втором случае расписывается, как отказаться от битов.
1. Администратор был как пример. МОжет быть любая другая група которая дает доступ к некоторым разделам.
2. Перечитаю сейчас еще раз
Предложите свой вариант :)
Да вот смотря на количество статтей, думаю свою написать =) Только со временем не очень =(
Будет интерестно почитать. Надеюсь, у вас появится время и желание реализовать статью. :)
по моему 1-й способ нарушает принцип нормализации бд… хотя может я не внимательно прочел…
Второй способ нарушает точно. И ничего страшного в этом нет. Нормализация — это хорошо, но необходимо в первую очередь думать, как и где оно будет использоваться :).
Я лично сначала строю нормализованные таблицы, а затем уже от общего перехожу к частному — денормализую таблицы и произвожу рефакторинг объектов. Это часть оптимизации.
тогда при дальнейшей работе возникнут проблемы, например при выборке всех админов, или выборке всех элементов на кот. пользователь имеет права, в общем при любой выборке будут проблемы. А заказчик рано или поздно захочет написать какой то фильтр/сортировку на права. Идея интересная, но применять её чревато проблемами при дальнейшей поддержке.
Эти проблеммы решаются, например дополнительной таблицей прав, к которой доступ идёт только в случае, когда необходим фильтр пользователей по правам.
Скорость основного приложения не замедлит (выборки новостей), единственное что необходимо будет следить за правами в объекте и таблицей прав отдельно при внесении изменений.

То есть будет существовать для каждого объекта (в нашем случае пользователя) «прокешированные» (в serialize виде) права и нормализованные права в отдельной БД.
Вообще, в данной статье, я не могу разбирать каждый нюанс — вы это сами понимаете. И время у меня не резиновое — писать столько кода. И статья разрастётся очень сильно. Причём метод решение проблемы с поиском и фильтрацией прав я рассмотрел в первой статье.

Эти две статьи просто обучающие, в которых я рассматриваю несколько подходов к решению данной проблемы. Я здесь не рассматриваю «самый универсальный» подход, который быстрее всех и решает сразу все проблемы работы с правами. Если-бы такой существовал, я уверен, мы бы уже знали о нём и пользовались везде.

У любого подхода есть свои плюсы и минусы — использование зависит от поставленных задач.
в любом случае респект за оригинальную идею
Интереснее было бы покопать по интеграции веб-сайта с политиками SELinux.
Хотя, конечно, это достаточно нишевое решение. Как-нибудь надо заняться.
Ивините, но, чтобы не наступали другие на такие большие грабли скажу так:
Как говорят студенты кубинцы — это пиздьеза.

Не заморачивайтесь на битовых самках.
Доступ групп и юзеров к обьектам, и к модулям можно сделать гораздо легче. Причем без битовых масок.
Я тоже вначале пошел вашим путем. Буквально 2 месяца назад — понял как я заблуждался. Все можно было сделать проще и «юзабилити» с точки зрения как разработчика так и пользователя.
Теперь переделываю.
сорри — опечатка читать вместо «самках» — масках :))))
Вы недочитали до конца… Во втором примере с serialize какраз рассматривается этот способ.
Можете пояснить зачем нужно наличие двух полей Allow и Disallow?
Почему не сделать на одном поле Allow и соответственно всё, что не разрешено (стоит там в 0) пользователю запретить?
Возможно будет наследование прав доступа от родительского обьекта, но если честно статью не читал просто глазами пробежал! Понравиласькартинка в заголовке!
vit1251 абсолютно прав.
На ваш вопрос ответ в первой части статьи.
Мммм, не видимо мне сложно отойти от своих стереотипов =(
Как только думаю о битовых масках доступа, сразу вспоминаю # chmod, и никак не могу увязать это с двумя полями… пошёл ещё раз перечитывать…
Если уж говорить о том, как оптимизируют работу сайта с большой посещаемостью, то промежуточные и конечные результаты сложных расчетов (в вашем случае — конечный результат выборки прав доступа) хранят в memcached, а не в базе. Снижение нагрузки на сервер от наплыва пользователей заключается в том, чтобы как можно меньше общаться с СУБД.
Вы абсолютно правы. Об этом напишу, когда предоставлю готовую реализацию в следующей статье.
Все не плохо но ресурс растет, вы уперлись в производительность сервера, нужно добавлять машины, у вас 2 выхода простой репликация и горизонтальное портирование как натянуть вашу модель...?
Что-то я не уловил, в чём сложность, особенно используя репликацию?
а вот ранним морозним утром до вас допёрло, что чтобы заработали индексы в бд на битовых полях надо просто охренеть что сделать…
Что-то я совсем вас не понял.
Sign up to leave a comment.

Articles