Smarty的保留变量为 null

PHPABC PHP开发 1,446 次浏览 , , 没有评论

Smarty 中可用的变量一般有三种:1、来自PHP页面,通过assign()方法传递的变量;2、保留变量,即相当于PHP中预定义的变量;3、从配置文件中读取的变量。引用方法很简单,我就不详细说明了,具体可见:这里。不过,我遇到一个问题,就是在模板中引用保留变量时,其值为空(null )。开始感觉比较奇怪,后发现是其引用于PHP的php.ini中register_long_arrays设置、Smarty对象的 request_use_auto_globals 属性有关。

一、保量变量值为空(null )
例如,在模板中使用下面的方式获取一个保留变量:

{$smarty.server.PHP_SELF}

我原来的想法是,它应该返回一个相当于下面PHP的变量:

_SERVER["PHP_SELF"]

但是,在测试环境中,发现其值为空(null),与预期不相符。
后查看编译后的页面:
引用

Smarty/templates_c/%%193/%%1934206966/test.php

上面的语句被转换成如下的语句:

<?php echo $GLOBALS['HTTP_SERVER_VARS']['PHP_SELF']; ?>

二、处理方法
从上面可知,Smarty 的保留变量会转换为$GLOBALS[‘HTTP_SERVER_VARS’]数组的元素。而该数组是否生效,与PHP配置文件/etc/php.ini 的设定有关:
引用

register_long_arrays = On

只有当 register_long_arrays为打开状态时,$HTTP_*_VARS 变量才有效。而测试环境中,该值为Off,所以,当Smarty的保留变量为空值(null )。可见,这会对GET、POST、SERVER等保留变量都有影响。

三、注意事项
1、建议关闭 register_long_arrays
PHP手册中,有如下一段话:
引用

register_long_arrays boolean
Tells PHP whether or not to register the deprecated long $HTTP_*_VARS type predefined variables. When On (default), long predefined PHP variables like $HTTP_GET_VARS will be defined. If you're not using them, it's recommended to turn them off, for performance reasons. Instead, use the superglobal arrays, like $_GET. This directive became available in PHP 5.0.0.
Warning
This feature has been DEPRECATED as of PHP 5.3.0. Relying on this feature is highly discouraged.

也就是说,建议关闭该设定值,并且在PHP 5.3.0后该设定将会被取消。

2、更好的方法
实际上,Smarty也考虑到了该问题,并且提供了解决办法。就是在创建Smarty对象时,把其request_use_auto_globals值设置为true:

$smarty->request_use_auto_globals = true;

Smarty手册的说明如下:
引用
指定Smarty是否使用php 的$HTTP_*_VARS[]数组变量(默认$request_use_auto_globals=false)或$_*[]数组 ($request_use_auto_globals=true)变量。这对使用了{$smarty.request.*},, {$smarty.get.*}等标记的模板有影响。值得注意的是:如果设置$request_use_auto_globals为真,variable.request.vars.order就无效了但php的gpc_order配置值还有作用。

可见,该值默认为false,即使用$HTTP_*_VARS[]数组变量。修改为true后,上面的保留变量会转换为:

<?php echo $_SERVER['PHP_SELF']; ?>

这时,即可把 PHP设置中的register_long_arrays 关闭。
※ 注意:修改request_use_auto_globals 后,建议把templates_c/目录下的文件都清空,待Smarty重建。

发表评论

电子邮件地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据

Go