我不太确定为什么会这样,或者如何正确解释它,但也许有人可以对此有所了解。
我有一个基于CodeIgniter / Opencart框架的CMS系统,它使用注册表,控制器和模块。我遇到过一个我以前将变量保存到注册表的场景:
$this->application_page = 'current/page';
但出于某种原因,我在应用程序中调用它:
echo empty($this->application_page)?'yes':'no';
//Returns Yes
但是..当我重新分配时:
echo empty($this->application_page)?'yes':'no';
//Returns Yes
$page = $this->application_page;
echo empty($page)?'yes':'no';
//Returns No
var_dump返回:
var_dump($this->application_page);
string 'current/page' (length=12)
我可以通过使用$page
轻松解决这个问题,但我很想知道为什么会发生这种情况?
更新
所以我搞砸了_isset
函数,但没有让它工作,可能是我的错误,可能不是..以下是它们如何一起工作:
class Registry {
private $data = array();
public function get($key){ return (isset($this->data[$key]) ? $this->data[$key] : NULL); }
public function set($key,$val){ $this->data[$key] = $val;
}
abstract class Controller {
protected $registry;
public function __construct($registry){ $this->registry = $registry; }
public function __get($key){ return $this->registry->get($key); }
public function __set($key,$value){ $this->registry->set($key, $value); }
}
class Applications {
private $registry;
function __construct($Registry){ $this->registry = $Registry; }
function __get($key){ return $this->registry->get($key); }
function __set($key,$val){ return $this->registry->set($key,$val); }
public function buildApplication(){
$this->application_page = 'current/page';
$application = new application($this->registry);
}
}
class Application extends Controller {
public function index(){
echo empty($this->application_page)?'yes':'no';
//Returns Yes
$page = $this->application_page;
echo empty($page)?'yes':'no';
//Returns No
}
}
希望这有帮助吗? 有一个错字,注册表的功能不是魔术方法。此外,还在应用程序中声明了$ registry。
答案 0 :(得分:4)
该类可能没有实现魔法__isset()方法,该方法是通过在无法访问的属性上调用isset()或empty()来触发的。
示例:
<?php
class Test {
private $a = '42';
public function __get($name) {
return $this->a;
}
}
$obj = new Test();
var_dump($obj->a); // string(2) "42"
var_dump(empty($obj->a)); // bool(true)
按如下方式(__isset())实施Live demo II方法将产生正确的结果:
public function __isset($name) {
if ($name == 'a') {
return true;
}
return false;
}
// ...
var_dump($obj->a); // string(2) "42"
var_dump(empty($obj->a)); // bool(false)
<小时/> 以下是实施__isset()方法的代码的新版本:http://ideone.com/rJekJV
更改日志:
__isset()
方法添加到 Controller 类,该类在内部调用Registry::has()
。将<{1}}方法添加到注册类。
[仅用于测试:对象初始化和运行has()
方法。]
有一个问题(在更新答案后):
您尚未在 Applications 类中将Application::index()
声明为成员变量。
代码失败,因为它不访问实际的成员变量(magic __set()方法!)
此外,您的代码中存在相当多的冗余(而不是DRY)。我希望这不是生产代码;)