代码之家  ›  专栏  ›  技术社区  ›  Imnotapotato

symfony di:uncaught argumentcounterror:函数app的参数太少::\uuu construct(),在第28行的index.php中传递了0,应为1。

  •  -1
  • Imnotapotato  · 技术社区  · 6 年前

    我正在尝试实现symfonys依赖注入容器。

    我设置了2个容器,一个用于数据库,一个用于系统用户。

    我在用“ addArgument() “两者兼而有之 App 类和 SystemUser 类,推到 应用程序 甲类 系统用户 对象,以及 系统用户 甲类 Database 对象。

    索引:

    require_once 'vendor/autoload.php';
    
    use TestingDI\App;
    use Symfony\Component\DependencyInjection\ContainerBuilder;
    use Symfony\Component\DependencyInjection\Reference;
    
    $containerBuilder = new ContainerBuilder();
    $containerBuilder->register('database', '\TestingDI\Database');
    
    $containerBuilder->register('system.user', '\TestingDI\SystemUser')
                     ->addArgument(new Reference('database'));
    
    $containerBuilder->register('app', '\TestingDI\App')
                     ->addArgument(new Reference('system.user'));
    
    
    $database       = $containerBuilder->get('database');
    $systemUser     = $containerBuilder->get('system.user');
    $app            = $containerBuilder->get('app');
    
    # Initialize App class
    $app = new App();
    

    App.php:

    <?php 
    
    namespace TestingDI;
    
    use TestingDI\SystemUser; 
    
    
    class App {
    
        public $systemUser; 
    
        public function __construct(SystemUser $systemUser)
        {
            var_dump($systemUser);
        }
    }
    

    我确实看到了我的var_dump结果和对象,但是继续得到这个错误:

    php致命错误:未捕获的argumentcounterror:函数testingdi\app::u construct()的参数太少,在第28行中传入了/www/potato/symfony di/index.php,在/www/potato/symfony di/testingdi/app中正好需要1个参数。php:12

    堆栈跟踪:

    0/www/potato/symfony di/index.php(28):testingdi\app->uu construct()

    1 {主} 在第12行插入/www/potato/symfony di/testingdi/app.php

    这些是我的其他课程:

    系统用户

    <?php 
    namespace TestingDI;
    
    use TestingDI\Database;
    
    class SystemUser {
    
        public $db; 
    
        public function __construct( Database $database )
        {
            $this->db = $database;
        }
    }
    

    数据库,PHP

    <?php 
    namespace TestingDI;
    
    class Database {
    
        public function __construct()
        {
    
        }
    }
    
    1 回复  |  直到 6 年前
        1
  •  3
  •   yivi SilverLink    6 年前

    对于依赖注入是什么以及如何使用它,似乎有一个基本的误解。

    由于您使用依赖容器来构建应用程序的不同部分,因此应该获取这些对象 从容器中 ,而不是直接实例化它们。

    而且,如果您要直接实例化它们(例如 new App() )你需要遵守常规的语言规则。在这种情况下,构造函数的签名:

    public function __construct(SystemUser $systemUser)
    

    如果在不传递构造函数的情况下调用它, SystemUser 类,它将失败,就像其他方法/函数失败一样,如果您以不符合其签名的方式调用它。

    当你这么做的时候

    $app            = $containerBuilder->get('app');
    

    你的应用程序已经“初始化”,你不需要调用 new 完全。

    这样做:

    $containerBuilder = new ContainerBuilder();
    $containerBuilder->register('database', '\TestingDI\Database');
    
    $containerBuilder->register('system.user', '\TestingDI\SystemUser')
                     ->addArgument(new Reference('database'));
    
    $containerBuilder->register('app', '\TestingDI\App')
                     ->addArgument(new Reference('system.user'));
    
    
    $database       = $containerBuilder->get('database');
    $systemUser     = $containerBuilder->get('system.user');
    $app            = $containerBuilder->get('app');
    

    你做的相当于:

    $database   = new Database();
    $systemUser = new SystemUser($database);
    $app        = new App($systemUser);
    

    只有你让DI容器为你做这些工作。哪一个当然,考虑到如何 冗长的 您的容器定义是,似乎有点无意义。

    但是你可以让 autowiring 为您进行大部分的重物提升,并执行以下操作:

    $container = new ContainerBuilder();
    $container->autowire( Database::class );
    $container->autowire( SystemUser::class );
    $container->autowire( App::class )
              ->setPublic( true );
    
    $container->compile();
    
    // this will get you an application instance with all the dependencies
    // resolved and injected in the class.
    $app = $container->get( App::class );
    

    我现在注意到你已经有了类似的问题 trying a different DI library 现在我意识到整个问题都是关于一个关于DI容器处理什么问题的简单误解。

    推荐文章