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但我很想知道为什么会这样?

更新:

所以我弄乱了这个_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 也在 Applications 中声明。

4

1 回答 1

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()
  • 向Registy类添加has()了方法。

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

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

  • 您尚未在Applications类中声明$registry为成员变量。 否则代码会失败,因为它没有访问实际的成员变量(神奇的__set()方法!)

  • 此外,您的代码中有相当多的冗余(不是 DRY)。我希望这不是生产代码;)

于 2013-08-06T07:26:32.513 回答