我刚刚开始我的OOP之旅 - 我现在正在尝试推出自己的MVC - 纯粹是出于学习目的。我正在编写Apress PHP-Objects模式实践手册中的教程。我使用私有__construct / __克隆技术创建了一个注册表单例对象:
class Registry
{
private static $instance;
private $values = array();
private function __construct(){}
private function __clone(){}
public static function getInstance(){
if( !isset( self::$instance ) ){
self::$instance = new Registry();
}
return self::$instance;
}
public function get( $key ) {
if ( isset( $this->values[$key] ) ) {
return $this->values[$key];
}
return null;
}
public function set( $key, $val ) {
$this->values[$key] = $val;
}
}
我直接获得了这个对象的实例,例如:
Registry::getInstance();
然而,(遵循教程中的语法) - 如果我尝试使用' - >'访问公共方法方法 - 例如:
Registry->setVal('page',$page);
我得到一个解析错误。我只能使用范围解析运算符访问这些方法 - 即'::'。
我假设这是因为对象包装器还没有实例化 - 但我只是想用你们来验证/讨论这个问题......
答案 0 :(得分:6)
Registry::getInstance()
返回类Registry
的一个(实际上是唯一的)实例。它具有与new Registry()
相同的返回值,只是整个应用程序中只能有一个实例。这些是您访问这些方法的可能性:
// #1
$registry = Registry::getInstance();
$registry->set($key, $value);
// #2
Registry::getInstance()->set($key, $value);
另一个技巧:
将get()
和set()
映射到他们的魔术方法。
public function __set($key, $value)
{
return $this->set($key, $value);
}
public function __get($key)
{
return $this->get($key);
}
因此,您可以使用Registry::getInstance()->set($key, $value);
或Registry::getInstance()->$key = $value;
答案 1 :(得分:1)
你需要在一个实例上调用setVal(),而不是类本身,所以你可以这样做:
Registry::getInstance()->set('page', $page);
答案 2 :(得分:0)
另一种方法是将对象创建放在类中,而不是在每次使用时引用它:
public static function get( $key ) {
$instance = self::getInstance();
if ( isset( $instance->values[$key] ) ) {
return $instance->values[$key];
}
return null;
}
只用Registry::set('page', $page);
这样你就可以在使用它时得到更好的代码,即使单例仍然应该被视为警告标志(如果你搜索,已经有很多关于堆栈溢出的原因的好线程。)