PHP Slim 環境構築(4) Autoloaderとソースツリー
Introduction
前回は、RedisとかMySQLとかPostgreSQLとかをdocker-composeを使って構築しましたが、今回は追加ソースのツリーを構築してみたいと思います。
このあたりはベストプラクティスが良く分かっていないので、自己流です。
今回のサンプル
SlimフレームワークのMiddlewareの説明の前半部分、単純なMiddlewareの追加を実装してみます。
ソースツリー
ソースツリーは以下の通りにしました。
$(PROJECTROOT)
/compose
/src
/hoge
/public
index.php
/lib
ExampleAfterMiddleware.php
ExampleBeforeMiddleware.php
/vendor
composer.json
composer.lock
ExmplaAfterMiddleware.php
処理したコンテンツの後ろに":AFTER"と追加するだけの単純なMiddlewareです。
<?php
namespace Hoge;
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Server\RequestHandlerInterface as RequestHandler;
use Psr\Http\Message\ResponseInterface as Response;
class ExampleAfterMiddleware
{
public function __invoke(Request $request, RequestHandler $handler): Response
{
$response = $handler->handle($request);
$response->getBody()->write(':AFTER');
return $response;
}
}
ExampleBeforeMiddleware.php
処理したコンテンツの前に"BEFORE:"と追加するだけのMiddlewareです。
ExampleAfterMiddlewareと"Response"の型が違うのがちょっと嫌な感じです・・・
<?php
namespace Hoge;
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Server\RequestHandlerInterface as RequestHandler;
use Slim\Psr7\Response;
class ExampleBeforeMiddleware
{
public function __invoke(Request $request, RequestHandler $handler): Response
{
$response = $handler->handle($request);
$existingContent = (string) $response->getBody();
$newResponse = new Response();
$newResponse->getBody()->write('BEFORE:' . $existingContent);
return $newResponse;
}
}
composer.json
composer.json書き換えて云々というのがよくあるタイプの解決方法ですが、今回はcomposerを書き換えない方法を使います。
index.php
新しく書き換えたHello, Worldのindex.phpです。
ポイントは、require autoload.phpが返してきたClassLoader(Composer\Autoload\ClassLoader)に対して、Psr4名前空間しているところです。
<?php
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Slim\Factory\AppFactory;
use Hoge\ExampleAfterMiddleware;
use Hoge\ExampleBeforeMiddleware;
/** @var Composer\Autoload\ClassLoader $loader */
$loader = require __DIR__ . '/../../vendor/autoload.php';
$loader->addPsr4('Hoge\\', __DIR__ . '/../lib');
$app = AppFactory::create();
// Middleware
$app->add(new ExampleBeforeMiddleware());
$app->add(new ExampleAfterMiddleware());
$app->get('/', function (Request $request, Response $response, array $args) {
$response->getBody()->write('Hello, World!');
return $response;
});
$app->run();
これで、このページにアクセスすると、"BEFORE:Hello, World!:AFTER"と出るはずです。
なお、参考までに呼び出しシーケンスは、以下の通りです。
ExampleAfterMiddleware::__invoke
ExampmleBeforeMiddleware::__invoke
index.phpで"Hello, World!"が返される
"BEFORE:Hello, World!"になる
"BEFORE:Hello, World!:AFTER"になる
ここまでのソース
こちらでどうぞ。