Php 如何防止分支节点表达式转义?

Php 如何防止分支节点表达式转义?,php,twig,Php,Twig,我正在努力实现。我几乎知道了,但我不知道如何防止输出被HTML转义 我已在Twig_分机中注册了我的新操作员: public function getOperators() { return [ [/* Unary Operators */ '...' => array('precedence' => 10, 'class' => SpreadAttributes::class), ], [/* B

我正在努力实现。我几乎知道了,但我不知道如何防止输出被HTML转义

我已在Twig_分机中注册了我的新操作员:

public function getOperators() {
    return [
        [/* Unary Operators */
            '...' => array('precedence' => 10, 'class' => SpreadAttributes::class),
        ],
        [/* Binary Operators */
            // ...
        ]
    ];
}
我的班级是这样的:

class SpreadAttributes extends Twig_Node_Expression_Unary {
    public function compile(Twig_Compiler $compiler) {
        $compiler
            ->raw(\WXUtility::class . '::html_attrs(')
            ->subcompile($this->getNode('node'))
            ->raw(')');
    }

    public function operator(Twig_Compiler $compiler) {
        throw new \Exception("Unused");
    }
}
 echo twig_escape_filter($this->env, WXUtility::html_attrs((isset($context["label_attrs"]) ? $context["label_attrs"] : $this->getContext($context, "label_attrs"))), "html", null, true);
用法:

<label{{ ...label_attrs }}>
我需要去掉
twig\u escape\u过滤器
,因为
WXUtility::html\u attrs
已经生成了转义html

我怎样才能防止逃跑


我认为这是可行的,但它相当复杂。在某个时间点,编译器创建一个
Twig\u节点\u Print
,它写出
echo
语句。在
vendor/twig/twig/lib/twig/NodeVisitor/Escaper.php的第73行中,我们可以看到它在
leaveNode
中调用
escapePrintNode
escapePrintNode
调用
$node->getNode('expr')
,它返回我们的
扩展属性的一个实例。然后传递到
isSafeFor
,如果安全(不需要转义),它将返回true。如果不安全,则应用
twig\u escape\u过滤器

所以我们只需要覆盖
Twig\u NodeVisitor\u Escaper::isSafeFor
Twig\u NodeVisitor\u SafeAnalysis::getSafe

$twig->removeExtension
已被弃用,因此我无法删除默认的
转义器
扩展。我想我必须重写Twig_环境
,将其从构造函数中取出。然后从那里覆盖
getNodeVisitors
。然后
isSafeFor
。但是
Twig\u Node\u表达式
没有我可以检查的任何有用属性;我能做的最好的事情就是
instanceof spreadsattributes
,这是一个主要的黑客攻击


没有更好的方法了吗?

我不知道为什么我没早点想到,但我最后还是看了看
小树枝逃生过滤器。如果它是
Twig\u标记的一个实例
,它将不会转义字符串。因此,我们所要做的就是将输出包装成:

class SpreadAttributes extends Twig_Node_Expression_Unary {
    public function compile(Twig_Compiler $compiler) {
        $compiler
            ->raw(__CLASS__ . '::attrs(')
            ->subcompile($this->getNode('node'))
            ->raw(', $this->env->getCharset())'); // not sure if this is the best way to pass the charset along, but it seems to work
    }

    public function operator(Twig_Compiler $compiler) {
        throw new \Exception("Unused");
    }

    public static function attrs($attrs, $charset) {
        return new Twig_Markup(WXU::html_attrs($attrs), $charset);
    }
}
砰!不能再逃跑了


有关
html\u attrs

的示例实现,请参阅。过滤器是否可以工作?@Orangepill如何在
SpreadAttributes
类中应用raw?我不想到处写
{…label|attrs|raw}
。考虑到它的用途,您永远不会将它与
|raw
一起使用。呵呵。谢谢分享!