У меня есть плагин cakephp , который создает миниатюры изображений.
В настоящее время миниатюры «обслуживаются» действием контроллера, который возвращает файл в качестве ответа ( здесь ).
Это маршрут:
Router::plugin(THUMBER, ['path' => '/thumb'], function (RouteBuilder $routes) {
$routes->get('/:basename', ['controller' => 'Thumbs', 'action' => 'thumb'], 'thumb')
->setPatterns(['basename' => '[\w\d=]+'])
->setPass(['basename']);
});
Таким образом, URL-адрес (базовое имя миниатюры закодировано):
/thumb/ZDc1NTYyMGY1N2VmMzRiNTQyZjE0NTY2Mjk0YWQ2NTFfNGIyYTBkMjVhMTdjZTdjN2E4MjVjY2M1YWU1ODNhMzcuZ2lm
Теперь я пытаюсь заменить контроллер промежуточным программным обеспечением.
Это довольно просто, потому что в основном он будет работать как AssetMiddleware
, а метод __invoke()
почти как старый метод действия:
class ThumbnailMiddleware
{
use ThumbsPathTrait;
public function __invoke($request, $response, $next)
{
if ($request->getParam('_name') !== 'thumb' || !$request->getParam('basename')) {
return $next($request, $response);
}
$file = $this->getPath(base64_decode($request->getParam('basename')));
if (!is_readable($file)) {
throw new ThumbNotFoundException(__d('thumber', 'File `{0}` doesn\'t exist', $file));
}
$response = $response->withModified(filemtime($file));
if ($response->checkNotModified($request)) {
return $response;
}
return $response->withFile($file)->withType(mime_content_type($file));
}
}
Это работает очень хорошо.
Проблема в том, что теперь он работает, потому что это промежуточное ПО берет маршрут контроллера и «перехватывает» запрос, «решая» его, не проходя через контроллер (см. Первые три строки метода __invoke()
).
Теперь я хотел бы переписать этот маршрут и отвязать его от контроллера, который я должен полностью исключить из плагина.
Очевидно, что это хорошо работает следующим образом (второй параметр null
):
$routes->get('/:basename', null, 'thumb')
->setPatterns(['basename' => '[\w\d=]+'])
->setPass(['basename']);
Или я мог бы просто вызвать метод RouteBuilder::fallback()
и проанализировать URL запроса (как это происходит для AssetMiddleware
).
Но мне было интересно, есть ли способ связать маршрут только с промежуточным программным обеспечением и явно для промежуточного программного обеспечения.
Или, если нет, какой метод самый лучший.
Я знаю, что могу применить «промежуточное ПО для определенных областей маршрутизации» ( cookbook ), поэтому мне интересно, действительно ли это правильная формула:
Router::plugin(THUMBER, ['path' => '/thumb'], function (RouteBuilder $routes) {
$routes->registerMiddleware('thumbnail', new ThumbnailMiddleware);
$routes->applyMiddleware('thumbnail');
$routes->get('/:basename', null, 'thumb')
->setPatterns(['basename' => '[\w\d=]+'])
->setPass(['basename']);
});