基于TYPO3中间件与URL规则处理Extbase控制器动作方案咨询
TYPO3 自定义API中间件实现方案
核心逻辑
识别/api/[ext_name]/[controllerName]/[actionName]格式的URL,解析出扩展名、控制器名和动作名后,调用对应Extbase控制器的指定动作,最终返回JSON格式响应,支持GET/POST/PUT/DELETE请求。
步骤1:注册中间件
在Configuration/RequestMiddlewares.php中注册中间件,注意要放在Extbase基础中间件之后,确保依赖环境就绪:
return [ 'frontend' => [ 'your-vendor/api-handler' => [ 'target' => \YourVendor\YourExtension\Middleware\ApiMiddleware::class, 'after' => [ 'typo3/cms-frontend/site', 'typo3/cms-extbase/frontend-base', ], ], ], ];
步骤2:配置服务依赖
在Configuration/Services.yaml中注入中间件所需的Extbase核心服务:
services: YourVendor\YourExtension\Middleware\ApiMiddleware: arguments: $objectManager: '@TYPO3\CMS\Extbase\Object\ObjectManager' $dispatcher: '@TYPO3\CMS\Extbase\Mvc\Dispatcher' $requestBuilder: '@TYPO3\CMS\Extbase\Mvc\RequestBuilder' $responseFactory: '@Psr\Http\Message\ResponseFactoryInterface' tags: - name: middleware identifier: 'your-vendor/api-handler'
步骤3:实现中间件类
创建Classes/Middleware/ApiMiddleware.php,完成URL匹配、请求转换、控制器调用和响应封装:
<?php namespace YourVendor\YourExtension\Middleware; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Server\MiddlewareInterface; use Psr\Http\Server\RequestHandlerInterface; use TYPO3\CMS\Extbase\Mvc\Dispatcher; use TYPO3\CMS\Extbase\Mvc\RequestBuilder; use TYPO3\CMS\Extbase\Object\ObjectManager; use Psr\Http\Message\ResponseFactoryInterface; class ApiMiddleware implements MiddlewareInterface { protected $objectManager; protected $dispatcher; protected $requestBuilder; protected $responseFactory; public function __construct( ObjectManager $objectManager, Dispatcher $dispatcher, RequestBuilder $requestBuilder, ResponseFactoryInterface $responseFactory ) { $this->objectManager = $objectManager; $this->dispatcher = $dispatcher; $this->requestBuilder = $requestBuilder; $this->responseFactory = $responseFactory; } public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface { $uriPath = $request->getUri()->getPath(); // 匹配API URL规则,可根据需求调整正则 if (preg_match('#^/api/([a-z0-9_]+)/([a-z0-9_]+)/([a-z0-9_]+)$#i', $uriPath, $matches)) { [$_, $extName, $controllerName, $actionName] = $matches; // 构建Extbase标准请求 $extbaseRequest = $this->requestBuilder->build(); $extbaseRequest->setControllerExtensionName(ucfirst($extName)); $extbaseRequest->setControllerName(ucfirst($controllerName)); $extbaseRequest->setControllerActionName($actionName); $extbaseRequest->setRequestMethod($request->getMethod()); // 传递请求参数:POST/PUT取请求体,GET取URL参数 if (in_array($request->getMethod(), ['POST', 'PUT'])) { $params = $request->getParsedBody(); $extbaseRequest->setArguments(is_array($params) ? $params : []); } else { $extbaseRequest->setArguments($request->getQueryParams()); } // 调用控制器动作并处理异常 try { $extbaseResponse = $this->dispatcher->dispatch($extbaseRequest); $content = $extbaseResponse->getContent(); } catch (\Exception $e) { $content = json_encode(['code' => $e->getCode(), 'message' => $e->getMessage()]); } // 返回JSON格式响应 return $this->responseFactory->createResponse() ->withHeader('Content-Type', 'application/json; charset=utf-8') ->withBody($request->getBody()->write($content)->rewind()); } // 不匹配规则时,交给后续中间件处理 return $handler->handle($request); } }
步骤4:调整控制器动作
确保Extbase控制器的动作返回可序列化的数据,直接使用jsonResponse方法返回数组即可自动转为JSON:
<?php namespace YourVendor\Event\Controller; use TYPO3\CMS\Extbase\Mvc\Controller\ActionController; class EventManagementController extends ActionController { public function listAction() { $events = $this->eventRepository->findAll(); // 直接返回数组,Extbase会自动序列化为JSON return $this->jsonResponse($events); } public function createAction(\YourVendor\Event\Domain\Model\Event $event) { $this->eventRepository->add($event); return $this->jsonResponse(['status' => 'success', 'data' => $event]); } }
关键注意事项
- 正则表达式可根据实际需求调整,比如支持带额外参数的URL
- 中间件顺序必须在
typo3/cms-extbase/frontend-base之后,否则无法正确初始化Extbase请求环境 - 对于PUT/DELETE请求,确保TYPO3启用了请求体解析中间件(默认已启用)
- 异常处理可根据业务需求扩展,比如添加日志记录
内容的提问来源于stack exchange,提问作者Geee
相关产品推荐
相关产品推荐

