Twig 如何使用动态变量设置变量名?
我试图用动态名称设置变量。我使用的代码是:Twig 如何使用动态变量设置变量名?,twig,Twig,我试图用动态名称设置变量。我使用的代码是: {% for i in 0..2 %} {% set foo~i = 'array'.'~i~'.'getfoo' %} {% set bar~i = 'array'.'~i~'.'getbar' %} {% endfor %} 我想要的变量是: foo0 bar0 foo1 bar1 foo2 bar2 但是我得到了这个错误值为“~”的意外标记“运算符”(“应该是语句块结尾) 另外,我不希望这些变量作为数组。就像前面提到
{% for i in 0..2 %}
{% set foo~i = 'array'.'~i~'.'getfoo' %}
{% set bar~i = 'array'.'~i~'.'getbar' %}
{% endfor %}
我想要的变量是:foo0
bar0
foo1
bar1
foo2
bar2 但是我得到了这个错误
值为“~”的意外标记“运算符”(“应该是语句块结尾)
另外,我不希望这些变量作为数组。就像前面提到的@DarkBee一样,在vanilla Twig中不能这样做。但是您可以创建一个非常简单的扩展–请注意,
$context
需要通过引用传递:
class MyTwigExtension extends Twig_Extension {
public function getFunctions() {
return [
new Twig_Function('set', [$this, 'set'], ['needs_context' => true]),
];
}
public function set(&$context, $name, $value) {
$context[$name] = $value;
}
}
$twig->addExtension(new MyTwigExtension());
然后在Twig中,您可以执行以下操作:
{{ dump() }}
{% do set('foo' ~ 1, 'bar') %}
{{ dump() }}
以上将打印:
array(0) {
}
array(1) {
["foo1"]=>
string(3) "bar"
}
array(3) {
["foo0"]=>
NULL
["foo1"]=>
string(11) "iteration 1"
["foo2"]=>
string(11) "iteration 2"
}
array(4) {
["foo13"]=>
string(7) "1 and 3"
["foo14"]=>
string(7) "1 and 4"
["foo23"]=>
string(7) "2 and 3"
["foo24"]=>
string(7) "2 and 4"
}
但是请注意,for
循环有自己的上下文。因此,如果您这样做:
{% set foo = 'bar' %}
Before loop:
{{ dump() }}
{% for i in 0..2 %}
{%- do set('foo' ~ i, 'iteration ' ~ i) %}
{%- if loop.last %}
{{- 'Inside loop (last iteration):\n' }}
{{- loop.last ? dump() }}
{% endif %}
{% endfor %}
After loop:
{{ dump() }}
您可以看到这一点–请注意\u parent
数组,它表示循环外部的“parent”上下文:
Before loop:
array(1) {
["foo"]=>
string(3) "bar"
}
Inside loop (last iteration):
array(9) {
["foo"]=>
string(3) "bar"
["_parent"]=>
array(1) {
["foo"]=>
string(3) "bar"
}
["_seq"]=>
array(3) {
[0]=>
int(0)
[1]=>
int(1)
[2]=>
int(2)
}
["loop"]=>
array(8) {
["parent"]=>
array(1) {
["foo"]=>
string(3) "bar"
}
["index0"]=>
int(2)
["index"]=>
int(3)
["first"]=>
bool(false)
["revindex0"]=>
int(0)
["revindex"]=>
int(1)
["length"]=>
int(3)
["last"]=>
bool(true)
}
["i"]=>
int(2)
["_key"]=>
int(2)
["foo0"]=>
string(11) "iteration 0"
["foo1"]=>
string(11) "iteration 1"
["foo2"]=>
string(11) "iteration 2"
}
After loop:
array(1) {
["foo"]=>
string(3) "bar"
}
您可以通过三种方式克服此限制。首先是在for
循环之前初始化变量(注意foo0
保留为null
,因为循环从1
开始,而foo3
由于未初始化而不在全局上下文中):
以上将打印:
array(0) {
}
array(1) {
["foo1"]=>
string(3) "bar"
}
array(3) {
["foo0"]=>
NULL
["foo1"]=>
string(11) "iteration 1"
["foo2"]=>
string(11) "iteration 2"
}
array(4) {
["foo13"]=>
string(7) "1 and 3"
["foo14"]=>
string(7) "1 and 4"
["foo23"]=>
string(7) "2 and 3"
["foo24"]=>
string(7) "2 and 4"
}
第二种方法是修改扩展的set
方法,以检查$context
是否包含键\u parent
:
public function set(&$context, $name, $value) {
$context[$name] = $value;
if (array_key_exists('_parent', $context)) {
$this->set($context['_parent'], $name, $value);
}
}
那么,即使是嵌套的for
循环也不是问题:
{% for i in 1..2 %}
{% for j in 3..4 %}
{% do set('foo' ~ i ~ j, i ~ ' and ' ~ j) %}
{% endfor %}
{% endfor %}
{{ dump() }}
以上将打印:
array(0) {
}
array(1) {
["foo1"]=>
string(3) "bar"
}
array(3) {
["foo0"]=>
NULL
["foo1"]=>
string(11) "iteration 1"
["foo2"]=>
string(11) "iteration 2"
}
array(4) {
["foo13"]=>
string(7) "1 and 3"
["foo14"]=>
string(7) "1 and 4"
["foo23"]=>
string(7) "2 and 3"
["foo24"]=>
string(7) "2 and 4"
}
第三种方法是保持扩展的set
方法完好无损,并创建一个新方法,例如set\u global
:
class MyTwigExtension extends Twig_Extension {
public function getFunctions() {
return [
new Twig_Function('set', [$this, 'set'], ['needs_context' => true]),
new Twig_Function('set_global', [$this, 'set_global'], ['needs_context' => true]),
];
}
public function set(&$context, $name, $value) {
$context[$name] = $value;
}
public function set_global(&$context, $name, $value) {
$context[$name] = $value;
if (array_key_exists('_parent', $context)) {
return $this->set_global($context['_parent'], $name, $value);
}
}
}
$twig->addExtension(new MyTwigExtension());
然后,您可以使用
set
在当前上下文中设置变量(例如,在for
循环的上下文中)或set_global
设置“全局”变量(在文件的上下文中)。您可以在for
循环中使用这两种方法来为已初始化的变量设置新值。不能通过vanillatwig
完成,您需要一个扩展