这个问题很头疼,控制器构造注入始终为单例

wangerwu

就不贴我的代码了,这里直接新安装webman测试。

// 安装webman框架
composer create-project workerman/webman
// 进入目录
cd webman
// 安装依赖注入 PHP-DI
composer require psr/container ^1.1.1 php-di/php-di ^6.3 doctrine/annotations ^1.14

config/app.php

return [
  省略其他……
  'controller_reuse' => false, // 控制器复用已关闭
]

config/container.php

$builder = new \DI\ContainerBuilder();
$builder->addDefinitions(config('dependence', []));
$builder->useAutowiring(true);
$builder->useAnnotations(true);
return $builder->build();

·
·
·

构造注入时 IndexController.php 代码如下

<?php

namespace app\controller;

use app\Test;

class IndexController
{
    public function __construct(Test $test)
    {
        var_dump($test->get());
    }

    public function index()
    {
    }
}

控制台输出(始终为单例):
string(15) "执行了构造"
string(9) "获取get"
string(9) "获取get"
string(9) "获取get"

当控制器方法注入时 IndexController.php代码如下

<?php

namespace app\controller;

use app\Test;

class IndexController
{
    public function index(Test $test)
    {
        var_dump($test->get());
    }
}

控制台输出(如我预期一致,每次新实例):
string(15) "执行了构造"
string(9) "获取get"
string(15) "执行了构造"
string(9) "获取get"
string(15) "执行了构造"
string(9) "获取get"

已做尝试:

升级PHP-DI为7(控制器构造注入依然为单例)

在dependence.php配置为非单例,控制器构造仍然为单例。

·
·

有知道怎么回事的老哥么?

控制器构造注入始终为单例。

控制器方法注入除了注入类,其他也都是单例。比如:A -> B、C、D

只有A是新实例,B、C、D均为单例。

464 1 0
1个回答

walkor 打赏

应该是PHP-DI内部复用了实例。写个脚本测试下类似如下代码

$builder = new \DI\ContainerBuilder();
$builder->addDefinitions(config('dependence', []));
$builder->useAutowiring(true);
$builder->useAnnotations(true);
$container = $builder->build();
$container->make($class);
$container->make($class);
  • wangerwu 26天前

    老哥,你给的这个测试脚本,放在控制器构造或方法中结果都是一样的,没有复用,正常的。

  • walkor 26天前
    <?php
    
    require __DIR__ . '/vendor/autoload.php';
    
    class IndexController
    {
        public function __construct(Test $test)
        {
            var_dump($test->get());
        }
    }
    
    class Test
    {
        public function __construct()
        {
            echo "Test __construct\n";
        }
        public function get()
        {
            return 'test';
        }
    }
    
    $builder = new \DI\ContainerBuilder();
    $builder->addDefinitions(config('dependence', []));
    $builder->useAutowiring(true);
    $builder->useAnnotations(true);
    $container = $builder->build();
    $container->make(IndexController::class);
    $container->make(IndexController::class);
    $container->make(IndexController::class);

    结果

     php .\container.php
    Test __construct
    string(4) "test"
    string(4) "test"
    string(4) "test"

    PHP-DI make的时候构造函数里依赖的类实例被复用了

  • walkor 26天前

    非常感谢

×
🔝