0

我试图找到一种方法将所有 php 应用程序数据保存在一个地方。比如get和post参数、页面标题、分页结果等,避免使用全局变量。

将所有数据和控制器之间的交换保留在以下对象中是个好主意吗?

class container {

protected static $_instance;
protected $_instance_class;

public static function instance($instance_name = 'default')
{
    $c = __CLASS__;

    if ( ! isset($c::$_instance[$instance_name]))
    {
        $c::$_instance[$instance_name] = new $c();
        $c::$_instance[$instance_name]->_instance_class = $instance_name;
    }
    return $c::$_instance[$instance_name];
}

public function set($key, $val)
{
    // someting like $this->$key = $val;
}

public function get($key)
{
    // someting like retrun $this->$key;
}

}

然后,例如在模型中

container::instance('messages')->set('error', 'some error');

并在控制器或视图中

container::instance('messages')->get('error');

或者有没有其他方法可以让数据从应用程序的任何地方都可以访问?

谢谢!

4

3 回答 3

1

您所谈论的内容称为注册表模式(以及关于它的另一篇好文章)。虽然它有一些缺点(例如,为了测试从 Registry 获取一些数据的方法,我们也必须模拟这个 Registry),但它肯定比使用全局变量或 Singletons 更好。

事实上,在 Zend Framework 1 中,这种模式是按字面意思实现的:

// setting a value (usually done in Bootstrap)
Zend_Registry::set('index', $value);

// getting a value (usually in actions and/or models)
$value = Zend_Registry::get('index');

为了说明这种方法可能有什么问题,让我们分析以下内容:

class FooController extends Zend_Controller_Action {
    public function barAction() {
        $baz = Zend_Registry::get('baz');
        $model = new Some_Model($baz); 
        ...
    }
}

问题很简单:$baz这里的东西是什么?它是一个对象吗?还是数组?还是其他一些野兽,例如功能或资源?您必须在这里依赖注释,这通常不是一件好事——除非您使用的是琐碎和常见的对象(如查询参数或数据库资源对象)。

于 2012-09-13T20:00:58.073 回答
0

对于这种性质的事物,对静态类进行硬编码引用的问题在于,您正在创建对这些静态类的紧密依赖。如果您决定将来更改“全局”属性的来源,那么您的应用程序中就会出现对该来源的引用。

如果您想要一个有点全局的属性实体,一个更好的方法是创建一些您将实例化的东西,并提供一个适合您的应用程序需要的接口。为了论证起见,我们称这个接口GlobalConfigurationProvider。然后,您的应用程序代码可能会期望(并依赖于)一些GlobalConfigurationProvider. 现在,如果您将来更改实现配置的方式,您只需要担心新元素 - 的新实例GlobalConfigurationProvider,而不是您引用配置提供程序的所有类、视图等。

于 2012-09-13T19:58:02.863 回答
0

不要使用全局容器类,而是考虑编程 OO 并将方法和变量放在一个类中。

在您的错误示例中,错误属于一个类,应该保留在那里。

对您的类的引用可以由全局注册表保存,或者更好的是,由 IoC 容器保存。

于 2012-09-13T20:04:04.070 回答