Smarty assignByRef 内部循环
Smarty assignByRef inside loop
我需要为循环内的不同值渲染一些 Smarty 模板(PHP 循环,而不是 Smarty foreach
), 方式如下(仅举个例子):
$a = 0;
$b = 0;
$output = "";
$tmpl = "$a, $b";
$smarty->assignByRef('a', $a['a']);
$smarty->assignByRef('b', $b['b']);
for (int i = 0; i < 10; ++i) {
++$a;
++$b;
$output .= $smarty->fetch("string:" . $tmpl);
}
我的疑问是assignByRef
。 Smarty v3 文档说:
With the introduction of PHP5, assignByRef() is not necessary for most
intents and purposes. assignByRef() is useful if you want a PHP array
index value to be affected by its reassignment from a template.
Assigned object properties behave this way by default.
但我不完全理解该技术说明的含义。那么,我可以这样使用 assignByRef
吗?或者只使用 assign
会产生相同的输出?
PHP 4 个对象被 按值 传递,除非用户通过前置 & 符号明确指定引用:&$variable
。出于这个原因,可能会消耗大量内存的函数参数通过引用传递以优化内存使用:
function f(&$huge) {
// ...
}
PHP 5 个变量通过引用传递,即使用户没有明确指定它(未使用 & 字符)。通过将一个变量分配给另一个变量,我们只是为内存中的相同数据创建了一个新容器(内部称为 zval
)。考虑一下:
$a = new stdClass;
$b = $a;
第一行为变量$a
和stdClass
的对象分配内存,并将对象的标识符存储到变量中。第二行为变量 $b
分配内存,将对象的标识符存储到 $b
变量中,并增加一个内部引用计数器。引用计数器值显示对象在代码中被引用了多少次。当 $b
变量被销毁时,引用计数器减一。当引用计数器的值变为零时,对象的内存将被释放。下面的代码演示了这个想法:
$a = new stdClass;
debug_zval_dump($a);
$b = $a;
debug_zval_dump($a);
$c = $a;
debug_zval_dump($a);
$c = null; // destroy $c
debug_zval_dump($a);
$b = null; // destroy $b
debug_zval_dump($a);
输出
object(stdClass)#1 (0) refcount(2){
}
object(stdClass)#1 (0) refcount(3){
}
object(stdClass)#1 (0) refcount(4){
}
object(stdClass)#1 (0) refcount(3){
}
object(stdClass)#1 (0) refcount(2){
}
但是当变量被修改时,PHP版本 5 和 7 会创建变量的副本,以保持原始值(变量)不变。
$m1 = memory_get_usage();
$a = str_repeat('a', 1 << 24);
echo number_format(memory_get_usage() - $m1), PHP_EOL;
// 16,781,408
$b = $a;
$c = $a;
echo number_format(memory_get_usage() - $m1), PHP_EOL;
// 16,781,472
$b[0] = 'x';
echo number_format(memory_get_usage() - $m1), PHP_EOL;
// 33,562,880
$c[0] = 'x';
echo number_format(memory_get_usage() - $m1), PHP_EOL;
// 50,344,288
这同样适用于函数参数的上下文。因此,如果一个变量应该用于只读,则不需要显式地通过引用传递它。 Smarty 文档中的话意味着在大多数情况下,您将变量传递给模板,并且通常不希望模板更改它们。仅当您确实希望在模板中修改变量时才需要通过引用传递变量。同样的概念适用于 PHP 5 和更新版本中的任何函数参数。
我需要为循环内的不同值渲染一些 Smarty 模板(PHP 循环,而不是 Smarty foreach
), 方式如下(仅举个例子):
$a = 0;
$b = 0;
$output = "";
$tmpl = "$a, $b";
$smarty->assignByRef('a', $a['a']);
$smarty->assignByRef('b', $b['b']);
for (int i = 0; i < 10; ++i) {
++$a;
++$b;
$output .= $smarty->fetch("string:" . $tmpl);
}
我的疑问是assignByRef
。 Smarty v3 文档说:
With the introduction of PHP5, assignByRef() is not necessary for most intents and purposes. assignByRef() is useful if you want a PHP array index value to be affected by its reassignment from a template. Assigned object properties behave this way by default.
但我不完全理解该技术说明的含义。那么,我可以这样使用 assignByRef
吗?或者只使用 assign
会产生相同的输出?
PHP 4 个对象被 按值 传递,除非用户通过前置 & 符号明确指定引用:&$variable
。出于这个原因,可能会消耗大量内存的函数参数通过引用传递以优化内存使用:
function f(&$huge) {
// ...
}
PHP 5 个变量通过引用传递,即使用户没有明确指定它(未使用 & 字符)。通过将一个变量分配给另一个变量,我们只是为内存中的相同数据创建了一个新容器(内部称为 zval
)。考虑一下:
$a = new stdClass;
$b = $a;
第一行为变量$a
和stdClass
的对象分配内存,并将对象的标识符存储到变量中。第二行为变量 $b
分配内存,将对象的标识符存储到 $b
变量中,并增加一个内部引用计数器。引用计数器值显示对象在代码中被引用了多少次。当 $b
变量被销毁时,引用计数器减一。当引用计数器的值变为零时,对象的内存将被释放。下面的代码演示了这个想法:
$a = new stdClass;
debug_zval_dump($a);
$b = $a;
debug_zval_dump($a);
$c = $a;
debug_zval_dump($a);
$c = null; // destroy $c
debug_zval_dump($a);
$b = null; // destroy $b
debug_zval_dump($a);
输出
object(stdClass)#1 (0) refcount(2){
}
object(stdClass)#1 (0) refcount(3){
}
object(stdClass)#1 (0) refcount(4){
}
object(stdClass)#1 (0) refcount(3){
}
object(stdClass)#1 (0) refcount(2){
}
但是当变量被修改时,PHP版本 5 和 7 会创建变量的副本,以保持原始值(变量)不变。
$m1 = memory_get_usage();
$a = str_repeat('a', 1 << 24);
echo number_format(memory_get_usage() - $m1), PHP_EOL;
// 16,781,408
$b = $a;
$c = $a;
echo number_format(memory_get_usage() - $m1), PHP_EOL;
// 16,781,472
$b[0] = 'x';
echo number_format(memory_get_usage() - $m1), PHP_EOL;
// 33,562,880
$c[0] = 'x';
echo number_format(memory_get_usage() - $m1), PHP_EOL;
// 50,344,288
这同样适用于函数参数的上下文。因此,如果一个变量应该用于只读,则不需要显式地通过引用传递它。 Smarty 文档中的话意味着在大多数情况下,您将变量传递给模板,并且通常不希望模板更改它们。仅当您确实希望在模板中修改变量时才需要通过引用传递变量。同样的概念适用于 PHP 5 和更新版本中的任何函数参数。