Slim4 を触ってみようと思い立ったのでメモ。
Slim3 のときは上述参考記事の通りに Slim-Skelton に dotenv(
vlucas/phpdotenv ) や whoops(
dopesong/Slim-Whoops ) 等を導入したのですが、 Slim のバージョンが4に上がって同じやり方ができなくなってしまいました。
そこで、同じようなことができないかと試した方法を以下に記します。
ベース
ベースとして使用するのは
slimphp/Slim-Skeleton: Slim Framework 4 Skeleton Application 。公式なので Slim4 版ですね。
public/vendor
.env
composer.lock
.gitignore
に上述3行を追加。
{
"name": "slim/slim-skeleton",
"description": "A Slim Framework skeleton application for rapid development",
"keywords": [
"microframework",
"rest",
"router",
"psr7"
],
"homepage": "http://github.com/slimphp/Slim-Skeleton",
"license": "MIT",
"authors": [
{
"name": "Josh Lockhart",
"email": "info@joshlockhart.com",
"homepage": "http://www.joshlockhart.com/"
},
{
"name": "Pierre Berube",
"email": "pierre@lgse.com",
"homepage": "http://www.lgse.com/"
}
],
"require": {
"ext-json": "*",
"monolog/monolog": "^1.24",
"php": ">=7.1",
"php-di/php-di": "^6.0",
"slim/psr7": "^0.5",
"slim/slim": "^4.1",
"vlucas/phpdotenv": "v4.1.0"
},
"require-dev": {
"phpunit/phpunit": "^7.5",
"squizlabs/php_codesniffer": "^3.5.3",
"phpmd/phpmd": "^2.8.1",
"zeuxisoo/slim-whoops": "^0.7.2"
},
"config": {
"process-timeout": 0,
"sort-packages": true,
"vendor-dir": "public/vendor"
},
"autoload": {
"psr-4": {
"App\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"Tests\\": "tests/"
}
},
"scripts": {
"start": "php -S localhost:8080 -t public",
"test": "phpunit",
"phpcs": "phpcs --standard=PSR2 src/",
"phpmd": "phpmd src/ text cleancode,codesize,design,unusedcode"
}
}
composer.json
に各種追加。
require __DIR__ . '/vendor/autoload.php'; // modified
public/index.php
のautoloadのディレクトリを書き換えます。これは
composer.json
の
config
で
"vendor-dir": "public/vendor"
と、
vendor
の位置を変える記述をしたため。
この変更を行った理由については最後のdebugbarの追加の部分で。
これについては Slim3 とほぼ同様。
require __DIR__ . '/../vendor/autoload.php';
// added
$dot_env = __DIR__. '/../.env';
if (is_readable($dot_env)) {
$dotenv = Dotenv\Dotenv::createImmutable(__DIR__ . '/../');
$dotenv->load();
}
// Instantiate PHP-DI ContainerBuilder
$containerBuilder = new ContainerBuilder();
ただし
phpdotenv
自体が新しくなっているので
public/index.php
の微妙に書き方を変えました。
// Global Settings Object
$containerBuilder->addDefinitions([
'settings' => [
'debug' => getenv('DEBUG'), // added
'displayErrorDetails' => true, // Should be set to false in production
'logger' => [
'name' => 'slim-app',
app/settings.php
に1行追加。
Slim3 で使用していた
dopesong/Slim-Whoops が更新されていないので、 Slim4 対応している別のwhoops(
zeuxisoo/php-slim-whoops )を使用することにします。
<?php
declare(strict_types=1);
use App\Application\Middleware\SessionMiddleware;
use Slim\App;
return function (App $app) {
$app->add(SessionMiddleware::class);
// added
$c = $app->getContainer();
if ((bool)($c->get('settings')['debug'] ?? false)) {
$app->add(new Zeuxisoo\Whoops\Slim\WhoopsMiddleware(['enable' => true]));
} else {
$errorMiddleware = $app->addErrorMiddleware(false, true, true);
$errorHandler = $errorMiddleware->getDefaultErrorHandler();
$errorHandler->registerErrorRenderer('text/html', HtmlErrorRenderer::class);
}
};
app/middleware.php
に上述コードを追加。コードは
Custom error rendering in Slim 4 – Rob Allen’s DevNotes より。
ちなみにRob Allen(akrabat)さんはSlimのメンテナーの一人。……道理でSlim関係を検索するとよくヒットすると思った。
debugbarも
kitchenu/Slim-DebugBar が Slim3 で止まっているので、
maximebf/php-debugbar を使用。
// 略
use Psr\Log\LoggerInterface;
use DebugBar\StandardDebugBar; // added
return function (ContainerBuilder $containerBuilder) {
$containerBuilder->addDefinitions([
// 略
DebugBar::class => function (ContainerInterface $c) { // added
$debugbar = new StandardDebugBar();
$debugbar->addCollector(new DebugBar\Bridge\MonologCollector($c->get(LoggerInterface::class)));
$renderer = $debugbar->getJavascriptRenderer();
$renderer->setIncludeVendors(false);
return $debugbar;
},
]);
};
app/dependencies.php
に以上を追加。
return function (App $app) {
$c = $app->getContainer();
$app->get('/', function (Request $request, Response $response) use ($c) {
$renderHead = '';
$renderBottomBody = '';
if ((bool)($c->get('settings')['debug'] ?? false)) {
$debugbar = $c->get(DebugBar::class);
$debugbarRenderer = $debugbar->getJavascriptRenderer();
$renderHead = <<<eof
<script src="https://code.jquery.com/jquery-3.4.1.min.js" integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=" crossorigin="anonymous"></script>
{$debugbarRenderer->renderHead()}
eof;
$renderBottomBody = $debugbarRenderer->render();
}
$bodyText = 'Hello world!';
$body = <<<eof
<html>
<head>
{$renderHead}
</head>
<body>
<h1>{$bodyText}</h1>
{$renderBottomBody}
</body>
</html>
eof;
$response->getBody()->write($body);
return $response;
});
app/routes.php
のルートのルーティングを書き換え。コードについてはやはり
Dependency Injection in Slim 4 – Rob Allen’s DevNotes より。
ここまででPHP的には動作をするのですが、debugbarが
vendor
ディレクトリ内のcssやらJSやらを読み込もうとします。
そのため、
composer start
こと
php -S localhost:8080 -t public
でPHPのビルドインWebサーバを起動した場合はリソースが読み込めずにコンソールに404エラーを吐きます。
そこで冒頭のように
vendor
ディレクトリを
public
内に持ってきました。
この変更により、debugbarが表示されるようになりました。
ついでに
.env
に
DEBUG=1
と記述した場合はdebugbar表示、そうれなければ非表示、というように条件分岐を追記しておきました。
動作確認
カスタマイズしたSlim4-Skeletonの動作確認
DebugBarも出ていますね。
成果物
カスタマイズしたものをGithubのリポジトリに置いておきました。
参考