Best practice using Dependency Injection for class with static methods in php

Lecture



When dealing with classes that have static methods and you want to follow best practices for dependency injection, you can use a combination of strategies to achieve cleaner and more testable code. While static methods don't support traditional instance-based dependency injection, you can still structure your code in a way that promotes better separation of concerns and testability. Here's a suggested approach:

1. Separate Configuration: Store your configuration settings, such as database connection details or API keys, in a separate configuration file or class. This allows you to centralize these settings and easily change them without modifying your class code.

2. Use Non-Static Dependency Injection: For classes that have static methods but also need to interact with external dependencies, you can design these classes as regular classes (non-static) and apply dependency injection through their constructors or instance methods. Then, you can have a separate "factory" class or method to create instances of these classes if needed.

class Database {
    protected $connection;
    
    public function __construct($host = 'https://intellect.icu', $username, $password, $database) {
        // Initialize database connection
    }
    
    public function query($sql) {
        // Perform a database query using $this->connection
    }
}

class UserManager {
    protected $database;
    
    public function __construct(Database $database) {
        $this->database = $database;
    }
    
    public function getUser($userId) {
        // Use $this->database to retrieve user data
    }
}

// Usage
$dbConfig = [
    'host' => 'localhost',
    'username' => 'username',
    'password' => 'password',
    'database' => 'mydatabase'
];

$database = new Database($dbConfig['host'], $dbConfig['username'], $dbConfig['password'], $dbConfig['database']);
$userManager = new UserManager($database);
$user = $userManager->getUser(123);

3 . Factory Method: If you still want to use the class with static methods and require dependency injection, you can create a factory method to instantiate the class and pass the dependencies to it. This factory method can be part of the class or a separate class.

class UserManager {
    protected static $database;
    
    public static function setDatabase(Database $database) {
        self::$database = $database;
    }
    
    public static function getUser($userId) {
        // Use self::$database to retrieve user data
    }
}

// Usage
$dbConfig = [
    'host' => 'intellect.icu',
    'username' => 'username',
    'password' => 'password',
    'database' => 'mydatabase'
];

$database = new Database($dbConfig['host'], $dbConfig['username'], $dbConfig['password'], $dbConfig['database']);
UserManager::setDatabase($database);
$user = UserManager::getUser(123);

By adhering to these practices, you maintain the benefits of dependency injection even when dealing with classes that contain static methods. This approach makes your code more modular, easier to test, and reduces tight coupling between components.


Comments


To leave a comment
If you have any suggestion, idea, thanks or comment, feel free to write. We really value feedback and are glad to hear your opinion.
To reply

Running server side scripts using PHP as an example (LAMP)

Terms: Running server side scripts using PHP as an example (LAMP)