Php Smarty::$\u tpl\u vars-未定义属性-支持Smarty 3中的\u tpl\u vars

Php Smarty::$\u tpl\u vars-未定义属性-支持Smarty 3中的\u tpl\u vars,php,smarty,smarty3,Php,Smarty,Smarty3,我正在将旧的PHP5.2.14和Smarty2.6.19迁移到PHP7.3.25+Smarty3.1.34 PHP代码库非常庞大,我使用Smarty::\u tpl\u vars数组访问分配的变量 $smarty->assign("myvar","var-value"); $myvar = $smarty->_tpl_vars['myvar']; #this returns "var-value" 此方法似乎已被弃用

我正在将旧的PHP5.2.14和Smarty2.6.19迁移到PHP7.3.25+Smarty3.1.34

PHP代码库非常庞大,我使用Smarty::\u tpl\u vars数组访问分配的变量

$smarty->assign("myvar","var-value"); 
$myvar = $smarty->_tpl_vars['myvar']; #this returns "var-value"  
此方法似乎已被弃用并替换为getTemplateVars


在较新版本的Smarty中是否有使用\u tpl\u vars的解决方法您可以创建一个polyfill类,通过实现接口包装
getTemplateVars
方法,并将其作为
\u tpl\u vars
分配给Smarty实例。您需要在应用程序中非常仔细地测试这个。这是一个概念的证明,我刚刚提出并测试了这个答案,以证明这是可能的

特别是,您应该检查是否需要在PHP5.2代码中通过引用将Smarty实例传递到构造函数中-我现在只有7.4可供测试

<?php
class TplVarsPolyfill implements ArrayAccess
{
    private $_smarty;

    public function __construct(Smarty $smarty)
    {
        $this->_smarty  = $smarty;
    }

    public function offsetSet($varName, $value)
    {
        $this->_smarty->assign($varName, $value);
    }

    public function offsetExists($offset)
    {
        $tplVars = $this->_smarty->getTemplateVars();
        return isset($tplVars[$offset]);
    }

    public function offsetUnset($varName)
    {
        $this->_smarty->clearAssign($varName);
    }

    public function offsetGet($offset)
    {
        $tplVars = $this->_smarty->getTemplateVars();
        return isset($tplVars[$offset]) ? $tplVars[$offset] : null;
    }

    /**
     * This is required to convince Smarty to set the instance
     * @see Smarty::__set
     * @return mixed
     */ 
    public function _tpl_vars()
    {
        return $this->_smarty->getTemplateVars();
    }
}

$smarty = new Smarty();
$smarty->_tpl_vars = new TplVarsPolyfill($smarty);

$testVarName = 'foo';
$testVal = 'bar';

$smarty->assign($testVarName, $testVal);

assert($smarty->_tpl_vars[$testVarName]==$testVal, 'Value in polyfill should match what was assigned via assign()');

$polyfillVarName = 'animal';
$polyfillVal = 'wombat';

$smarty->_tpl_vars[$polyfillVarName] = $polyfillVal;

$smartyTemplateVars = $smarty->getTemplateVars();
assert($smartyTemplateVars[$polyfillVarName]==$polyfillVal, 'Value in getTemplateVars() should match what was assigned via polyfill');

通过在php5.2/Smarty 2中的Smarty.class.php中添加以下代码片段来管理解决方案

function getTemplateVars($name=null)
{
    return $this->_tpl_vars[$name];
}

我将用$smarty->getTemplateVars()替换所有$smarty->\u tpl\u vars[],这样可以确保向后兼容性。

使用
getTemplateVars()
有什么问题?正如我提到的,代码库很大,迁移需要时间。在迁移过程中,很少有服务器仍然在旧的php/smarty设置上运行。因此,在升级整个服务器之前,我必须让代码在两个版本的PHP上都工作。
\u tpl\u vars
是一个私有字段,不应该首先访问它。对于smarty 2,您必须使用
get\u template\u vars()
,请参阅。根据您使用的IDE,您可以使用“全部替换”将对
\u tpl\u vars
的访问更改为使用
get\u template\u vars()
甚至
getTemplateVars()
。记事本++还有一个“全部替换”,可以运行多个文件。根据您的部署/升级策略,您可能希望使用
SmartyBC
类()。但是,您仍然不应该使用
\u tpl\u vars