如何正确使用PHP的依赖注入?

I'm very new at PHP. I have two classes: Database and RetrieveItem. Because RetrieveItem needs a connection, I've just been extending the Database class to use its constructor. Apparently this is wrong, because RetrieveItem is not a database?

Here is my current code:

class Database {
    public $host = '127.0.0.1';
    public $username = 'root';
    public $password = '';
    public $dbname = 'example';

 function __construct(){
    $this->connect = new PDO("mysql:host=$this->host;dbname=$this->dbname", $this->username, $this->password);
  }
}

class RetrieveItem extends Database {

    function retrieve_item(){
            $query = $this->connect->prepare("SELECT * FROM posts");
            $query->execute();
            $all_items = $query->fetchAll(PDO::FETCH_ASSOC);
            return $all_items;
    }
}

And on a separate page, to use this, I have:

include 'db.php';
$retrieve = new RetrieveItem();
print_r($retrieve->retrieve_item());

Rather than extend the class, how can I access the Database constructor in the cleanest possible way?

Any help or guidance would be much appreciated.

This amended code is still not working:

Argument 1 passed to RetrieveItem::__construct() must be an instance of Database, none given:

class Database {
    public $host = '127.0.0.1';
    public $username = 'root';
    public $password = '';
    public $dbname = 'example';

 function __construct(){
    $this->connect = new PDO("mysql:host=$this->host;dbname=$this->dbname", $this->username, $this->password);
  }
}

class RetrieveItem {
    private $_db;

    public function __construct(Database $database){
            $this->_db = $database;
    }

    public function retrieve_item(){
            $query = $this->connect->prepare("SELECT  * FROM posts");
            $query->execute();
            $all_items = $query->fetchAll(PDO::FETCH_ASSOC);
            return $all_items;
    }
}

In use:

include 'db.php';

$database = new Database();
$retrieve = new RetrieveItem($database);
print_r($retrieve->retrieve_item());

A dependency injection is so easy but it sounds complicated.

$class1 = new firstclass();
$class2 = new secondclass($class1); //This is a dependency injection.

class firstclass{
    private $var1;
    private $var2;

    public function __construct(){
        $this->var1 = "hello";
        $this->var2 = "world";
    }

    public function getvar1(){
        return $this->var1;
    } //imagine a second one like this for var2;
}

class secondclass{

    private $fc; //will hold first class object or the dependency.

    public function __construct($firstclassobject){
        $this->fc = $firstclassobject;
        echo $this->fc->getvar1(); //call dependency methods like this.
        echo $this->fc->getvar2();
    } //echoes helloworld
}

So you pretty much put an object of one class and asign it to a field in your other class.

for your edit

set this line in your database class at the top.

public connect; //add to dbclass

Then do this in your function

public function retrieve_item(){
    $connect = $this->db->connect; //added this
    $query = $connect->prepare("SELECT  * FROM posts"); //changed this
    $query->execute();
    $all_items = $query->fetchAll(PDO::FETCH_ASSOC);
    return $all_items;
}

As you said, with plain dependency injection

class RetrieveItem {

    private $_db;

    public function __construct(Database $db) {
        $this->_db = $db;
    }

}

For easier use, you can abstract the injection in container, or, at least, has one super class that recieves the injection.

class Database {
    public $host = '127.0.0.1';
    public $username = 'root';
    public $password = '';
    public $dbname = 'example';
    public $connect;

 function __construct(){
    $this->connect = new PDO("mysql:host=$this->host;dbname=$this->dbname", $this->username, $this->password);
  }
}

class RetrieveItem {
    private $connect;

    public function __construct(&$db){
        $this -> connect = $db -> connect;
    }

    function retrieve_item(){
            $query = $this->connect->prepare("SELECT * FROM posts");
            $query->execute();
            $all_items = $query->fetchAll(PDO::FETCH_ASSOC);
            return $all_items;
    }
}


// Usage
$db = new Database();
$retrieve_item = new RetrieveItem($db);

Here in Retrieve Item we tried to send the database object as a refereneced variable rather sending a copy of its, which happens to be a good way of passing connection to your operable classes