CodeIgniter 4:控制器构造函数中的参数太少“错误

CodeIgniter 4: Too few arguments to function" error in controller constructor

提问人:Rk Bishnoi 提问时间:9/3/2023 更新时间:9/15/2023 访问量:168

问:

我在我的 CodeIgniter 项目中遇到了一个问题,在我的一个控制器的构造函数中出现了“参数太少而无法运行”错误。我不确定为什么会发生此错误,我需要帮助解决它。

错误信息:

函数 App\Controllers\RestAPI\V1\OTP\OTPController::__construct() 的参数太少,0 传入...

Controller 构造函数:

public function __construct(JWTService $jwtService, UserModel $userModel, ReferralCodeModel $referralCodeModel, ReferralHistoryModel $referralHistoryModel)
{
    $this->jwtService = $jwtService;
    $this->userModel = $userModel;
    $this->referralCodeModel = $referralCodeModel;
    $this->referralHistoryModel = $referralHistoryModel;
}

我检查了什么:

  1. 我已经验证了依赖项(JWTService、UserModel、ReferralCodeModel、ReferralHistoryModel)在我的 CodeIgniter 项目中是否正确配置。
  2. 我已经检查了我的CodeIgniter配置文件(app/Config/Services.php和app/Config/Autoload.php)以确保服务和模型已注册。
  3. 我已确保我的配置文件中没有拼写错误或命名空间问题。
  4. 我已经运行了composer dump-autoload来重新生成自动加载器文件。

**请求帮助: ** 我将不胜感激有关如何解决此错误并将所需的依赖项正确注入我的控制器的任何指导。如果你有使用 CodeIgniter 依赖注入系统的经验,并且能够深入了解为什么会发生这个错误,请分享你的专业知识。谢谢!

php codeigniter 依赖注入 构造函数 自动加载

评论


答:

0赞 Ronin-0822 9/4/2023 #1

错误表明,构造函数没有收到必要的四个中的任何一个。它还应该告诉您在代码中尝试实例化 OTPController 的位置。0 passed in…

你能给我们看一下整个错误消息吗?

在代码的某个地方,你会有这样的内容:

模型和库的依赖注入:

//instantiating the model somewhere in your code
$model = new model();

//and then pass it to the OTPModel
$OTPModel = new OTPModel($model)

//OTPModel class:

class OTPModel {

    public function __construct($model){

          $this->model = $model;

    }
}

对于控制器:

在 __construct() 中加载模型,而不是将它们作为参数传递:

class OTPController extends BaseAPIController
    {

        public function __construct()
        {
            $this->userModel = new UserModel();
            ...
        }

更新:

使用 Codeigniter 的服务

或者使用 Codeigniter 的服务功能来获得依赖注入的好处。查看 CI 的文档,在“Codeigniter 4 Overview->Services”下,看看是否有帮助。

看看这个链接: https://www.patreon.com/posts/services-in-4-20830710

服务是项目中的依赖项。使用服务,而不仅仅是在控制器中创建一个新实例,它有三个主要好处:

  1. 允许您始终获取相同的实例,无论您调用该服务多少次。
  1. 您可以在一个地方设置服务的依赖项。
  1. 如果您需要将服务换成共享相同接口的另一个类,则可以在 Service 文件中更改该类,并且现在在应用程序中可能使用过该类的所有位置都会更改该类。

评论

0赞 Rk Bishnoi 9/5/2023
class OTPController extends BaseAPIController { protected $jwtService; protected $userModel; protected $referralCodeModel; protected $referralHistoryModel; public function __construct(JWTService $jwtService, UserModel $userModel, ReferralCodeModel $referralCodeModel, ReferralHistoryModel $referralHistoryModel) { $this->jwtService = $jwtService; $this->userModel = $userModel; $this->referralCodeModel = $referralCodeModel; $this->referralHistoryModel = $referralHistoryModel; } Send OTP Method }
0赞 Rk Bishnoi 9/5/2023
错误消息: “title”: “ArgumentCountError”, “type”: “ArgumentCountError”, “code”: 500, “message”: “函数 App\\Controllers\\RestAPI\\V1\\OTP\\OTPController::__construct(), 0 在 /Users/rkbishnoi/Sites/localhost/FProject/vendor/codeigniter4/framework/system/CodeIgniter.php 中传递,恰好是预期的 4”, “file”: “/Users/rkbishnoi/Sites/localhost/FProject/app/Controllers/RestAPI/V1/OTP/OTPController.php”,
0赞 Ronin-0822 9/5/2023
谢谢你的代码。如果我错了,任何人都会纠正我,但我认为你不能将参数传递给控制器的 __construct() 方法。但是,您可以通过自己的库中的构造函数传递参数。您还可以使用 .我已经编辑了我的答案。$this->model = new model()
0赞 Rk Bishnoi 9/7/2023
与直接在控制器方法中使用 new ServiceName() 相比,使用依赖关系注入(如代码示例中所示)通常被认为是一种更安全、更易于维护的依赖关系处理方式。
0赞 Ronin-0822 9/7/2023
这是绝对正确的。但我认为 DI 应该(可以?)只在模型和库中使用。对于控制器,Codeigniter 使用一种叫做“服务”的东西。请查看 Codeigniter 4 Overview->Services 下的 CI 文档。Quote:建议仅在控制器内创建服务。其他文件(如模型和库)应将依赖项传递到构造函数中或通过 setter 方法传递。