PHP数据库连接太多了

问题描述 投票:0回答:1

在我的logout.php端点我使用3个不同的类。这3个课程中的每一个都有:

private $conn;
private $table_name = "users";

// constructor with $db as database connection
public function __construct($db)
{
    $this->conn = $db;
}

这段代码是为了从端点连接到数据库,同时初始化类,如下所示:

// include needed files
include_once '../config/database.php';
include_once '../classes/user.php';
include_once '../classes/token.php';

// instantiate database and product object
$database = new Database();
$db = $database->getConnection();

// initialize object
$user = new user($db);
$token = new token($db);

在一些函数的这3个类中,我有时需要使用其他类,所以我再次在用户类的这个注销函数中再次包含database class

public function logout($receivedToken)
{
    include_once '../config/database.php';
    include_once '../classes/token.php';

    // instantiate database
    $database = new Database();
    $db = $database->getConnection();

    $token = new token($db);
    if($token->checkToken($receivedToken))

而且我不确定它是否是正确的方法我正在调试我的代码并尝试重构它以使其更有意义。我是否需要在用户类的logout函数中再次包含此db以便使用令牌类?或者也许我可以以某种方式使用这个连接,我通过__construct而不是include数据库反复初始化端点?

php database pdo
1个回答
2
投票

这是一个糟糕的方法,首先,你应该只在文件的顶部一次include

没有必要在logout方法中再次包含它,并且在我看来,方法体内部的includes通常是代码气味,除了在某些特定情况下。

其次,您正在与数据库建立两个连接,每次实例化Database类$database = new Database()并调用$database->getConnection()时,您正在建立与数据库的新连接。您应该只实例化一次数据库,然后将其注入需要数据库连接的类(通过构造函数或作为方法参数传递)。

最后但并非最不重要,你应该确保你的$database->getConnection()返回singleton

你可以这样做

<?php
    class Database
    {
        // specify your own database credentials
        private $host = "localhost";
        private $db_name = "obiezaca_db";
        private $username = "root";
        private $password = "";
        private $conn;
        // get the database connection

        public function getConnection()
        {
            if (!$this->conn) {
                try {
                    $this->conn = new PDO("mysql:host=" . $this->host . ";dbname=" . $this->db_name, $this->username, $this->password);
                    $this->conn->exec("set names utf8");
                } catch(PDOException $exception) {
                    // you shouldn't output exception error message in production
                    // because it can leak sensitive data such as DB username and password
                    echo "Database error";
                }
            }  
            return $this->conn;
        }
    }
?>

或者你可以像这样建立一个Singleton工厂

<?php
    class Database 
    {
        // specify your own database credentials
        private $host = "localhost";
        private $db_name = "obiezaca_db";
        private $username = "root";
        private $password = "";

        private $conn;

        private static $instance;

        private function __construct() {};

        private function __clone() {};

        public static getInstance() 
        {
            if (!static::$instance) {
                static::$instance = new Database(); 
            } 
            return static::$instance;
        }

        // get the database connection
        public function getConnection()
        {
            if (!$this->conn) {
                try {
                    $this->conn = new PDO("mysql:host=" . $this->host . ";dbname=" . $this->db_name, $this->username, $this->password);
                    $this->conn->exec("set names utf8");
                } catch(PDOException $exception) {
                    // you shouldn't output exception error message in production
                    // because it can leak sensitive data such as DB username and password
                    echo "Database error";
                }
            }  
            return $this->conn;
        }
    }

 $database = Database::getInstance();
 $connection = $database->getConnection();

在这种方法中,无论您在代码中多少次调用这些方法,您都将获得相同的DatabasePDO对象实例。

这样,您将确保始终与数据库建立一个连接,此外,您的数据库将是全局可访问的,因为它是静态访问的。

© www.soinside.com 2019 - 2024. All rights reserved.