Slim 框架给出了一个令人困惑的未捕获类型错误
Slim Framework Is Giving A Confuing Uncaught TypeError
我刚刚使用我自己的设置通过 composer 安装了一个全新的 slim 副本。非常简单 index.php 里面很少:
<?php
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Slim\Factory\AppFactory;
require_once __DIR__ . '/../bootstrap.php';
// start the app
$APP = AppFactory::create();
/**
* Middleware to check validation before any routes
*/
$APP->add(function(Request $request, Response $response, callable $next){
$response = $next($request,$response);
return $response;
});
/**
* Add routes
*/
$APP->get('/test',function(Request $request, Response $response, array $args){
return $response->getBody()->write('hello');
});
// run the app
$APP->run();
Php 给出了一个非常奇怪的错误:
**Fatal error: Uncaught TypeError: Argument 2 passed to {closure}() must be an instance of Psr\Http\Message\ResponseInterface, instance of
Slim\Routing\RouteRunner given, called in
/var/www/vendor/slim/slim/Slim/MiddlewareDispatcher.php on line 275
and defined in /var/www/public/index.php:16 Stack trace: #0
/var/www/vendor/slim/slim/Slim/MiddlewareDispatcher.php(275):
{closure}(Object(Slim\Psr7\Request), Object(Slim\Routing\RouteRunner))
1 /var/www/vendor/slim/slim/Slim/MiddlewareDispatcher.php(73): class@anonymous->handle(Object(Slim\Psr7\Request)) #2
/var/www/vendor/slim/slim/Slim/App.php(206):
Slim\MiddlewareDispatcher->handle(Object(Slim\Psr7\Request)) #3
/var/www/vendor/slim/slim/Slim/App.php(190):
Slim\App->handle(Object(Slim\Psr7\Request)) #4
/var/www/public/index.php(34): Slim\App->run() #5 {main} thrown in
/var/www/public/index.php on line 16**
我不明白为什么它说这里的基本中间件正在使用 Slim\Routing\RouteRunner 的实例,而我显然给它 Psr\Http\Message\ResponseInterface
有什么想法吗?
编辑:
感谢 delboy 的回答,但你能更具体一点吗?苗条的文档显示像这样使用它(http://www.slimframework.com/docs/v3/concepts/middleware.html):
$app->add(function ($request, $response, $next) {
$response->getBody()->write('BEFORE');
$response = $next($request, $response);
$response->getBody()->write('AFTER');
return $response;
});
但这行不通!总是出现类型错误,他们的文档是否已过时?如果是这样,我如何在这里实现中间件?
他们给出的这个示例代码也产生了另一个奇怪的错误:
Fatal error: Uncaught ArgumentCountError: Too few arguments to function {closure}(), 2 passed in /var/www/vendor/slim/slim/Slim/MiddlewareDispatcher.php on line 275 and exactly 3 expected in /var/www/public/index.php:26 Stack trace: #0 /var/www/vendor/slim/slim/Slim/MiddlewareDispatcher.php(275): {closure}(Object(Slim\Psr7\Request), Object(class@anonymous)) #1 /var/www/vendor/slim/slim/Slim/MiddlewareDispatcher.php(73): class@anonymous->handle(Object(Slim\Psr7\Request)) #2 /var/www/vendor/slim/slim/Slim/App.php(206): Slim\MiddlewareDispatcher->handle(Object(Slim\Psr7\Request)) #3 /var/www/vendor/slim/slim/Slim/App.php(190): Slim\App->handle(Object(Slim\Psr7\Request)) #4 /var/www/public/index.php(38): Slim\App->run() #5 {main} thrown in /var/www/public/index.php on line 26
我的示例代码传递了 3 个参数,而不是 2 个!
编辑:
好的,Slim 文档显然已经过时了,应该这样做:
$app->add(function(ServerRequestInterface $request, RequestHandlerInterface $handler) {
$response = new Response();
$response->getBody()->write('STUFF');
return $response;
});
您的中间件未实现 PSR-15。您不应传递响应,而应传递请求处理程序接口:
namespace Psr\Http\Server;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
/**
* Participant in processing a server request and response.
*
* An HTTP middleware component participates in processing an HTTP message:
* by acting on the request, generating the response, or forwarding the
* request to a subsequent middleware and possibly acting on its response.
*/
interface MiddlewareInterface
{
/**
* Process an incoming server request.
*
* Processes an incoming server request in order to produce a response.
* If unable to produce the response itself, it may delegate to the provided
* request handler to do so.
*/
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface;
}
需要补充:
使用 Slim\Psr7\Response;
首先你需要检查你使用的是哪个 slim 版本,当我开始学习的时候我也遇到了这个问题 error/problem 但是你想解决这个问题你可以在你的代码中进行这个编辑。
$APP = AppFactory::create();
$app->setBasePath("/myapp/public/index.php");
$APP->add(function(Request $request, Response $response, callable $next){
$response = $next($request,$response);
return $response;
});
我刚刚使用我自己的设置通过 composer 安装了一个全新的 slim 副本。非常简单 index.php 里面很少:
<?php
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Slim\Factory\AppFactory;
require_once __DIR__ . '/../bootstrap.php';
// start the app
$APP = AppFactory::create();
/**
* Middleware to check validation before any routes
*/
$APP->add(function(Request $request, Response $response, callable $next){
$response = $next($request,$response);
return $response;
});
/**
* Add routes
*/
$APP->get('/test',function(Request $request, Response $response, array $args){
return $response->getBody()->write('hello');
});
// run the app
$APP->run();
Php 给出了一个非常奇怪的错误:
**Fatal error: Uncaught TypeError: Argument 2 passed to {closure}() must be an instance of Psr\Http\Message\ResponseInterface, instance of Slim\Routing\RouteRunner given, called in /var/www/vendor/slim/slim/Slim/MiddlewareDispatcher.php on line 275 and defined in /var/www/public/index.php:16 Stack trace: #0 /var/www/vendor/slim/slim/Slim/MiddlewareDispatcher.php(275): {closure}(Object(Slim\Psr7\Request), Object(Slim\Routing\RouteRunner))
1 /var/www/vendor/slim/slim/Slim/MiddlewareDispatcher.php(73): class@anonymous->handle(Object(Slim\Psr7\Request)) #2
/var/www/vendor/slim/slim/Slim/App.php(206): Slim\MiddlewareDispatcher->handle(Object(Slim\Psr7\Request)) #3 /var/www/vendor/slim/slim/Slim/App.php(190): Slim\App->handle(Object(Slim\Psr7\Request)) #4 /var/www/public/index.php(34): Slim\App->run() #5 {main} thrown in /var/www/public/index.php on line 16**
我不明白为什么它说这里的基本中间件正在使用 Slim\Routing\RouteRunner 的实例,而我显然给它 Psr\Http\Message\ResponseInterface
有什么想法吗?
编辑:
感谢 delboy 的回答,但你能更具体一点吗?苗条的文档显示像这样使用它(http://www.slimframework.com/docs/v3/concepts/middleware.html):
$app->add(function ($request, $response, $next) {
$response->getBody()->write('BEFORE');
$response = $next($request, $response);
$response->getBody()->write('AFTER');
return $response;
});
但这行不通!总是出现类型错误,他们的文档是否已过时?如果是这样,我如何在这里实现中间件?
他们给出的这个示例代码也产生了另一个奇怪的错误:
Fatal error: Uncaught ArgumentCountError: Too few arguments to function {closure}(), 2 passed in /var/www/vendor/slim/slim/Slim/MiddlewareDispatcher.php on line 275 and exactly 3 expected in /var/www/public/index.php:26 Stack trace: #0 /var/www/vendor/slim/slim/Slim/MiddlewareDispatcher.php(275): {closure}(Object(Slim\Psr7\Request), Object(class@anonymous)) #1 /var/www/vendor/slim/slim/Slim/MiddlewareDispatcher.php(73): class@anonymous->handle(Object(Slim\Psr7\Request)) #2 /var/www/vendor/slim/slim/Slim/App.php(206): Slim\MiddlewareDispatcher->handle(Object(Slim\Psr7\Request)) #3 /var/www/vendor/slim/slim/Slim/App.php(190): Slim\App->handle(Object(Slim\Psr7\Request)) #4 /var/www/public/index.php(38): Slim\App->run() #5 {main} thrown in /var/www/public/index.php on line 26
我的示例代码传递了 3 个参数,而不是 2 个!
编辑:
好的,Slim 文档显然已经过时了,应该这样做:
$app->add(function(ServerRequestInterface $request, RequestHandlerInterface $handler) {
$response = new Response();
$response->getBody()->write('STUFF');
return $response;
});
您的中间件未实现 PSR-15。您不应传递响应,而应传递请求处理程序接口:
namespace Psr\Http\Server;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
/**
* Participant in processing a server request and response.
*
* An HTTP middleware component participates in processing an HTTP message:
* by acting on the request, generating the response, or forwarding the
* request to a subsequent middleware and possibly acting on its response.
*/
interface MiddlewareInterface
{
/**
* Process an incoming server request.
*
* Processes an incoming server request in order to produce a response.
* If unable to produce the response itself, it may delegate to the provided
* request handler to do so.
*/
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface;
}
需要补充: 使用 Slim\Psr7\Response;
首先你需要检查你使用的是哪个 slim 版本,当我开始学习的时候我也遇到了这个问题 error/problem 但是你想解决这个问题你可以在你的代码中进行这个编辑。
$APP = AppFactory::create();
$app->setBasePath("/myapp/public/index.php");
$APP->add(function(Request $request, Response $response, callable $next){
$response = $next($request,$response);
return $response;
});