0

我对 __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->user 和 $this->email 之类的东西,但这将是一个混乱且不直观的解决方案。我很想找到一种方法,可以在使用未定义变量时直接引用变量而不会让 PHP 抛出错误。

想法?有没有一种干净的方法可以做到这一点,还是我被迫求助于骇人听闻的解决方案?

4

2 回答 2

2

编辑我的答案。有点“破解”但潜在的解决方案。可能希望将 error_handler “重置”为更通用的功能。

视图.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);
?>

文件名.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.

于 2010-04-19T16:54:17.057 回答
0

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

function display() {
    extract($this->varArray);
    include($this->filename);
}
于 2010-04-19T16:49:40.813 回答