Pimple ArgumentCountError: Too few arguments to function

Pimple ArgumentCountError: Too few arguments to function

我想了解依赖注入,理论上我明白了,但是,我想举个例子来帮助我。但是,我收到以下错误

PHP Fatal error:  Uncaught ArgumentCountError: Too few arguments to function Main\Services\UserService::__construct(), 0 passed
in ...

这是我的 "main" 文件,我将其命名为 index.php

<?php 
#index.php
require_once 'vendor/autoload.php';

use Main\Controllers\UserController;
use Main\Services\UserService;
use Main\Models\UserModel;
use Pimple\Container;

$container = new Container;
$container['UserModel'] = function($c) {
    return new UserModel();
};

$container['UserService'] = function ($c) {
    return new UserService($c['UserModel']);
};

$container['UserController'] = function ($c) {
    echo "creating a new UserController\n";

    $aUserService = $c['UserService'];
    return new UserController($aUserService);
};

$myUserService = new $container['UserService'];
$myResult = $myUserService->parseGet();
echo $myResult, PHP_EOL;

这是传递给服务的模型

<?php
# Models/UserModel.php
namespace Main\Models;

class UserModel
{
    private $record;

    public function getRecord()
    {
        return [
            'first_name' => 'Bob',
            'last_name'  => 'Jones',
            'email'      => 'bj@example.com',
            'date_joined' => '11-12-2014',
        ];
    }
}

而且,这是服务,它将模型作为构造函数参数

<?php
namespace Main\Services;

use Main\Models\UserModel;

class UserService
{
    private $userModel;

    public function __construct(UserModel $userModel)
    {
        echo "verifying that the userModel passed in was a valid UserModel\n";
        $this->userModel = $userModel;

         print_r($this->userModel->getRecord());
    }

    public function parseGet()
    {
        $retVal = $this->userModel->getRecord();

        return json_encode($retVal);
    }
}

因此,理论上,Pimple 应该能够实例化一个 UserService 对象。我什至验证了传递给 UserService class 的 UserModel 是一个有效的 UserModel 对象(很明显它打印出一个数组)

我错过了什么?有什么我没有考虑到的吗?

哦,这是 composer.json 文件

{
    "require": {
        "pimple/pimple": "~3.0"
    },
    "autoload": {
        "psr-4": {
            "Main\" : "./"
        }
    }
}

我制作了一个 gitHub link 这样就可以检出项目并 运行 而不必复制过去的所有内容 (https://github.com/gitKearney/pimple-example)

解决方案

问题是我在

行中有一个额外的 new
$myUserService = new $container['UserService'];

太明显了,我没看到

$container['UserService'] 已经 一个 UserService 对象。检查您的服务定义:

$container['UserService'] = function ($c) {
    return new UserService($c['UserModel']);
};

调用时将 $container['UserService'] 设置为 return new UserService($c['UserModel']),对吗?

你的代码基本上是:

$o1 = new UserService($c['UserModel']);
$o2 = new $o2;

您使用依赖项注入容器来摆脱操作对象依赖项的痛苦。没有必要创建一个新的 UserService如果它确实是一个服务)。在这种情况下,您只需在 $container 中定义一次,并在需要时使用它。

因此,与其创建一个新的 UserService 对象并调用其方法 parseGet()(您在代码中所做的),不如这样做:

$myResult = $container['UserService']->parseGet();

当您定义如下内容时:

$container['UserService'] = function ($c) {
    return new UserService($c['UserModel']);
};

您是在告诉 Pimple 在您尝试访问 $container['UserService']

后如何处理 UserService 的创建

这就是将依赖项定义为函数的原因。

这可能与您的问题有关