2013-08-06 91 views
5

我不太清楚为什么会发生这种情况,或者如何正确地解释它,但也许有人可以对此进行说明。变量为空直到重新分配

我有一个基于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即可轻松解决此问题,但我很想知道为什么会发生这种情况?

UPDATE:

所以我用_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

你是否100%确定你没有在你的var名错误,而测试呢? – NDM

+0

对不起延迟!是的,我确定,我在发帖前加倍检查了大约5次=) – Corey

+0

@Corey请看我更新的答案。 – ComFreek

回答

4

类可能没有实现神奇__isset()方法是通过在人迹罕至的属性调用isset()empty()触发。


实施例:

Live demo I

<?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) 


这里是一个新v你的代码的版为实现 __isset()方法: http://ideone.com/rJekJV

更改日志:

  • 新增__isset()方法控制器类内部调用Registry::has()
  • 添加has()方法到注册类。

  • [仅限测试:对象初始化和运行Application::index()方法。]

有一个问题(更新你的答案后):

  • 您还没有宣布$registry作为应用类的成员变量。
    代码,否则失败,因为它不访问实际的成员变量(魔术__set()方法!)

  • 此外,您在代码中有相当长的一段冗余(未干)。我希望这不是生产代码;)

+0

对不起,我的文章中出现了一些错字:__set&__get实际上已被设置并获得。应用程序中还有$注册表集。你建议摆脱注册表中的“数据”变量,并使用__isset。这部分是从opencart框架中复制的 – Corey

+0

@Corey我已经更新了我的答案。如果你想摆脱'Registry :: $ data',你还想要保存注册表数据吗?我的建议是:使用'__get(),__set(),__isset()'或类似'get(),set(),has()'。 – ComFreek

+0

美丽!现在一切正常!谢谢你的帮助!!! – Corey