【问题标题】:Is using the $GLOBALS variables frowned upon? [duplicate]是否不赞成使用 $GLOBALS 变量? [复制]
【发布时间】:2013-12-02 17:48:01
【问题描述】:

基本上,我有一个“用户”类,其中一部分是这样的:

class user{
    private $username;

    public function get_last_visit(){
        return $GLOBALS['db']->get(
            'users',
            'last_visit',
            'username' => $this->username
        );
    }
}

我需要从“用户”类中调用对象“db”的方法。使用上述方法是解决此问题的最佳方法吗?我听说有人说使用 $GLOBALS 变量是不好的做法。

【问题讨论】:

  • 是的,不赞成。

标签: php oop global


【解决方案1】:

您想了解的是Dependency Injection,它使您能够像这样将所需的对象注入到 User 对象的构造中。

# Your updated User class
class User {
    private $username;
    private $db

    public function __construct($db){
        $this->db = $db
    }

    public function get_last_visit(){
        return $this->db->get(
            'users',
            'last_visit',
            'username' => $this->username
        );
    }
}
# Instantiate your Database Wrapper
$db = new DatabaseWrapper();

# Instantiate your User object with the DatabaseWrapper injected
$john_doe = new User($db);

$john_doe->get_last_visit();

【讨论】:

  • 这会使它成为一个新对象,不是吗?使用我的 db 对象,我有一个“查询计数器”,每次执行查询时都会递增,但如果这是创建一个新对象,那么我将无法记录查询数量,因为有是两个独立的数据库对象。
  • 这确实会创建一个新的 DB 类实例。我们在这里遇到了一个不好的例子。您可能希望为您传递给您的用户类的构造的 DB 类创建一个单例。看看这个:stackoverflow.com/questions/130878/…
【解决方案2】:

由于范围问题,它不被接受。毫无疑问,正如您所经历的那样,函数和类中的变量不会直接与它们各自区域之外的任何东西交互。否则你会有变量在整个地方发生冲突。这就是为什么对象和方法通常正在取代过去的程序代码。当您必须显式传递数据时,跟踪程序中发生的事情要容易得多,而不是依赖各种$GLOBALS

我强烈建议您依赖注入您的数据库指针。这样您就不会一直重新创建连接,并且您的类和方法对于连接是如何形成的变得不可知。

class user{
    private $username;
    /** @var stdClass */
    protected $db;

    public function __construct($db) {
        $this->db = $db;
    }

    public function get_last_visit(){
        return $this->db->get(
            'users',
            'last_visit',
            'username' => $this->username
        );
    }
}
$user = new user($db);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-13
    • 2015-10-10
    • 2021-11-02
    • 2015-12-22
    • 2013-06-11
    • 1970-01-01
    • 2011-08-07
    相关资源
    最近更新 更多