【问题标题】:Slim controller issue : must be an instance of ContainerInterface, instance of Slim\\Container givenSlim 控制器问题:必须是 ContainerInterface 的实例,给定 Slim\\Container 的实例
【发布时间】:2016-10-20 18:07:39
【问题描述】:

我正在尝试在 Slim 中使用控制器,但不断收到错误

PHP 可捕获的致命错误:参数 1 传递给
TopPageController::__construct() 必须是 ContainerInterface 的实例,
给定 Slim\Container 的实例

我的 index.php

<?php
use \Psr\Http\Message\ServerRequestInterface as Request;
use \Psr\Http\Message\ResponseInterface as Response;

require '../vendor/autoload.php';
require 'settings.php';

spl_autoload_register(function ($classname) {
    require ("../classes/" . $classname . ".php");
});

$app = new \Slim\App(["settings" => $config]);
$app->get('/', function (Request $request, Response $response) {
    $response->getBody()->write("Welcome");
    return $response;
});
$app->get('/method1', '\TopPageController:method1');
$app->run();
?>

我的 TopPageController.php

<?php
class TopPageController {
   protected $ci;
   //Constructor
   public function __construct(ContainerInterface $ci) {
       $this->ci = $ci;
   }

   public function method1($request, $response, $args) {
        //your code
        //to access items in the container... $this->ci->get('');
        $response->getBody()->write("Welcome1");
        return $response;
   }

   public function method2($request, $response, $args) {
        //your code
        //to access items in the container... $this->ci->get('');
        $response->getBody()->write("Welcome2");
        return $response;
   }

   public function method3($request, $response, $args) {
        //your code
        //to access items in the container... $this->ci->get('');
        $response->getBody()->write("Welcome3");
        return $response;
   }
}
?>

谢谢。我正在使用 Slim 3。

【问题讨论】:

  • 您的 ContainerInterface 上没有正确的命名空间。应该是Interop\Container\ContainerIterface

标签: php model-view-controller slim


【解决方案1】:

您的代码似乎基于http://www.slimframework.com/docs/objects/router.html 的 Slim 3 文档,其中不包含避免抛出异常所需的所有代码。

你基本上有两个选择让它工作。

选项 1:

index.php 中导入命名空间,就像为RequestResponse 所做的那样:

use \Interop\Container\ContainerInterface as ContainerInterface;

选项 2:

将TopPageController的构造函数改为:

public function __construct(Interop\Container\ContainerInterface $ci) {
    $this->ci = $ci;
}

TL;DR

抛出异常的原因是Slim\Container类使用了Interop\Container\ContainerInterface接口(见源码):

use Interop\Container\ContainerInterface;

由于Slim\ContainerPimple\Container 的扩展,以下都应该是控制器方法的有效(工作)类型声明:

public function __construct(Pimple\Container $ci) {
    $this->ci = $ci;
}

...甚至...

public function __construct(ArrayAccess $ci) {
    $this->ci = $ci;
}

【讨论】:

  • 如果这是升级 Slim 的结果,Trendfischer 的答案是最好的。 Interop\Container 已弃用,Slim 更改为 Psr\Container。最好更新您的代码以匹配 Slim 的更新。
【解决方案2】:

基于后来的change in Slim3(从版本 3.12.2 到 3.12.3),需要稍微不同的 ContainerInterface。这会将\Interop\ 更改为\Psr\。在您的代码之上添加以下内容或更改现有的use

use Psr\Container\ContainerInterface;

或者改变构造函数:

public function __construct(\Psr\Container\ContainerInterface $container)
{
    $this->container = $container;
}

【讨论】:

  • 从 3.12.2 => 3.12.3 更新时出现的问题
  • @DariuszChowański 谢谢,我忘了提。我相信当互操作模块获得“弃用”状态时,他们制作了这个补丁版本。我在答案中添加了版本信息。
【解决方案3】:

只需将以下代码粘贴到您的控制器中

use \Psr\Http\Message\ServerRequestInterface as Request;
use \Psr\Http\Message\ResponseInterface as Response;
use \Interop\Container\ContainerInterface as ContainerInterface;

您的控制器结构应该如下所示

public function __construct(ContainerInterface $container) {
    parent::__construct($container);
}

我认为您在控制器中为 ContainerInterface 提供命名空间是错误的。

【讨论】:

    【解决方案4】:

    由于container-interop/container-interop弃用,只需将其替换为psr/container (Psr\Container\ContainerInterface)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-03-12
      • 2017-12-02
      • 1970-01-01
      • 2023-03-03
      • 2021-05-15
      • 2015-10-16
      • 2019-03-21
      • 1970-01-01
      相关资源
      最近更新 更多