在类中使用全局变量的替代方法


Alternative to using a global variable in a class?

我已经开始学习如何使用OOP,并创建了一个用户授权类来检查用户是否存在等。 目前,我使用全局变量$dbh连接到数据库,这是一个PDO连接。我听说以这种方式使用全局变量不是好的做法,但不确定如何改进它,我是否会在连接到数据库时将$dbh变量传递到需要它的方法中,为什么这不被认为是好的做法?

这是我正在使用的一些代码:

调用程序中包含的数据库PDO连接:

//test the connection
    try{
        //connect to the database
        $dbh = new PDO("mysql:host=localhost;dbname=oopforum","root", "usbw");
    //if there is an error catch it here
    } catch( PDOException $e ) {
        //display the error
        echo $e->getMessage();
    }

需要数据库连接的类:

class Auth{
        private $dbh;
        function __construct(){
            global $dbh;
            $this->dbh = $dbh;
        }
        function validateLogin($username, $password){
            // create query (placing inside if statement for error handling)
            if($stmt = $this->dbh->prepare("SELECT * FROM oopforumusers WHERE username = ? AND password = ?")){
                $stmt->bind_param(1, $username);
                $stmt->bind_param(2, $password);
                $stmt->execute();

                // Check rows returned
                $numrows = $stmt->rowCount();
                //if there is a match continue
                if( $numrows > 0 ){
                    $stmt->close();
                    return TRUE;
                }else{
                    $stmt->close();
                    return FALSE;
                }
            }else{
                die('ERROR: Could not prepare statement');
            }
        }

        function checkLoginStatus(){
            if(isset($_SESSION['loggedin'])){
                return TRUE;
            }else{
                return FALSE;
            }
        }
        function logout(){
            session_destroy();
            session_start();
        }
    }

您应该将 PDO 连接传递给构造函数:

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

该连接称为类的依赖项,因为显然您的类需要它才能执行其功能。良好做法要求你的类应该明确说明这种依赖关系的存在;这是通过使其成为必需的构造函数参数来实现的。

如果改为从全局变量中提取依赖项,则会产生几个问题:

  • 对于类的用户来说,根本不清楚首先存在依赖关系
  • 您的类现在耦合到全局变量,这意味着在不破坏程序的情况下无法删除或重命名该变量
  • 您已经为"远距离操作"创建了前提条件:修改全局变量的值会导致应用程序的另一个(看似不相关的)部分更改行为

你可以简单地把它传递给构造函数。

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

创建对象时,您可以执行以下操作:

$obj = new Class($dbh);

通过构造函数传入数据库对象。 PHP 的对象模型意味着 = 创建对对象同一实例的新引用。

class ThingThatDependsOnDatabase
{
    private $db = NULL;
    public function __construct (PDO $db)
    {
        $this -> db = $db;
    }
    public function selectSomething ($id)
    {
        $sql = 'SELECT * FROM table WHERE id = ?;'
        $this -> db -> prepare ($sql);
        // And so on
    }
}

这是一个称为依赖注入的模式示例,因为您的类所依赖的东西是通过方法(setter、构造函数等)注入的。