ZenaMiSpava
ZenaMiSpava

Reputation: 3

PHP Dependency injection for sub classes

I'm new to php oop and i'm trying to learn it in a right way so i have two questions about the code below:

  1. When I create the objects Circle and Square I am passing Database object through the constructor for both Circle and Square. By doing so, am I creating and using one Database object in memory or two Database objects? I'm asking this because when I print_r array containing these objects i'm getting this for both:

    [connection:Database:private] => Resource id #4

  2. Is this a good practise for this particular case from a dependency injection perspective?

code:

<?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);

?>

Upvotes: 0

Views: 76

Answers (1)

Mike Brant
Mike Brant

Reputation: 71384

By default in PHP, an object passed in as parameter to function will be passed by reference. If you create a single Database instance and pass to both classes, you will only be working with a single instance (which in most application use cases is desirable).

As a side note, you should probably put constructor in your GeoShape class to set passed DB object to local property. Right now, you are duplicating this code in each concrete class. You are also defining $db as private in the abstract class, which means inheriting classes cannot access this property. This should likely be protected not private.

Also, if you are trying to learn the "right way" to do things, you should understand very clearly that using mysql_* methods IS NOT the "right way". These are deprecated methods (see the big read warning in PHP docs).

Upvotes: 1

Related Questions