我对__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解决方案?
答案 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);
}