当前位置:首页 > PHP

php实现di

2026-02-28 13:10:49PHP

依赖注入(DI)实现方法

在PHP中实现依赖注入(Dependency Injection,DI)可以通过手动注入或使用容器两种方式完成。以下是具体实现方法:

手动依赖注入

通过构造函数或方法直接传递依赖对象,不依赖外部容器。

class DatabaseConnection {
    public function connect() {
        return "Database connected";
    }
}

class UserRepository {
    private $db;

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

    public function getUsers() {
        return $this->db->connect() . " -> Fetching users";
    }
}

// 手动注入
$db = new DatabaseConnection();
$userRepo = new UserRepository($db);
echo $userRepo->getUsers();

使用DI容器

通过容器管理依赖关系,自动解析和注入依赖项。以下是简易容器实现:

class Container {
    private $bindings = [];

    public function bind($abstract, $concrete) {
        $this->bindings[$abstract] = $concrete;
    }

    public function resolve($abstract) {
        if (isset($this->bindings[$abstract])) {
            $concrete = $this->bindings[$abstract];

            if (is_callable($concrete)) {
                return $concrete($this);
            }

            return $this->resolve($concrete);
        }

        $reflector = new ReflectionClass($abstract);
        $constructor = $reflector->getConstructor();

        if (is_null($constructor)) {
            return new $abstract;
        }

        $parameters = $constructor->getParameters();
        $dependencies = array_map(
            function($param) {
                return $this->resolve($param->getClass()->name);
            },
            $parameters
        );

        return $reflector->newInstanceArgs($dependencies);
    }
}

// 使用容器
$container = new Container();
$container->bind(DatabaseConnection::class, DatabaseConnection::class);
$userRepo = $container->resolve(UserRepository::class);
echo $userRepo->getUsers();

使用现有DI库

推荐使用成熟的DI库如PHP-DI或Symfony DependencyInjection组件:

// 使用PHP-DI示例
require_once 'vendor/autoload.php';

use DI\ContainerBuilder;

$builder = new ContainerBuilder();
$builder->addDefinitions([
    DatabaseConnection::class => DI\create(DatabaseConnection::class)
]);
$container = $builder->build();

$userRepo = $container->get(UserRepository::class);
echo $userRepo->getUsers();

接口绑定实践

通过接口绑定实现更松散的耦合:

php实现di

interface DatabaseInterface {
    public function connect();
}

class MySQLConnection implements DatabaseInterface {
    public function connect() {
        return "MySQL connected";
    }
}

// 容器配置
$container->bind(DatabaseInterface::class, MySQLConnection::class);

最佳实践建议

  • 优先使用接口而非具体类进行类型提示
  • 将容器配置与业务代码分离
  • 对于小型项目手动注入足够,大型项目建议使用成熟DI库
  • 避免服务定位器模式(直接从容器中解析依赖),应通过构造函数注入

标签: phpdi
分享给朋友:

相关文章

php实现文件上传

php实现文件上传

文件上传的基本实现 在PHP中实现文件上传需要使用$_FILES超全局数组处理上传的文件数据。表单必须设置enctype="multipart/form-data"属性,并采用POST方法提交。 创…

php实现文件下载

php实现文件下载

PHP实现文件下载的方法 通过PHP实现文件下载功能,可以采用多种方式,以下是几种常见的实现方法: 使用header()函数强制下载 设置HTTP头信息,强制浏览器下载文件而非直接打开: $fi…

php实现上传

php实现上传

PHP 文件上传实现 HTML 表单设置 创建一个包含文件上传字段的 HTML 表单,确保表单的 enctype 属性设置为 multipart/form-data,这是文件上传必需的设置。 <…

php 实现单链表

php 实现单链表

单链表的基本概念 单链表是一种线性数据结构,由节点组成,每个节点包含数据域和指向下一个节点的指针域。链表的头节点是访问整个链表的入口。 单链表的节点类实现 在PHP中,可以通过类来定义链表节…

php 线程实现

php 线程实现

PHP 线程实现方法 PHP 本身是单线程语言,但可以通过扩展或库实现多线程功能。以下是几种常见的实现方式: 使用 pthreads 扩展 pthreads 是一个 PHP 扩展,允许在 PHP 中…

php 无限分类的实现

php 无限分类的实现

无限分类的实现方法 无限分类通常用于构建树形结构数据,如商品分类、多级菜单等。以下是几种常见的实现方式: 邻接列表模型(Adjacency List) 邻接列表是最简单的实现方式,通过在每个节点中存…