PHP:如何为局部函数变量实现类似__get的方法

时间:2010-04-19 16:44:23

标签: php php-5.3

我对__get()并不陌生,过去曾用它来制作一些非常方便的库。但是,我面临一个新的挑战(PHP 5.3,这个问题的缩写和简化我的代码):

<?php
namespace test;

class View {
    function __construct($filename, $varArray) {
        $this->filename = $filename;
        $this->varArray = $varArray;
    }

    function display() {
        include($this->filename);
    }

    function __get($varName) {
        if (isset($this->varArray[$varName]))
            return $this->varArray[$varName];
        return "?? $varname ??";
    }
}

?>

上面是一个非常非常简化的加载视图的系统。此代码将调用视图并显示它:

<?php

require_once("View.php");

use test\View;

$view = new View("views/myview.php", array("user" => "Tom"));
$view->display();

?>

我对此代码的目标是允许视图“myview.php”包含这样的代码:

<p>
    Hello <?php echo $user; ?>!  Your E-mail is <?php echo $email; ?>
</p>

并且,与上面的代码一起使用,这将输出“Hello Tom!你的电子邮件是??电子邮件??”

但是,这不起作用。视图包含在类方法中,因此当它引用$ user和$ email时,它正在查找本地函数变量 - 而不是属于View类的变量。因此,__get永远不会被触发。

我可以将我的所有视图变量更改为$ this-&gt; user和$ this-&gt; email,但这将是一个混乱且不直观的解决方案。我很想找到一种方法,我可以直接引用变量而不使用PHP在使用未定义的变量时抛出错误。

思考?有没有干净的方法来做到这一点,还是我被迫采用hacky解决方案?

2 个答案:

答案 0 :(得分:2)

编辑我的答案。升技术是一种“黑客攻击”,但却是一种潜在的解决方案。可能希望将error_handler“重置”为更通用的功能。

view.php

<?php
error_reporting(E_ALL);
ini_set("display_errors", 0);
class View {
    function display($file, $values) {        
        set_error_handler(array($this, '__get'), E_NOTICE);        
        extract($values);
        include($file);
    }

    function __get($vaule)
    {
        echo '<i>Unknown</i>';
    }
}

$View = new View;
$values = array('user' => 'Tom',
               'email' => 'email@host.com');

$View->display('/filename.php', $values);
?>

filename.php

Hello <?php echo $user; ?>, your email is <?php echo $email; ?> and your are <?php echo $age; ?> years old.

输出

Hello Tom, your email is email@host.com and your are 未知 years old.

答案 1 :(得分:0)

您可以使用extract将所有变量拉入本地范围:

function display() {
    extract($this->varArray);
    include($this->filename);
}