Symfony3 分析器存储
Symfony3 Profiler Storage
在文档中
http://symfony.com/doc/master/cookbook/profiler/storage.html
您仍然可以找到有关 Profiler 存储的信息。
我刚刚检查了代码,找不到任何关于如何设置自定义存储的线索。
除了 2.8 的原始来源中的一些@legacy 注释外,我也没有找到说明这一点的文档。
是否有删除此内容的原因?
我使用 redis 来存储此数据,其生命周期为 eta 1 小时。
现在我需要 运行 手动清理以清除该目录中的所有文件。
如果有人有一些线索或提示可以帮助我解决这个问题,我们将不胜感激^^
克里斯
自 2.8 起被标记为已弃用,并在 3.0 中被禁止。我在 PR 中找不到任何动机。该文档尚未像您提到的那样更新。
唯一的建议是关于 this issue 中的评论:
If you want to use your own implementation of a profiler storage,
then just override the profile.storage service.
希望对您有所帮助
感谢 Matteo 的提示,我能够非常灵活地解决这个问题。
Symfony 团队删除了它,因为它被硬编码到 Profiler 子系统中。
我没有通过添加 class 参数来解决这个问题,而是不得不解决它。 :)
好的,这是代码,如果有人需要的话。
首先我们需要 Symfony 2.7 的原始 类(至少我重用了它们,因为我只需要 Redis 选项(我使用它,因为我可以使用 igbinary 压缩数据)
接下来你需要实现一个 Compiler Pass。
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');
}
}
这需要在 Bundle Loader 中加载:
public function build(ContainerBuilder $container)
{
...
$container->addCompilerPass(new ProfilerCompilerPass());
}
在此之后,我们需要在 DependencyInjection 文件夹中添加新分析器存储的配置。
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();
}
}
现在在依赖注入捆绑加载器中设置默认值
<?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']);
...
}
...
}
作为最后一步,您需要构建一个基本容器以添加新的 Profiler 处理程序。
我选择实现它不复杂:
<?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);
}
}
我还添加了一个库来定义存储接口的构造函数。
<?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);
}
您现在需要做的就是在 config_dev.yml 文件中定义一些选项。
acmebundle:
profiler:
defaultEnabled: false
class:CLASSNAME INCLUDING NAMESPACE
dsn: redis://localhost/1
username:
password
ttl: 3600
使用 defaultEnabled = true 您可以重新启用原始处理程序。
剩下的就是,我相信自我解释。
用户名+密码来自原始功能集。
(ttl == 生命周期)
我希望这对其他人也有帮助:)
在文档中
http://symfony.com/doc/master/cookbook/profiler/storage.html
您仍然可以找到有关 Profiler 存储的信息。 我刚刚检查了代码,找不到任何关于如何设置自定义存储的线索。 除了 2.8 的原始来源中的一些@legacy 注释外,我也没有找到说明这一点的文档。
是否有删除此内容的原因? 我使用 redis 来存储此数据,其生命周期为 eta 1 小时。 现在我需要 运行 手动清理以清除该目录中的所有文件。 如果有人有一些线索或提示可以帮助我解决这个问题,我们将不胜感激^^
克里斯
自 2.8 起被标记为已弃用,并在 3.0 中被禁止。我在 PR 中找不到任何动机。该文档尚未像您提到的那样更新。
唯一的建议是关于 this issue 中的评论:
If you want to use your own implementation of a profiler storage, then just override the profile.storage service.
希望对您有所帮助
感谢 Matteo 的提示,我能够非常灵活地解决这个问题。 Symfony 团队删除了它,因为它被硬编码到 Profiler 子系统中。 我没有通过添加 class 参数来解决这个问题,而是不得不解决它。 :)
好的,这是代码,如果有人需要的话。
首先我们需要 Symfony 2.7 的原始 类(至少我重用了它们,因为我只需要 Redis 选项(我使用它,因为我可以使用 igbinary 压缩数据)
接下来你需要实现一个 Compiler Pass。
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');
}
}
这需要在 Bundle Loader 中加载:
public function build(ContainerBuilder $container)
{
...
$container->addCompilerPass(new ProfilerCompilerPass());
}
在此之后,我们需要在 DependencyInjection 文件夹中添加新分析器存储的配置。
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();
}
}
现在在依赖注入捆绑加载器中设置默认值
<?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']);
...
}
...
}
作为最后一步,您需要构建一个基本容器以添加新的 Profiler 处理程序。 我选择实现它不复杂:
<?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);
}
}
我还添加了一个库来定义存储接口的构造函数。
<?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);
}
您现在需要做的就是在 config_dev.yml 文件中定义一些选项。
acmebundle:
profiler:
defaultEnabled: false
class:CLASSNAME INCLUDING NAMESPACE
dsn: redis://localhost/1
username:
password
ttl: 3600
使用 defaultEnabled = true 您可以重新启用原始处理程序。 剩下的就是,我相信自我解释。 用户名+密码来自原始功能集。 (ttl == 生命周期)
我希望这对其他人也有帮助:)