Symfony3 Profiler存储

时间:2015-12-05 18:32:08

标签: redis profiler symfony

文档中的

http://symfony.com/doc/master/cookbook/profiler/storage.html

您仍然可以找到有关Profiler存储的信息。 我刚检查了代码,找不到任何线索如何设置自定义存储。 我还发现没有文档说明这一点,除了原始资源中的@legacy注意事项2.8。

是否有理由将其删除? 我使用redis来存储这些数据,其生命周期为1小时。 现在我需要运行手动清理来擦除该目录中的所有文件。 如果有人有一些线索或提示帮助我解决这个问题,那么^^

克里斯

2 个答案:

答案 0 :(得分:2)

感谢Matteo的提示,我能够很灵活地解决这个问题。 Symfony团队删除了这个,因为它被硬编码到Profiler子系统中。 而不是通过添加类参数来解决这个问题,我必须解决它。 :)

好的,这是代码,如果有人需要这个。

首先,我们需要来自Symfony 2.7的原始类(至少我重用它们,因为我只需要Redis选项(我使用它,因为我可以使用igbinary压缩数据)

接下来,您需要实现编译器通行证。

int

这需要在Bundle Loader中加载:

        namespace AcmeBunlde\DependencyInjection\CompilerPass;

        use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
        use Symfony\Component\DependencyInjection\ContainerBuilder;

        class ProfilerCompilerPass implements CompilerPassInterface
        {

            /**
             * You can modify the container here before it is dumped to PHP code.
             *
             * @param ContainerBuilder $container
             */
            public function process(ContainerBuilder $container)
            {
                $definition = $container->getDefinition('profiler');
                $definition->addArgument('%acmebundle.profiler.defaultEnabled%');
                $definition->addArgument('%acmebundle.profiler.class%');
                $definition->addArgument('%acmebundle.profiler.dsn%');
                $definition->addArgument('%acmebundle.profiler.username%');
                $definition->addArgument('%acmebundle.profiler.password%');
                $definition->addArgument('%acmebundle.profiler.ttl%');
                $definition->setClass('acmebundle\Profiler\Profiler');
            }
        }

在此之后,我们需要在DependencyInjection文件夹中添加新Profiler存储的配置。

    public function build(ContainerBuilder $container)
    {
        ...
        $container->addCompilerPass(new ProfilerCompilerPass());
    }

现在在Dependency Injection Bundle Loader中设置默认值

    namespace AcmeBundle\DependencyInjection;

    use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
    use Symfony\Component\Config\Definition\Builder\TreeBuilder;
    use Symfony\Component\Config\Definition\ConfigurationInterface;

    /**
     * This is the class that validates and merges configuration from your app/config files
     *
     * To learn more see {@link http://symfony.com/doc/current/cookbook/bundles/extension.html#cookbook-bundles-extension-config-class}
     * @author Chris
     */
    class Configuration implements ConfigurationInterface
        /**
         * {@inheritdoc}
         */
        public function getConfigTreeBuilder()
        {
            $treeBuilder = new TreeBuilder();
            $rootNode = $treeBuilder->root('library');

            $rootNode
                ->children()
                    ->arrayNode('profiler')
                        ->addDefaultsIfNotSet()
                        ->children()
                            ->booleanNode('defaultStorage')
                                ->defaultTrue()
                            ->end()
                            ->scalarNode('class')
                                ->defaultValue('')
                            ->end()
                            ->scalarNode('dsn')
                                ->defaultValue('')
                            ->end()
                            ->scalarNode('username')
                                ->defaultValue('')
                            ->end()
                            ->scalarNode('password')
                                ->defaultValue('')
                            ->end()
                            ->scalarNode('ttl')
                                ->defaultValue('3600')
                            ->end()
                        ->end()
                    ->end();
            return $treeBuilder();
        }
    }

作为最后一步,您需要构建一个基本容器来添加新的Profiler处理程序。 我选择实现它不复杂:

    <?php

    namespace AcmeBundle\DependencyInjection;

    use Symfony\Component\DependencyInjection\ContainerBuilder;
    use Symfony\Component\Config\FileLocator;
    use Symfony\Component\HttpKernel\DependencyInjection\Extension;
    use Symfony\Component\DependencyInjection\Loader;
    use Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface;

    /**
     * This is the class that loads and manages your bundle configuration
     *
     * To learn more see {@link http://symfony.com/doc/current/cookbook/bundles/extension.html}
     * @author Chris 
     */
    class AcmeExtension extends Extension
    {
        /**
         * {@inheritdoc}
         */
        public function load(array $configs, ContainerBuilder $container)
        {

            $configuration = new Configuration();
            $config = $this->processConfiguration($configuration, $configs);
            ...
            $container->setParameter('acmebundle.profiler.defaultEnabled',$config['profiler']['defaultStorage']);
            $container->setParameter('acmebundle.profiler.class',$config['profiler']['class']);
            $container->setParameter('acmebundle.profiler.dsn',$config['profiler']['dsn']);
            $container->setParameter('acmebundle.profiler.username',$config['profiler']['username']);
            $container->setParameter('acmebundle.profiler.password',$config['profiler']['password']);
            $container->setParameter('acmebundle.profiler.ttl',$config['profiler']['ttl']);
            ...
        }
        ...
    }

我还添加了一个库来定义存储接口的构造函数。

    <?php

        namespace AcmeBundle\Profiler;
        use Psr\Log\LoggerInterface;
        use \Symfony\Component\HttpKernel\Profiler\Profiler as ProfilerSrc;
        use Symfony\Component\HttpKernel\Profiler\ProfilerStorageInterface;

        /**
         * Profiler.
         */
        class Profiler extends ProfilerSrc
        {
            public function __construct(ProfilerStorageInterface $storage, LoggerInterface $logger, $defaultEnabled=true,$class=null,$dsn=null,$username=null,$password=null,$ttl=3600)
            {
                if($defaultEnabled!==true)
                {
                    $storage = new $class($dsn,$username,$password,$ttl);
                }
                parent::__construct($storage , $logger);
            }
        }

现在您需要做的就是在config_dev.yml文件中定义一些选项。

    <?php

        namespace AcmeBundle\Profiler;

        use Symfony\Component\HttpKernel\Profiler\ProfilerStorageInterface as ProfilerStorageSource;

        interface ProfilerStorageInterface extends ProfilerStorageSource
        {
            /**
             * ProfilerStorageInterface constructor.
             *
             * @param $dsn
             * @param $username
             * @param $password
             * @param $ttl
             */
            public function __construct($dsn,$username,$password,$ttl);
        }

使用defaultEnabled = true您可以重新启用原始处理程序。 其余的是,我相信自我解释。 用户名+密码来自原始功能集。 (ttl ==一生)

我希望这也有助于其他人:)

答案 1 :(得分:1)

自2.8以来被标记为已弃用,并且在3.0中有抑制。我在PR找不到任何动机。如您所述,该文档尚未更新。

唯一的建议是关于this issue中的评论:

  

如果您想使用自己的分析器存储实现,   然后只需覆盖profile.storage服务。

希望这个帮助