# Расширенное использование

## Постоянное хранение данных ACL

Zend_Acl спроектирован таким образом, что не требует для хранения данных ACL использования строго определенных технологий хранения - таких, как база данных или сервер кеша. Его реализация на чистом PHP позволяет создавать административные инструменты под управлением Zend_Acl с относительной простотой и гибкостью. Многие ситуации требуют некоторой интерактивной поддержки от ACL, и Zend_Acl предоставляет методы для настройки, произведения запросов, контроля доступа приложением.

Тем не менее, хранение данных ACL остается задачей разработчика, т.к. случаи использования могут сильно варьироваться в различных ситуациях. Поскольку Zend_Acl доступен для сериализации, то можно сериализовать объекты ACL через PHP-функцию serialize(), и результаты можно хранить там, где пожелает разработчик - например, в файле, базе данных или с помощью механизма кэширования.

## Написание условных правил ACL с утверждениями

Иногда правило разрешения или запрета доступа роли к ресурсу должно быть не безусловным, а зависеть от различных критериев. Например, определенный доступ должен быть разрешен, но только с 8:00 до 17:00. Другой пример - доступ должен быть запрещен, если запрос поступил с IP-адреса, находящегося в "черном списке". Zend_Acl имеет встроеную поддержку для применения правил, основанных на любых нужных разработчику условиях.

Zend_Acl предоставляет поддержку условных правил с помощью интерфейса Zend_Acl_Assert_Interface. Чтобы использовать интерфейс утверждений, разработчик должен написать класс, который реализует метод assert() интерфейса:

    class CleanIPAssertion implements Zend_Acl_Assert_Interface
    {
        public function assert(Zend_Acl $acl,
                               Zend_Acl_Role_Interface $role = null,
                               Zend_Acl_Resource_Interface $resource = null,
                               $privilege = null)
        {
            return $this->_isCleanIP($_SERVER['REMOTE_ADDR']);
        }

        protected function _isCleanIP($ip)
        {
            // ...
        }
    }

После объявления класса утверждения разработчик должен передавать экземпляр этого класса при определении условных правил. Правило, которое создается с утверждением, применяется только тогда, когда метод утверждения возвращает `TRUE`.

    $acl = new Zend_Acl();
    $acl->allow(null, null, null, new CleanIPAssertion());

Код выше создает условное правило, разрешающее всем доступ ко всем привилегиям всех ресурсов, за исключением случаев, когда IP-адрес запрашивающего занесен в "черный список". Если запрос приходит с IP-адреса, который не определяется как "белый", то правило не применяется. Поскольку правило применяется ко всем ролям, всем ресурсам и всем привилегиям, то "черный" IP приведет к запрещению доступа. Тем не менее, это особый случай, и следует понимать, что во всех других случаях (например, когда для правила были указаны роль, ресурс, или привилегия), невыполнение утверждения приводит к тому, что правило не применяется, и для определения того, разрешить ли доступ или запретить, могут использоваться другие правила.

Методу assert() объекта утверждения передаются ACL, роль, ресурс и привилегия, к которым применяется запрос на авторизацию (например, isAllowed()). Это нужно для предоставления контекста классу утверждения и определения его условий там, где это нужно.