【问题标题】:Pimple ArgumentCountError: Too few arguments to functionPimple ArgumentCountError:功能参数太少
【发布时间】:2018-02-08 18:32:49
【问题描述】:

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

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

这是我的“主”文件,我将其命名为 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 类的 UserModel 是一个有效的 UserModel 对象(很明显它打印出一个数组)

我错过了什么?有什么我没有解释的吗?

哦,这是 composer.json 文件

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

我创建了一个 gitHub 链接,因此可以签出并运行该项目,而无需复制所有内容 (https://github.com/gitKearney/pimple-example)

解决方案

问题是我在行中有一个额外的 new

$myUserService = new $container['UserService'];

太明显了,我看不到

【问题讨论】:

  • 将复制案例添加到 Github 的工作做得很好,顺便说一句。能够获取您的代码并运行它真的很有帮助。
  • 当然!有什么可以帮到你的

标签: php dependency-injection psr-4 pimple


【解决方案1】:

$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;

【讨论】:

  • 天啊!就是这么简单!我在 $myUserService = $container['UserService']; 前面多了一个“新”
【解决方案2】:

您使用依赖注入容器将自己从操作对象依赖的痛苦中解脱出来。没有必要创建一个新的UserService(如果它真的是一个服务)。在这种情况下,您只需在 $container 中定义一次,然后在需要时使用它。

因此,与其创建一个新的 UserService 对象并调用其方法 parseGet()(您在代码中所做的),您还可以执行以下操作:

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

当您定义如下内容时:

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

您是在告诉 Pimple 在您尝试访问 $container['UserService'] 后如何处理 UserService 的创建

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

这可能与您的问题Why use a closure for assignment instead of directly assigning a value to a key?有关

【讨论】:

  • 啊!谢谢!我给出的例子不是“现实世界”的例子。我遇到了问题,这个错误对我来说毫无意义。这行代码应该是 $myUserController = $container['UserController'];
  • 是的,它应该(或$myUserService = $container['UserService'] 更像你的例子)。
猜你喜欢
  • 2019-01-08
  • 2020-08-04
  • 1970-01-01
  • 1970-01-01
  • 2019-06-01
  • 1970-01-01
  • 2022-08-17
  • 2020-07-30
  • 2018-10-11
相关资源
最近更新 更多