Slim 3.11 可调用解析器类型错误
Slim 3.11 Callable Resolver TypeError
我找不到我的错误。当我在我的 slim api 中尝试一条路线时,我得到了 follow TypeError。
错误是:
Argument 1 passed to
HCC\API\Controllers\FacultyController::__construct() must be an
instance of PDO, instance of Slim\Container given
此控制器的构造函数是:
public function __construct(\PDO $db, \MongoDB\Client $mongo, \Monolog\Logger $applogger, \Monolog\Logger $seclogger)
我放入容器的DI工厂是:
$container['FacultyController'] = function($c) {
return new FacultyController($c->get('db'), $c->get('mongo'), $c->get('appLogger'), $c->get('secLogger'));
};
我试过将每个设置为它自己的变量并传入这些变量但效果相同。我已经 运行 一个成功的测试,它只加载了 slim 应用程序并检查容器是否有一个对象 class FacultyController 并且它有消息说我有一个那个控制器所以我 99% 确定控制器实际上被放入容器中。我认为路线可能有问题。我在控制器中有一个与考试相同的构造和调用方法。
我在其他帖子中发现了这个错误,但我发现的是没有将某些东西传递给构造方法的问题,这似乎是传递给我的错误参数。
我不想将整个容器传递给每个控制器,因为这些控制器只需要设置依赖项,而就控制器而言,其中有很多不必要的项目。
这主要是因为 Slim 在依赖容器中找不到 HCC\API\Controllers\FacultyController
class(因为你用字符串 'FacultyController'
而不是 class 的完全限定名称注册了它) .
当 Slim 在依赖容器中找不到它时,默认情况下,Slim 会尝试自己创建 HCC\API\Controllers\FacultyController
并将容器实例传递给 FacultyController
构造函数。但是因为你用 PDO
class 的类型提示声明 FacultyController
的构造函数,PHP 抱怨这种类型不匹配。
解决方案是尝试将 'FacultyController'
替换为包含命名空间的全名,以使 Slim 可以在依赖容器中找到控制器。
因此,
$container['FacultyController'] = function($c) {
return new FacultyController(
$c->get('db'),
$c->get('mongo'),
$c->get('appLogger'),
$c->get('secLogger')
);
};
你应该使用
$container[\HCC\API\Controllers\FacultyController::class] = function($c) {
return new \HCC\API\Controllers\FacultyController(
$c->get('db'),
$c->get('mongo'),
$c->get('appLogger'),
$c->get('secLogger')
);
};
或
use \HCC\API\Controllers\FacultyController;
$container[FacultyController::class] = function($c) {
return new FacultyController(
$c->get('db'),
$c->get('mongo'),
$c->get('appLogger'),
$c->get('secLogger')
);
};
然后在你的路由声明中,你可以使用,例如:
$app->get('/faculty', \HCC\API\Controllers\FacultyController::class);
More information about ::class
更新
如果您使用上面的代码,FacultyController
被认为是可调用的 class,这意味着它应该实现 __invoke()
方法。
class FacultyController
{
public function __invoke($request, $response, $args)
{
//handle the request
}
}
如果不想使用invokableclass而是使用普通方法来处理请求,在设置路由时包含方法名
$app->get('/faculty', \HCC\API\Controllers\FacultyController::class . ':getFacultyCollection');
getFacultyCollection()
方法将被调用来处理请求。
class FacultyController
{
public function getFacultyCollection($request, $response, $args)
{
//handle the request
}
}
如果 getFacultyCollection()
调用导致应用程序崩溃,如您在评论中所说,那么这是完全不同的问题。也许你有未终止的循环?
我找不到我的错误。当我在我的 slim api 中尝试一条路线时,我得到了 follow TypeError。 错误是:
Argument 1 passed to HCC\API\Controllers\FacultyController::__construct() must be an instance of PDO, instance of Slim\Container given
此控制器的构造函数是:
public function __construct(\PDO $db, \MongoDB\Client $mongo, \Monolog\Logger $applogger, \Monolog\Logger $seclogger)
我放入容器的DI工厂是:
$container['FacultyController'] = function($c) {
return new FacultyController($c->get('db'), $c->get('mongo'), $c->get('appLogger'), $c->get('secLogger'));
};
我试过将每个设置为它自己的变量并传入这些变量但效果相同。我已经 运行 一个成功的测试,它只加载了 slim 应用程序并检查容器是否有一个对象 class FacultyController 并且它有消息说我有一个那个控制器所以我 99% 确定控制器实际上被放入容器中。我认为路线可能有问题。我在控制器中有一个与考试相同的构造和调用方法。
我在其他帖子中发现了这个错误,但我发现的是没有将某些东西传递给构造方法的问题,这似乎是传递给我的错误参数。
我不想将整个容器传递给每个控制器,因为这些控制器只需要设置依赖项,而就控制器而言,其中有很多不必要的项目。
这主要是因为 Slim 在依赖容器中找不到 HCC\API\Controllers\FacultyController
class(因为你用字符串 'FacultyController'
而不是 class 的完全限定名称注册了它) .
当 Slim 在依赖容器中找不到它时,默认情况下,Slim 会尝试自己创建 HCC\API\Controllers\FacultyController
并将容器实例传递给 FacultyController
构造函数。但是因为你用 PDO
class 的类型提示声明 FacultyController
的构造函数,PHP 抱怨这种类型不匹配。
解决方案是尝试将 'FacultyController'
替换为包含命名空间的全名,以使 Slim 可以在依赖容器中找到控制器。
因此,
$container['FacultyController'] = function($c) {
return new FacultyController(
$c->get('db'),
$c->get('mongo'),
$c->get('appLogger'),
$c->get('secLogger')
);
};
你应该使用
$container[\HCC\API\Controllers\FacultyController::class] = function($c) {
return new \HCC\API\Controllers\FacultyController(
$c->get('db'),
$c->get('mongo'),
$c->get('appLogger'),
$c->get('secLogger')
);
};
或
use \HCC\API\Controllers\FacultyController;
$container[FacultyController::class] = function($c) {
return new FacultyController(
$c->get('db'),
$c->get('mongo'),
$c->get('appLogger'),
$c->get('secLogger')
);
};
然后在你的路由声明中,你可以使用,例如:
$app->get('/faculty', \HCC\API\Controllers\FacultyController::class);
More information about ::class
更新
如果您使用上面的代码,FacultyController
被认为是可调用的 class,这意味着它应该实现 __invoke()
方法。
class FacultyController
{
public function __invoke($request, $response, $args)
{
//handle the request
}
}
如果不想使用invokableclass而是使用普通方法来处理请求,在设置路由时包含方法名
$app->get('/faculty', \HCC\API\Controllers\FacultyController::class . ':getFacultyCollection');
getFacultyCollection()
方法将被调用来处理请求。
class FacultyController
{
public function getFacultyCollection($request, $response, $args)
{
//handle the request
}
}
如果 getFacultyCollection()
调用导致应用程序崩溃,如您在评论中所说,那么这是完全不同的问题。也许你有未终止的循环?