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

I need a PHP object in global scope. How do I do that, or is there a better way?

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

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

每个页面内容 class 都是从 BasePage class 扩展而来的。因此,例如 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" class 的实例创建的。几乎每个页面都会引用此用户对象,Index.php、page.php 和 home.php。到目前为止发生的事情是我在其他 class 中创建了用户 class 的实例。这可行,但通常会导致多次调用数据库并创建多个用户对象。我认为最好的方法是使用户 class 成为单例 class,但我应该在哪里创建该单例对象。如果我在 base.php 中创建实例,home.php 会引用它,但 page.php 和 index.php 不会。如果我在 index.php 中创建实例,则没有其他页面可以访问它,除非我将它传递给每个 class - 这会变得混乱。 (我知道,我试过了)

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

谁能给点建议?我应该如何创建我的用户对象?

谢谢

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

一个非常简单的应用程序结构的更好方法是为您的应用程序创建某种主 class 并将您的组件 classes 作为属性分配给这个主 class .这已经是一个不错的小依赖注入的一半了。

关于单例为什么不好的一些小文章:

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

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