超薄控制器问题:必须是ContainerInterface的实例,Slim \\ Container的实例给定

时间:2016-06-19 10:43:00

标签: php model-view-controller slim

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

PHP Catchable致命错误:参数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。

4 个答案:

答案 0 :(得分:16)

您的代码似乎基于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\Container正在扩展Pimple\Container,因此以下内容应该是控制器方法的有效(工作)类型声明:

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

......甚至......

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

答案 1 :(得分: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;
}

答案 2 :(得分:1)

只需在控制器中粘贴以下代码

即可
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控制器中提供namepspace时犯了错误。

答案 3 :(得分:0)

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