Help us understand the problem. What is going on with this article?

PHP Slim 環境構築(4) Autoloaderとソースツリー

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です。

/src/hoge/lib/ExampleAfterMiddleware.php
<?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"の型が違うのがちょっと嫌な感じです・・・

/src/hoge/lib/ExampleBeforeMiddleware.php
<?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名前空間しているところです。

/src/hoge/public/index.php
<?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"になる

ここまでのソース

こちらでどうぞ。

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away