Slim Controller问题:必须是容器界面的实例,Slim 容器的实例



我正在尝试使用控制器,但是继续获取错误

PHP可捕致命错误:参数1传递给
TopPageController :: __ construct()必须是容器界面的实例,
Slim Container的实例

我的index.php

<?php
use PsrHttpMessageServerRequestInterface as Request;
use PsrHttpMessageResponseInterface as Response;
require '../vendor/autoload.php';
require 'settings.php';
spl_autoload_register(function ($classname) {
    require ("../classes/" . $classname . ".php");
});
$app = new SlimApp(["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。

您的代码似乎是基于http://www.slimframework.com/docs/objects/router.html的Slim 3文档,该文档不包含所有必需的代码抛出了例外。

您基本上有两个选择使它起作用。

选项1:

在您的index.php中导入名称空间,就像为RequestResponse完成的名称空间:

use InteropContainerContainerInterface as ContainerInterface;

选项2:

将toppagecontroller的构造函数更改为:

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

tl; dr

抛出异常的原因是SlimContainer类使用InteropContainerContainerInterface接口(请参阅源代码):

use InteropContainerContainerInterface;

由于SlimContainer正在扩展PimpleContainer,因此以下所有均应有效(工作)类型您的控制器方法的声明:

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

...甚至...

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

基于Slim3的以后更改(从3.12.2到3.12.3)需要一个稍有不同的容器接口。这将Interop更改为Psr。将以下内容添加到您的代码上方或更改现有的use

use PsrContainerContainerInterface;

或更改构造函数:

public function __construct(PsrContainerContainerInterface $container)
{
    $this->container = $container;
}

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

use PsrHttpMessageServerRequestInterface as Request;
use PsrHttpMessageResponseInterface as Response;
use InteropContainerContainerInterface as ContainerInterface;

您的控制器的结构应该看起来像下面的

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

我认为您在为ContainerInterface提供控制器的命名空间时犯了错误。

因为容器interop/container-Interop是 evemed ,只需将其替换为psr/container( PsrContainerContainerInterface)。

最新更新