首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将方法提取到全局范围的模板中,类似于提取函数

问将方法提取到全局范围的模板中,类似于提取函数
EN

Stack Overflow用户
提问于 2014-08-30 23:05:42
回答 2查看 686关注 0票数 0

我创建了我的迷你微框架。在加载模板的类中,我有一个名为$variable的属性。此属性存储应在我的模板中可用的变量数组。

例如:

代码语言:javascript
复制
$this->variable = array($key=>5, $data=>10);

接下来,我使用函数extract()

代码语言:javascript
复制
extract($this->variable);

现在,在我的模板(test.html.php)中,我可以简单地访问传递的变量:

test.html.php

代码语言:javascript
复制
echo $key;

我还有一个名为import()的方法。在我的模板中,我可以通过操作员$this访问此方法

test.html.php

代码语言:javascript
复制
$this->import();

有没有可能在没有$this操作符的情况下,在模板中调用我的函数import()?

EN

回答 2

Stack Overflow用户

发布于 2014-08-31 00:18:30

让您的模板实现__invoke()魔术方法。

代码语言:javascript
复制
class Template {
    ......

    public function __invoke() {
        $this->import();
    }
}

设置一个与$this相等的名为import的变量。

代码语言:javascript
复制
$this->variable['import'] = $this;

当您提取变量时,一个名为$import的变量将可用,如果您在模板中执行$import(),它应该调用模板类的__invoke()方法,而模板类又调用该类的import()方法。

不过,如果可能的话,您应该尽量避免调用模板中的方法。你应该只处理变量。在某个地方调用$import()可能不是世界上最糟糕的事情,这取决于该方法正在做什么。

票数 0
EN

Stack Overflow用户

发布于 2014-09-06 19:41:59

如果可以,请尽量避免使用extract()和全局作用域。

在使用extract()时要小心

extract()是一个非常动态的语言特性,它往往会导致与本地作用域中已经存在的变量发生冲突。您必须通过使用第二个参数来处理这一点,该参数控制新创建的变量。

仅覆盖现有变量(以便您可以创建白名单)

  • (EXTR_PREFIX_ALL)或通过向

添加前缀,包括不覆盖任何现有变量或仅覆盖现有变量(因此您可以创建白名单)

  • (EXTR_PREFIX_ALL)
  • (EXTR_SKIP)

extract()会引起开发人员的困惑,因为项目中的新开发人员根本不了解变量来自哪里。

extract() is also a performance killer,关于在HHVM中使用它,因为需要对作用域变量进行额外的记账。简而言之:在优化HHVM上的速度时,要避免这种情况。

在View对象中使用extract仍然是一种常见的做法,如下所示:

在视图对象中使用extract()提取

代码语言:javascript
复制
// View.php
class View {

    public $variables;

    function render($filename) {
        extract($this->variables);
        ob_start();
        $this->returned = include($this->dir . $this->filename);
        return ob_get_clean();
    }
}

// test.php
$view = new View;
$view->variables = array('test' => 'Hello World!');    
$template = __DIR__.'/test.tpl';

echo $view->render($template);

// var_dump($view->returned); // to see included template content

// Template: test.tpl
<p><?php echo $test; ?></p>

如果您真的想污染全局范围:

将变量合并到$GLOBALS

$GLOBALS += $vars;

代码语言:javascript
复制
function globalize($data) {  
  $GLOBALS += $data;
}

$vars = array('a' => 1, 'b' => 2);
globalize($vars);
echo $a; // prints 1

通过键名创建动态全局变量的foreach

代码语言:javascript
复制
foreach($array as $var_name => $var_value)
{
   global $$var_name;
   $$var_name = $var_value;
}

或者更好(为了避免冲突)直接添加到全局数组中。

代码语言:javascript
复制
foreach($array as $var_name => $var_value)
{
   $GLOBALS[$var_name] = $var_value;
}

是有效的,但它是邪恶的……

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25583740

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档