Spec-Zone.ru › Phalcon 2

Парсер аннотаций

Впервые компонент парсера аннотаций написан на языке C для мира PHP. Phalcon\Annotations — это компонент общего назначения, который обеспечивает удобство парсинга и кэширования аннотаций в классах PHP для использования в приложениях.

Аннотации считываются из docblocks в классах, методах и свойствах. Аннотация может быть размещена в любом месте docblock:

/**
 * This is the class description
 *
 * @AmazingClass(true)
 */
class Example
{

    /**
     * This a property with a special feature
     *
     * @SpecialFeature
     */
    protected $someProperty;

    /**
     * This is a method
     *
     * @SpecialFeature
     */
    public function someMethod()
    {
        // ...
    }

}

В приведенном выше примере мы находим некоторые аннотации в комментариях, аннотация имеет следующий синтаксис:

@ИмяАннотации[(параметр1, параметр2, ...)]

Также аннотация может быть размещена в любой части docblock:

/**
 * This a property with a special feature
 *
 * @SpecialFeature
 *
 * More comments
 *
 * @AnotherSpecialFeature(true)
 */

Парсер очень гибкий, следующий docblock является допустимым:

/**
 * This a property with a special feature @SpecialFeature({
someParameter="the value", false

 })  More comments @AnotherSpecialFeature(true) @MoreAnnotations
 **/

Однако, чтобы код был более поддерживаемым и понятным, рекомендуется размещать аннотации в конце docblock:

/**
 * This a property with a special feature
 * More comments
 *
 * @SpecialFeature({someParameter="the value", false})
 * @AnotherSpecialFeature(true)
 */

Чтение аннотаций

Рефлектор реализован для удобного получения аннотаций, определённых в классе, с помощью объектно-ориентированного интерфейса:

$reader = new \Phalcon\Annotations\Adapter\Memory();

//Reflect the annotations in the class Example
$reflector = $reader->get('Example');

//Read the annotations in the class' docblock
$annotations = $reflector->getClassAnnotations();

//Traverse the annotations
foreach ($annotations as $annotation) {

    //Print the annotation name
    echo $annotation->getName(), PHP_EOL;

    //Print the number of arguments
    echo $annotation->numberArguments(), PHP_EOL;

    //Print the arguments
    print_r($annotation->getArguments());
}

Процесс чтения аннотаций очень быстрый, однако по соображениям производительности рекомендуется хранить обработанные аннотации с помощью адаптера. Адаптеры кэшируют обработанные аннотации, избегая необходимости повторного парсинга аннотаций.

Phalcon\Annotations\Adapter\Memory был использован в приведенном выше примере. Этот адаптер кэширует аннотации только во время выполнения запроса, поэтому адаптер более подходит для разработки. Существуют другие адаптеры для замены, когда приложение находится в стадии производства.

Типы аннотаций

Аннотации могут иметь параметры или нет. Параметр может быть простым литералом (строки, числа, булевы значения, null), массивом, хэшированным списком или другой аннотацией:

/**
 * Simple Annotation
 *
 * @SomeAnnotation
 */

/**
 * Annotation with parameters
 *
 * @SomeAnnotation("hello", "world", 1, 2, 3, false, true)
 */

/**
 * Annotation with named parameters
 *
 * @SomeAnnotation(first="hello", second="world", third=1)
 * @SomeAnnotation(first: "hello", second: "world", third: 1)
 */

/**
 * Passing an array
 *
 * @SomeAnnotation([1, 2, 3, 4])
 * @SomeAnnotation({1, 2, 3, 4})
 */

/**
 * Passing a hash as parameter
 *
 * @SomeAnnotation({first=1, second=2, third=3})
 * @SomeAnnotation({'first'=1, 'second'=2, 'third'=3})
 * @SomeAnnotation({'first': 1, 'second': 2, 'third': 3})
 * @SomeAnnotation(['first': 1, 'second': 2, 'third': 3])
 */

/**
 * Nested arrays/hashes
 *
 * @SomeAnnotation({"name"="SomeName", "other"={
 *      "foo1": "bar1", "foo2": "bar2", {1, 2, 3},
 * }})
 */

/**
 * Nested Annotations
 *
 * @SomeAnnotation([email protected](1, 2, 3))
 */

Практическое применение

Далее мы объясним некоторые практические примеры использования аннотаций в приложениях PHP:

Включение кеша с помощью аннотаций

Предположим, у нас есть контроллер, и разработчик хочет создать плагин, который автоматически запускает кеш, если последняя выполненная операция помечена как кэшируемая. Прежде всего, мы регистрируем плагин в сервисе диспетчера, чтобы получать уведомления о выполнении маршрута:

$di['dispatcher'] = function() {

    $eventsManager = new \Phalcon\Events\Manager();

    //Attach the plugin to 'dispatch' events
    $eventsManager->attach('dispatch', new CacheEnablerPlugin());

    $dispatcher = new \Phalcon\Mvc\Dispatcher();
    $dispatcher->setEventsManager($eventsManager);
    return $dispatcher;
};

CacheEnablerPlugin — это плагин, который перехватывает каждую операцию, выполняемую в диспетчере, включая кеш при необходимости:

/**
 * Enables the cache for a view if the latest
 * executed action has the annotation @Cache
 */
class CacheEnablerPlugin extends \Phalcon\Mvc\User\Plugin
{

    /**
     * This event is executed before every route is executed in the dispatcher
     *
     */
    public function beforeExecuteRoute($event, $dispatcher)
    {

        //Parse the annotations in the method currently executed
        $annotations = $this->annotations->getMethod(
            $dispatcher->getActiveController(),
            $dispatcher->getActiveMethod()
        );

        //Check if the method has an annotation 'Cache'
        if ($annotations->has('Cache')) {

            //The method has the annotation 'Cache'
            $annotation = $annotations->get('Cache');

            //Get the lifetime
            $lifetime = $annotation->getNamedParameter('lifetime');

            $options = array('lifetime' => $lifetime);

            //Check if there is an user defined cache key
            if ($annotation->hasNamedParameter('key')) {
                $options['key'] = $annotation->getNamedParameter('key');
            }

            //Enable the cache for the current method
            $this->view->cache($options);
        }

    }

}

Теперь мы можем использовать аннотацию в контроллере:

class NewsController extends \Phalcon\Mvc\Controller
{

    public function indexAction()
    {

    }

    /**
     * This is a comment
     *
     * @Cache(lifetime=86400)
     */
    public function showAllAction()
    {
        $this->view->article = Articles::find();
    }

    /**
     * This is a comment
     *
     * @Cache(key="my-key", lifetime=86400)
     */
    public function showAction($slug)
    {
        $this->view->article = Articles::findFirstByTitle($slug);
    }

}

Выбор шаблона для отображения

В этом примере мы будем использовать аннотации, чтобы указать Phalcon\Mvc\View\Simple, какой шаблон должен быть отображён после выполнения операции:

Адаптеры аннотаций

Этот компонент использует адаптеры для кэширования или не кэширования обработанных аннотаций, тем самым улучшая производительность или обеспечивая удобства для разработки/тестирования:

Имя Описание API
Память Аннотации кэшируются только в памяти. По окончании запроса кэш очищается, загружая аннотации заново в каждом запросе. Этот адаптер подходит для стадии разработки Phalcon\Annotations\Adapter\Memory
Файлы Обработанные аннотации хранятся постоянно в файлах PHP, улучшая производительность. Этот адаптер должен использоваться вместе с кэшем байткода. Phalcon\Annotations\Adapter\Files
APC Обработанные аннотации постоянно хранятся в кэше APC, улучшая производительность. Это самый быстрый адаптер Phalcon\Annotations\Adapter\Apc
XCache Обработанные аннотации постоянно хранятся в кэше XCache, улучшая производительность. Это тоже быстрый адаптер Phalcon\Annotations\Adapter\Xcache

Реализация собственных адаптеров

Интерфейс Phalcon\Annotations\AdapterInterface должен быть реализован для создания собственных адаптеров аннотаций или расширения существующих.

Внешние ресурсы

  • Учебник: Создание пользовательского инициализатора моделей с помощью аннотаций

© 2011–2016 Phalcon Framework Team
Licensed under the Creative Commons Attribution License 3.0.
https://docs.phalconphp.com/en/2.0.0/reference/annotations.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API