我需要一个全局范围的PHP对象。我该怎么做,还是有更好的方法?

时间:2015-03-24 15:14:53

标签: php class oop globals

我正在尝试创建我的第一个面向对象的Web应用程序,并且有一个关于如何全局引用对象的问题。不确定是否有必要,但这里有一些背景知识。该应用是一个单页应用。

Index.php创建“Page”类的新实例。此实例检查url参数(page = ???),然后检查是否存在适当的内容类并调用其中的函数。如果该页面类不存在,则调用另一个404类并显示该类。

每个页面内容类都是从BasePage类扩展而来的。因此,例如index.php?page=Home可以像这样工作

+---------+                              +----------+
|         | creates instance of Page.php |          |
|index.php|----------------------------->| page.php |  
|         |                              |          |
+---------+     +----------+             +----------+
                |          |            /
                | base.php |           /
                |          |          / "Page" loads the relevant class
                +----------+         /  and calls a function within it
 home.php                  |       |/_
 extends base.php       +----------+
                        |          |
                        | home.php |
                        |          |
                        +----------+

希望到目前为止这是有道理的。我现在遇到的问题是我需要一个“User”对象,它是从“User”类的实例创建的。几乎每个页面都会引用此User对象,Index.php,page.php和home.php。到目前为止,我已经在每个其他类中创建了User类的实例。这有效但通常会导致对数据库的多次调用以及正在创建的多个用户对象。我认为最好的方法是使User类成为单例类,但是在哪里创建该单例对象。如果我在base.php中创建实例,home.php会引用它,但是page.php和index.php没有。如果我在index.php中创建实例,除非我将它传递给每个类 - 否则其他页面都无法访问它 - 这会变得混乱。 (我知道,我已经尝试过了。)

所以我的问题是,如何创建每个页面都可以访问的单例对象?我认为把它放在全球范围会有所帮助,但是a)我不知道该怎么做以及b)我已经阅读了很多关于为什么全局变量是坏事的文章。

有人可以提供任何建议吗?我该如何创建我的User对象?

谢谢

2 个答案:

答案 0 :(得分:2)

你要找的是一个单身人士。但Singleton模式被认为是非常糟糕的做法,应该不惜一切代价避免。您应该尽量避免任何需要您拥有全局内容的解决方案。

更简单的应用程序结构的更好方法是为您的应用程序创建某种主类,并将组件类作为属性分配给此主类。这已经是一个很好的小依赖注入的一半。

关于为什么单身人士不好的一些小文章:

答案 1 :(得分:1)

如果您选择尝试实施单例,这将是一个如何确保您的用户始终相同的示例:

class User {
    private static $instance = null;
    private $name;
    public function __construct($name) {
        $this->name = $name;
    }
    public static function get($name) {
        if (self::$instance === null) self::$instance = new self($name);
        return self::$instance;
    }
    public function sayHello() {
        echo 'Hello my name is '.$this->name;
    }
}

$user = User::get('Bob');
$user->sayHello(); // Hello my name is Bob

请注意,通过混合静态类和动态实例,这种做法容易出错,肆虐和讨厌。

如果你想了解依赖注入,pimple是我对它的介绍,通过复制他们的代码,我能够创建更加可靠的代码;无论您在何处访问它们,都可以使用相关的良好依赖关系创建可访问的对象。

这种容器的原理是定义你的对象然后检索它们,只构造那些必要的。假设你正在使用疙瘩:

$cnt = new Pimple();
$cnt['page'] = function($c) { 
// the class pimple passes the container itself to the functions you define
    return new page($c['session']); 
// defines the page key to return a new page
};
$cnt['session'] = function() {
    return new session();
};
$page = $cnt['page']; 
// constructs the session because it is called to construct the page