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

los*_*1in 8 php model-view-controller slim

我试图在Slim中使用控制器但是不断收到错误

PHP Catchable致命错误:传递给
TopPageController :: __ construct()的参数1 必须是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();
?>
Run Code Online (Sandbox Code Playgroud)

我的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;
   }
}
?>
Run Code Online (Sandbox Code Playgroud)

谢谢.我正在使用Slim 3.

Wer*_*ner 16

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

你基本上有两个选项让它工作.

选项1:

导入你的命名空间index.php,就像它正在做的RequestResponse:

use \Interop\Container\ContainerInterface as ContainerInterface;
Run Code Online (Sandbox Code Playgroud)

选项2:

将TopPageController的构造函数更改为:

public function __construct(Interop\Container\ContainerInterface $ci) {
    $this->ci = $ci;
}
Run Code Online (Sandbox Code Playgroud)

TL; DR

抛出异常的原因是Slim\Container该类正在使用该Interop\Container\ContainerInterface接口(请参阅源代码):

use Interop\Container\ContainerInterface;
Run Code Online (Sandbox Code Playgroud)

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

public function __construct(Pimple\Container $ci) {
    $this->ci = $ci;
}
Run Code Online (Sandbox Code Playgroud)

...甚至...

public function __construct(ArrayAccess $ci) {
    $this->ci = $ci;
}
Run Code Online (Sandbox Code Playgroud)


Tre*_*her 7

基于Slim3 的后续更改(从版本 3.12.2 到 3.12.3),需要稍微不同的 ContainerInterface。这将更\Interop\改为\Psr\. 在代码顶部添加以下内容或更改现有的use

use Psr\Container\ContainerInterface;

Run Code Online (Sandbox Code Playgroud)

或者更改构造函数:

public function __construct(\Psr\Container\ContainerInterface $container)
{
    $this->container = $container;
}
Run Code Online (Sandbox Code Playgroud)