You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过PHP动态获取Twig模板中的所有变量及对象属性?

如何通过PHP动态获取Twig模板中使用的所有变量

可以实现这个需求,核心思路是利用Twig的词法分析器和解析器遍历模板的抽象语法树(AST),提取所有显式引用的变量,包括嵌套属性和被包含模板中的变量,无需在模板内添加dump代码。

实现步骤

1. 初始化Twig环境并解析模板为AST

首先加载目标模板,将其解析为Twig的抽象语法树,这是提取变量的基础:

use Twig\Environment;
use Twig\Loader\FilesystemLoader;
use Twig\Parser;

// 初始化Twig文件加载器和环境
$loader = new FilesystemLoader('/path/to/your/templates');
$twig = new Environment($loader);

// 指定要分析的模板路径
$targetTemplate = 'page.html.twig';
// 获取模板源代码
$source = $twig->getLoader()->getSourceContext($targetTemplate);

// 词法分析生成Token,再解析为AST
$lexer = $twig->getLexer();
$tokens = $lexer->tokenize($source);
$parser = new Parser($twig);
$ast = $parser->parse($tokens);

2. 编写AST访问者提取变量

实现Twig的节点访问者接口,遍历AST节点,提取普通变量、嵌套属性,同时递归处理被包含的模板:

use Twig\Node\Node;
use Twig\NodeVisitor\NodeVisitorInterface;
use Twig\Node\Expression\NameExpression;
use Twig\Node\Expression\GetAttrExpression;
use Twig\Node\IncludeNode;

class TemplateVariableExtractor implements NodeVisitorInterface
{
    private $collectedVars = [];
    private $twigEnv;

    public function __construct(Environment $env)
    {
        $this->twigEnv = $env;
    }

    public function getCollectedVariables(): array
    {
        return array_unique($this->collectedVars);
    }

    public function enterNode(Node $node, Environment $env): Node
    {
        // 提取普通变量(如 {{ username }})
        if ($node instanceof NameExpression) {
            $this->collectedVars[] = $node->getAttribute('name');
        }

        // 提取嵌套属性(如 {{ user.profile.email }})
        if ($node instanceof GetAttrExpression) {
            $this->extractNestedPath($node);
        }

        // 处理被包含的模板,递归提取变量
        if ($node instanceof IncludeNode) {
            $templateExpr = $node->getNode('template');
            if ($templateExpr instanceof NameExpression) {
                $includedTemplate = $templateExpr->getAttribute('name');
                $this->extractFromIncludedTemplate($includedTemplate);
            }
        }

        return $node;
    }

    private function extractNestedPath(GetAttrExpression $node)
    {
        $currentNode = $node;
        $pathParts = [];

        // 回溯嵌套节点,拼接完整属性路径
        while ($currentNode instanceof GetAttrExpression) {
            $attr = $currentNode->getNode('attribute');
            if (method_exists($attr, 'getAttribute')) {
                $pathParts[] = $attr->getAttribute('value');
            }
            $currentNode = $currentNode->getNode('node');
        }

        if ($currentNode instanceof NameExpression) {
            $pathParts[] = $currentNode->getAttribute('name');
            $fullPath = implode('.', array_reverse($pathParts));
            $this->collectedVars[] = $fullPath;
        }
    }

    private function extractFromIncludedTemplate(string $templatePath)
    {
        $source = $this->twigEnv->getLoader()->getSourceContext($templatePath);
        $lexer = $this->twigEnv->getLexer();
        $tokens = $lexer->tokenize($source);
        $parser = new Parser($this->twigEnv);
        $includedAst = $parser->parse($tokens);

        $visitor = new self($this->twigEnv);
        $visitor->enterNode($includedAst, $this->twigEnv);
        $this->collectedVars = array_merge($this->collectedVars, $visitor->getCollectedVariables());
    }

    public function leaveNode(Node $node, Environment $env): ?Node
    {
        return $node;
    }

    public function getPriority(): int
    {
        return 0;
    }
}

3. 执行提取并获取结果

将访问者加入Twig环境,触发AST遍历,最终得到所有变量:

// 初始化提取器
$extractor = new TemplateVariableExtractor($twig);
$twig->addNodeVisitor($extractor);

// 触发解析流程,自动调用访问者
$twig->parse($tokens);

// 获取所有提取到的变量
$requiredVariables = $extractor->getCollectedVariables();

// 输出结果示例
print_r($requiredVariables);

注意事项

  • 仅能提取显式引用的变量,无法处理动态生成的变量(如 {{ attribute(user, dynamicKey) }}),这类变量在模板编译前无法确定具体名称。
  • 若模板使用了宏(Macro),需要在访问者中添加对MacroCallNode的处理逻辑,以提取宏调用中的变量。
  • 确保Twig加载器能访问到所有被包含的模板,否则递归提取会失败。

内容的提问来源于stack exchange,提问作者Fatemeh Gharri

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 19:55:25