我正在尝试从与 Slim 捆绑在一起的 pimple 容器切换到 PHP-DI,但我遇到了让自动装配工作的问题。由于我仅限于使用 PHP 5.6,因此我使用 Slim 3.9.0 和 PHP-DI 5.2.0 以及 php-di/slim-bridge 1.1。
我的项目结构如下:
api
- src
| - Controller
| | - TestController.php
| - Service
| - Model
| - ...
- vendor
- composer.json
在api/composer.json
我有以下内容,然后运行composer dumpautoload
:
{
"require": {
"slim/slim": "3.*",
"php-di/slim-bridge": "^1.1"
},
"autoload": {
"psr-4": {
"MyAPI\\": "src/"
}
}
}
我的api/src/Controller/TestController.php
文件包含一个类:
<?php
namespace MyAPI\Controller;
class TestController
{
public function __construct()
{
}
public function test($request,$response)
{
return $response->write("Controller is working");
}
}
我最初尝试使用最小设置来使自动装配工作,只使用默认配置。index.php
<?php
use \Psr\Http\Message\ServerRequestInterface as Request;
use \Psr\Http\Message\ResponseInterface as Response;
require '/../../api/vendor/autoload.php';
$app = new \DI\Bridge\Slim\App;
$app->get('/', TestController::class, ':test');
$app->run();
但是,这返回了错误:
Type: Invoker\Exception\NotCallableException
Message: 'TestController'is neither a callable nor a valid container entry
我可以让它工作的唯一两种方法是直接放置TestController
类index.php
(这让我觉得 PHP-DI 不能很好地与自动加载器一起使用)或使用\DI\Bridge\Slim\App
. 但是,由于我需要显式注册控制器类,这有点违背了使用自动装配的意义(除非我错过了这一点):
use DI\ContainerBuilder;
use Psr\Container\ContainerInterface;
use function DI\factory;
class MyApp extends \DI\Bridge\Slim\App
{
public function __construct() {
$containerBuilder = new ContainerBuilder;
$this->configureContainer($containerBuilder);
$container = $containerBuilder->build();
parent::__construct($container);
}
protected function configureContainer(ContainerBuilder $builder)
{
$definitions = [
'TestController' => DI\factory(function (ContainerInterface $c) {
return new MyAPI\Controller\TestController();
})
];
$builder->addDefinitions($definitions);
}
}
$app = new MyApp();
$app->get('/', ['TestController', 'test']);
$app->run();