Up until now, I had a static method in my "Database" class:
public static function getInstance()
{
if (!isset(self::$instance))
self::$instance = new Database();
return self::$instance;
}
Where I call to a $this->db = Database::getInstance();
variable in every class __construct
. And keep my db connection open (I have more than one database to connect to).
And since my post on code review - I discovered "Dependency Injections". I'm trying to understand how DIs work. Specifically with Symfony, and how it can solve my problem.
This is my previous post: Symfony DI: Uncaught ArgumentCountError: Too few arguments to function App::__construct(), 0 passed in index.php on line 28 and exactly 1 expected
Where I understood that what the Symfony container does is basically define my classes (and "initialize" them) from the beginning of my code (index.php) and when I "inject" a class-object via __construct
, I wont get any errors for "missing variables", since my container knows which object it should inject + the object is already created, and does that for me: 'when I have a SystemUser class I "expect" a Database class injected'.
Meaning, I have to create an object in my index.php file, to inject a dependency. I cannot initialize every class that uses the Database class since there are too many.
I'll give a very simple example for using the database class more than once:
index.php
require_once 'vendor/autoload.php';
use TestingDI\App;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;
$containerBuilder = new ContainerBuilder();
$containerBuilder->register('database', '\TestingDI\Database');
$containerBuilder->register('system.user', '\TestingDI\SystemUser')
->addArgument(new Reference('database'));
$containerBuilder->register('controller', '\TestingDI\Controller')
->addArgument(new Reference('database'));
$containerBuilder->register('app', '\TestingDI\App')
->addArgument(new Reference('system.user'));
$database = $containerBuilder->get('database');
$systemUser = $containerBuilder->get('system.user');
$app = $containerBuilder->get('app');
App.php:
-
Gets the SystemUser class from the construct (thanks to the DI container).
-
Sets
$this->systemUser
variable obj - Which uses the Database class (again, thanks to DI container). -
And then calls a Controller class
This is the code:
namespace TestingDI;
use TestingDI\SystemUser;
class App {
public $systemUser;
public function __construct(SystemUser $systemUser)
{
$this->systemUser = $systemUser;
echo "im in app and i have system user with me <br>";
var_dump($this->systemUser);
$controller = new Potato();
}
}
SystemUser.php:
namespace TestingDI;
use TestingDI\Database;
class SystemUser {
public $db;
public function __construct( Database $database )
{
$this->db = $database;
echo $this->db->test . " <br>";
$this->db->test = 2;
echo $this->db->test . " <br>";
}
}
Database.php:
namespace TestingDI;
class Database {
public $pdo = "DATABASE: I'm a pdo instance <br>";
public $test = 1;
public function __construct()
{
echo "DATABASE: init construct database <br>";
}
public function hello()
{
echo "DATABASE: hello database <br>";
}
}
And a Potato class:
-
that needs the Database object (and i do not want to initialize potato , since i wont be using it on ever page on my app).
-
Has the customer class - that also needs to use the Database class - but do not want to initialize customers, since it's not gonna be in use in every page.
this is the code:
<?php
namespace TestingDI;
class Potato
{
public $db;
public function __construct( Database $db)
{
$customer = new Customer();
$this->db = $db;
echo "---------------------------------";
var_dump($db);
echo "---------------------------------";
}
}
How do I use the Database class from the container in new created objects? Or at least in a proper way, regarding my situation.
Aucun commentaire:
Enregistrer un commentaire