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.

php Courses
php Courses
php Courses
Implementing and Using ThinkPHP Container for Dependency Management

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.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

BackendPHPdependency-injectionThinkPHP
php Courses
Written by

php Courses

php中文网's platform for the latest courses and technical articles, helping PHP learners advance quickly.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.