我正在尝试使用控制器,但是继续获取错误
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
中导入名称空间,就像为Request
和Response
完成的名称空间:
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
)。