Добавить кэширование в ZendFormAnnotationAnnotationBuilder


Поскольку я наконец нашел двоичный файл memcache для PHP 5.4.4 в Windows, я ускоряю приложение, которое в настоящее время разрабатываю.

Мне удалось установить memcache в качестве драйвера кэша сопоставления ORM доктрины, но мне нужно исправить еще одну утечку: формы, созданные с использованием аннотаций.

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

Это можно ли добавить кэширование в этот процесс? Я просмотрел код, но похоже, что Zend\Form\Annotation\AnnotationBuilder всегда создает форму, отражая код и анализируя аннотации. Заранее спасибо.

Author: Daniel M, 2012-09-11

2 answers

Возможно, вы захотите попробовать что-то вроде этого:

class ZendFormCachedController extends Zend_Controller_Action
{
    protected $_formId = 'form';

    public function indexAction()
    {
            $frontend = array(
                    'lifetime' => 7200,
                    'automatic_serialization' => true);

            $backend = array('cache_dir' => '/tmp/');
            $cache = Zend_Cache::factory('Core', 'File', $frontend, $backend);

            if ($this->getRequest()->isPost()) {
                    $form = $this->getForm(new Zend_Form);
            } else if (! $form = $cache->load($this->_formId)) {
                    $form = $this->getForm(new Zend_Form);
                    $cache->save($form->__toString(), $this->_formId);
            }

            $this->getHelper('layout')->setLayout('zend-form');
            $this->view->form = $form;
    }

Найдено здесь.

 1
Author: Louis Huppenbauer, 2012-09-11 15:34:46

Ответ Луи не сработал для меня, поэтому я просто расширил конструктор AnnotationBuilder, чтобы взять объект кэша, а затем изменил getFormSpecification, чтобы использовать этот кэш для кэширования результата. Моя функция ниже..

Очень быстрая работа...конечно, это можно было бы улучшить. В моем случае я был ограничен некоторым старым оборудованием, и это заняло время загрузки страницы от 10+ секунд до примерно 1 секунды

/**
 * Creates and returns a form specification for use with a factory
 *
 * Parses the object provided, and processes annotations for the class and
 * all properties. Information from annotations is then used to create
 * specifications for a form, its elements, and its input filter.
 *
 * MODIFIED: Now uses local cache to store parsed annotations
 *
 * @param  string|object $entity Either an instance or a valid class name for an entity
 * @throws Exception\InvalidArgumentException if $entity is not an object or class name
 * @return ArrayObject
 */
public function getFormSpecification($entity)
{
    if (!is_object($entity)) {
        if ((is_string($entity) && (!class_exists($entity))) // non-existent class
            || (!is_string($entity)) // not an object or string
        ) {
            throw new Exception\InvalidArgumentException(sprintf(
                '%s expects an object or valid class name; received "%s"',
                __METHOD__,
                var_export($entity, 1)
            ));
        }
    }

    $formSpec = NULL;
    if ($this->cache) { 
        //generate cache key from entity name
        $cacheKey =  (is_string($entity) ? $entity : get_class($entity)) . '_form_cache';

        //get the cached form annotations, try cache first
        $formSpec = $this->cache->getItem($cacheKey);
    }
    if (empty($formSpec)) {
        $this->entity      = $entity;
        $annotationManager = $this->getAnnotationManager();
        $formSpec          = new ArrayObject();
        $filterSpec        = new ArrayObject();

        $reflection  = new ClassReflection($entity);
        $annotations = $reflection->getAnnotations($annotationManager);

        if ($annotations instanceof AnnotationCollection) {
            $this->configureForm($annotations, $reflection, $formSpec, $filterSpec);
        }

        foreach ($reflection->getProperties() as $property) {
            $annotations = $property->getAnnotations($annotationManager);

            if ($annotations instanceof AnnotationCollection) {
                $this->configureElement($annotations, $property, $formSpec, $filterSpec);
            }
        }

        if (!isset($formSpec['input_filter'])) {
            $formSpec['input_filter'] = $filterSpec;
        }

        //save annotations to cache
        if ($this->cache) { 
            $this->cache->addItem($cacheKey, $formSpec);
        }
    }

    return $formSpec;
}
 1
Author: KTastrophy, 2013-08-12 16:03:10