如何在将要在生产中呈现的模板中使用“dump()”twig 函数?
Posted
技术标签:
【中文标题】如何在将要在生产中呈现的模板中使用“dump()”twig 函数?【英文标题】:How can I use the "dump()" twig function in a template that is going to be rendered on production? 【发布时间】:2021-12-01 01:43:48 【问题描述】:我想在我们的测试环境中实现一个调试输出,我想在其中输出应用程序发送的服务请求。
为此,我想使用 symfony/twig 函数 dump()
,因为这里的输出针对所有类型的变量进行了精美的格式化,并且还提供了打开和关闭结构的选项。
伪代码是这样的
% if debugEnabled %
dump (debugInfos)
% endif %
不幸的是,“dump”是 Symfony DebugBundle 的一部分,出于充分的原因,它没有在 Prod 环境中加载,应该保持这种状态:
Symfony\Bundle\DebugBundle\DebugBundle::class => ['dev' => true, 'test' => true],
在 Symfony 文档中说:
根据设计,dump() 函数仅在开发和测试中可用 环境,以避免在生产中泄露敏感信息。在 事实上,尝试在 prod 环境中使用 dump() 函数会 导致 php 错误。
我根本不想在生产环境中使用dump()
,而只想在本地输出我们的服务请求。
但是,我无法实现上述代码,因为生产中总是会出现错误(未定义函数dump()
)当然,因为根本没有加载dump()
。
【问题讨论】:
谢谢,但这有什么帮助?无论我如何通过它,在生产中它仍然是错误的。在我将 DebugBundle 注册为“prod”(我不想要的)之前,在生产中的任何情况下都会出现错误(“找不到函数”) 如果尚未加载,只需创建自己的转储函数?您究竟想在生产中使用 dump() 做什么? 转储功能比我认为的更复杂。它不仅是在做一个 var_dump()。在生产中我不想用“dump()”做任何事情,但我无法在 dev 中实现调试输出的功能,因为我不能在模板中使用 dump(),因为它会在生产中引发错误。 【参考方案1】:您可以创建自己的函数来测试扩展是否已加载。
正如您在source 中看到的那样,函数twig_var_dump
已注册,因此您可以测试该函数是否存在以确定是否加载了调试扩展。
只要你的扩展在调试扩展之后被加载
,你应该可以将你自己的函数注册为dump
namespace App\Twig;
use Twig\Extension\AbstractExtension;
use Twig\TwigFunction;
use Twig\Environment;
class AppExtension extends AbstractExtension
public function getFunctions()
return [
new TwigFunction('dump', [$this, 'dump'] , ['needs_context' => true, 'needs_environment' => true, ]),
];
public function dump(Environment $env, $context, ...$vars)
if (!function_exists('\twig_var_dump')) return;
return \twig_var_dump($env, $context, ...$vars);
旁注:未对此进行测试,但应该可以使用
【讨论】:
谢谢,听起来不错,但是尽管加载了 DebugBundle,但 function_exists('twig_var_dump') 给了我错误。当我尝试调用 twig_var_dump()(我的命名空间是 App\TwigExtension)“尝试从命名空间“App\TwigExtensions”调用函数“twig_var_dump”时,我也会遇到命名空间错误。” 更新了我的答案。您是否必须明确声明该函数是在根命名空间中定义的(请参阅我添加的额外反斜杠) "symfony": 4.4.19 "twig/extensions": "1.5.4" "php": 7.4.3 Nope...function_exists 仍然为 false 并且仍然出现“尝试调用函数“twig_var_dump”错误,现在来自全局命名空间:-) 当我从控制器内部调用 $this->container->get('twig')->getFunctions() 时,“twig_var_dump”不存在,而“dump”存在。我也可以使用 $this->container->get('twig')->getExtensions() 来确定扩展是否已加载,但我不知道如何调用 dump() 输出。【参考方案2】:创建您自己的仅在生产中加载的扩展。
在您的 src 目录中创建一个文件夹(例如 Twig
)。
如果您使用默认值,则将该文件夹排除在自动装配之外:
App\:
resource: '../src/'
exclude:
- '../src/DependencyInjection/'
- '../src/Entity/'
- '../src/Kernel.php'
- '../src/Tests/'
- '../src/Twig/' # This is the directory excluded from autowiring
然后用这个内容创建一个config/services_prod.yaml
文件:
services:
App\Twig\FakeDebugExtension: # replace with your class name
tags:
- twig.extension # not needed if you use autoconfiguration
然后用这个内容创建一个类:
<?php
namespace App\Twig;
use Twig\Extension\AbstractExtension;
use Twig\TwigFunction;
final class FakeDebugExtension extends AbstractExtension
public function getFunctions(): array
return [
new TwigFunction('dump', [$this, 'fakeDump']),
];
public function fakeDump(...$arguments): void
【讨论】:
非常感谢 Rikudou_Senin。但如前所述,我的问题不是,我想转储生产。我想从树枝模板内部从 dev 中转储。如前所述,我希望能够在 dev- 和 test-envs 上输出服务请求,这使得那些不运行 smyfony 分析器的人也可以轻松扩展复杂的数据结构。因此,我想为开发人员实现一个稳定的功能,例如“if env = dev”dump()。但我不能这样做,因为这会在生产中引发错误。我当然可以做自己的转储功能,但我不想重新实现转储()。 那就不要重新实现了。使用我的确切代码,该函数在生产中不会执行任何操作,因为您可以看到它是无效的并且没有主体。通过配置,此转储功能将仅在生产中可用,而在其他环境中,您将可以访问原始转储。这意味着您的模板将在 prod 中工作,即使它们包含对转储函数的调用。 啊!我第一次没有得到正确的方法,将尝试一下。以上是关于如何在将要在生产中呈现的模板中使用“dump()”twig 函数?的主要内容,如果未能解决你的问题,请参考以下文章
SpringBoot 在生产中没有找到错误模板,尽管它在 Netbeans 中找到了它