zendframework / zend-form

Form component from Zend Framework
BSD 3-Clause "New" or "Revised" License
69 stars 87 forks source link

Question about (view) helpers' plugin aliases #76

Closed pine3ree closed 8 years ago

pine3ree commented 8 years ago

This could be considered a general question about the AbstractPluginManager service-manager. I was wondering if it is possible to avoid defining multiple aliases such as:

formdatetimelocal form_date_time_local formDateTimeLocal FormDateTimeLocal

datetimelocal dateTimeLocal DateTimeLocal

and have a normalizeName($name) method called in the manager get() method so we can use just

formdatetimelocal datetimelocal

public function normalizeName($name) 
{
    return preg_replace('/[^a-z0-9]/', '', strtolower(name)); // I am not 100% sure maybe 0-9 char class could be skipped as well, right now I don't remember of any pluginalias having a digit.
}

kind regards

weierophinney commented 8 years ago

Normalization was one of the biggest performance issues we identified with zend -servicemanager, which is why it was removed from v3. So, no, we won't be adding it back.

pine3ree commented 8 years ago

@weierophinney I understand.

Still there is a performance penalty when using all the aliases defined in Zend\Form\View\HelperConfig.

In expressive I tried using both a custom factory and a delegator (sorry for the raw var_dump())

<?php
namespace App\View;

use Interop\Container\ContainerInterface;
use Zend\ServiceManager\Factory\DelegatorFactoryInterface;
use Zend\I18n\View\HelperConfig as I18nHelperConfig;
use Zend\Form\View\HelperConfig as FormHelperConfig;

class HelperPluginManagerDelegatorFactory implements DelegatorFactoryInterface
{
    public function __invoke(
        ContainerInterface $container,
        $name,
        callable $callback,
        array $options = null
    ) {
        $manager = $callback();

        (new I18nHelperConfig())->configureServiceManager($manager);

        $t0 = microtime(true);
        (new FormHelperConfig())->configureServiceManager($manager);
        var_dump(1000 * round(microtime(true) - $t0, 5) . ' ms');

        return $manager;
    }
}

Registering the factories + aliases takes about 22~26 ms in php 7 (40~48 ms for php 5.5). I believe this is due to the high number of calls to set(Alias|Factory) hence calls to configure() in the service-manager.

https://github.com/zendframework/zend-expressive-zendviewrenderer/issues/25

I temporarily solved this performance issue registering fewer helpers/aliases in zend-expressive templates.global.php config file. But i had to duplicate some aliases ( general form helpers such as formElement still need lowercase aliases).

Do you have any other suggestion/advice?

thanks and kind regards

pine3ree commented 8 years ago

@weierophinney

Just as a comparison with previous zend-expressive / zend-servicemanager (2.7.4) as explained in https://github.com/zendframework/zend-expressive-zendviewrenderer/issues/25

this factory only took 0.15 ms to register zend-form view helpers

<?php
namespace App\Factory\View;

use Interop\Container\ContainerInterface;
use Zend\ServiceManager\Config;
use Zend\View\HelperPluginManager;

use Zend\I18n\View\HelperConfig as I18nHelperConfig;
use Zend\Form\View\HelperConfig as FormHelperConfig;

/**
 * Class HelperPluginManageFactory
 */
class HelperPluginManagerFactory
{
    public function __invoke(ContainerInterface $container)
    {
        $config = $container->has('config') ? $container->get('config') : [];
        $config = isset($config['view_helpers']) ? $config['view_helpers'] : [];

        $manager = new HelperPluginManager(new Config($config));
        $manager->setServiceLocator($container);

        // Add zend-i18n view helper configuration
        $i18nHelperConfig = new I18nHelperConfig();
        $i18nHelperConfig->configureServiceManager($manager);

        // Add zend-form view helper configuration
        $t0 = microtime(true);
        $formHelperConfig = new FormHelperConfig();
        $formHelperConfig->configureServiceManager($manager);
        var_dump(1000 * round(microtime(true) - $t0, 5) . ' ms');

        return $manager;
    }
}