Implementing and Using ThinkPHP Container for Dependency Management
This article explains how to extend ThinkPHP's Container class with static get, getInstance, make, and magic methods, defines a bind array for aliases, modifies the entry script, and demonstrates retrieving Request instances to illustrate proper dependency injection in a PHP backend framework.
ThinkPHP's Container class provides static methods such as get() that retrieve instances by class name or alias while preserving a single created instance to avoid redundant instantiation.
The tutorial shows how to modify Container.php by adding the get() method implementation:
public static function get(string $abstract, array $vars = [], bool $newInstance = false) {
return static::getInstance()->make($abstract, $vars, $newInstance);
}Next, a getInstance() method and a static property $instance are introduced to store the container itself:
protected static $instance;
public static function getInstance() {
if (is_null(static::$instance)) {
static::$instance = new static;
}
return static::$instance;
}The make() method is then implemented to resolve a class, handle alias binding, reuse existing instances, and store newly created objects:
public function make(string $abstract, array $vars = [], bool $newInstance = false) {
if (isset($this->bind[$abstract])) {
$abstract = $this->bind[$abstract];
}
if (isset($this->instances[$abstract]) && !$newInstance) {
return $this->instances[$abstract];
}
$object = $this->invokeClass($abstract, $vars);
if (!$newInstance) {
$this->instances[$abstract] = $object;
}
return $object;
}A protected $bind array is added to map aliases to concrete classes:
protected $bind = [
'app' => App::class,
'config' => Config::class,
'request' => Request::class,
];The invokeClass() method simply creates a new instance of the given class (constructor arguments are passed via $vars):
public function invokeClass(string $class, array $vars = []) {
// $vars are constructor parameters
return new $class();
}The entry script index.php is updated to require the core base file, import the Request class, and retrieve the request instance through the container:
require __DIR__ . '/../core/base.php';
use think\Request;
$req = \think\Container::get('request');
var_dump($req instanceof Request);Outputting bool(true) confirms that the get() method works correctly.
Magic methods __get() and __set() are also added to allow direct property access to container services:
public function __get($abstract) {
return $this->make($abstract);
}
public function __set($abstract, $instance) {
if (isset($this->bind[$abstract])) {
$abstract = $this->bind[$abstract];
}
$this->instances[$abstract] = $instance;
}Finally, the container is tested in index.php:
$container = \think\Container::getInstance();
// Retrieve the request instance and output the object
var_dump($container->request);
$container->containerName = $container;
var_dump($container->containerName);The output object(think\Request) demonstrates successful dependency injection using the enhanced ThinkPHP container.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
php Courses
php中文网's platform for the latest courses and technical articles, helping PHP learners advance quickly.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
