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

## Постоянное хранение данных 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()`). Это нужно для предоставления контекста классу утверждения и определения его условий там, где это нужно.