用于子类的PHP依赖项注入


PHP Dependency injection for sub classes

我是php oop的新手,我正在努力以正确的方式学习它,所以我对下面的代码有两个问题:

  1. 当我创建对象Circle和Square时,我正在通过Circle和Square的构造函数传递Database对象。通过这样做,我是在内存中创建和使用一个数据库对象还是两个数据库对象?我之所以问这个问题,是因为当我打印包含这些对象的数组时,我得到了这两个对象的答案:

    [连接:数据库:私有]=>资源id#4

  2. 从依赖注入的角度来看,这对于这个特定的案例来说是一个好的实践吗?

代码:

<?php
class Database{
    public $server = "localhost";
    private $user = "root";
    private $pass = "mysql";
    private $db = "ao";
    private $connection;
    function __construct(){
        $this->openConnection();
    }
    public function openConnection(){
        $this->connection = mysql_connect($this->server, $this->user, $this->pass);
        if(!$this->connection){
            die("Could not connect: " . mysql_error());
        }
        else{
            $db = mysql_select_db($this->db, $this->connection);
            if(!$db){
                die("Could not connect: " . mysql_error());
            }
        }
    }
    public function closeConnection(){
        if (isset($this->connection)){
            mysql_close($this->connection);
            unset($this->connection);
        }
    }
    public function query($sql){
        $result = mysql_query($sql, $this->connection);
        $this->confirmQuery($result);
        return $result;
    }
    public function fetchAssoc($result){
        return mysql_fetch_assoc($result);
    }
    public function numRows($result){
        return mysql_num_rows($result);
    }
    private function confirmQuery($result){
        if(!$result){
            die("Query failed: " . mysql_error());
        }
    }
}
$database = new Database;
?>
<?php
    include("db.class.php");
//////////////////////////////////////////////////////
    abstract class GeoShape{
        private $db;
        abstract public function area();
    }
//////////////////////////////////////////////////////
    class Circle extends GeoShape{
        private $r = 5;

        public function __construct(Database $db){
            $this->db = $db;
        }
        public function area(){
            return $this->r * $this->r * 3.14;
        }
    ::
//////////////////////////////////////////////////////////
    class Square extends GeoShape{
        private $s = 5;

        public function __construct(Database $db){
            $this->db = $db;
        }
        public function area(){
            return $this->s * $this->s;
        }
    }
    $objects = array(new Circle($database), new Square($database));
    foreach ($objects as $object){
        echo "Area of the " . get_class($object) . ": " . $object->area() . "<br>";
    }
///////////////////////////////////////////////////////////////
    echo "<pre>";
    print_r($objects);
?>

在PHP中,默认情况下,作为参数传递给函数的对象将通过引用传递。如果创建一个数据库实例并将其传递给两个类,则只能使用一个实例(在大多数应用程序用例中,这是可取的)。

附带说明一下,您可能应该在GeoShape类中放置构造函数,以便将传递的DB对象设置为本地属性。现在,您正在每个具体类中复制这些代码。您还在抽象类中将$db定义为private,这意味着继承类不能访问此属性。这可能应该受到保护,而不是私人的。

此外,如果你正在努力学习"正确的做事方式",你应该非常清楚地明白,使用mysql_*方法不是"正确的方式"。这些都是不推荐使用的方法(请参阅PHP文档中的big read警告)。