PHP OOP ~ Multiple Classes Require Same Class [dup

2019-09-16 08:32发布

问题:

This question already has an answer here:

  • Using my database class with other classes in my project 3 answers

I currently have multiple classes that all depend on one class, the Database class. Each class requires an instance of the Database class to function, and with that, I am a little concerned.

Before I convert all my procedural code to object-oriented code I need to figure this out. I Currently have one database connection for the entire program. However, from what I understand when I convert my code to OOP I will have multiple classes all with open database connections within the same program. (all of these classes will be included in the main program file).

How do I implement this correctly? I'm assuming having 5 open database connections within the same program is certainly not the correct way.

回答1:

You could share a database connection between several different objects by supplying it as an argument to the constructor, or you could create a singleton to serve the other classes with the database connection.

Passing the database connection to constructor

class Foo {

    private $database = null;

    public function __construct(&$database) {
        $this->database = $database;
    }
}
$connection = mysql_connect(..);
$bar = new Foo($connection);

Singleton

class DatabaseConnection {

    private static $instance = null;

    private function __construct() {
    }

    public static function &getInstance() {
        if (DatabaseConnection::$instance == null) {
            DatabaseConnection::$instance = new DatabaseConnection();
        }
        return DatabaseConnection::$instance;
    }
}

$mysql_query("...", DatabaseConnection::getInstance());

The & means passing by reference, so there would be only one instance of the database object even if it is used in several different files, classes or functions. See http://php.net/manual/en/language.references.pass.php for more information.



回答2:

If you have classes that depend on database abstraction then Dependency Injection is the way to go.

class PDOProvider extends PDO
{
    public function __construct()
    {
        try { 

          parent::__construct(...); 
          $this->setAttribute(....);

        } catch(PDOException $e){
            die($e->getMessage());
        }
    }
    // ...
}

class Users
{
    private $provider; 

    public function __construct(PDOProvider $provider) // <- Injecting class dependency
    {
       $this->provider = $provider;
    }

    public function insert(array $stuff)
    {
       try {

        $this->provider->prepare("INSERT ...");
        $this->provider->execute(array(..));

       } catch(PDOException $e){
          //...
       }
    }
}


回答3:

Jakobs advice on using Singleton + aggregation is sound advice. To that I'd add Doctrine ORM/DBAL, http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/tutorials/getting-started.html

Avoid coupling the singleton instance directly to your objects by using them inside the "Foo" class, but rather pass the singleton instance to the constructor. This way you have more decoupling and thus more freedom.