こんにちは、コバヤシです。
今回は前回に引き続き、Slimを試していきます。
前回はSlimのインストールとTwigを使えるまでやったので、今回はコントローラーの使用とDB接続をやっていきたいと思います。
コントローラーを作成する
前回はroutes.php内で直接twigをrenderし表示をしていましたが、これだとroutesが増えてきた時に煩雑になります。
Laravelと同じ様にコントローラーを作成して、その中でviewの処理を行うようにしたいと思います.
app/Http/Controllers/TestController.php を作成して以下を記述します。
<?php namespace App\Http\Controllers; use Psr\Http\Message\RequestInterface; use Psr\Http\Message\ResponseInterface; use Psr\Container\ContainerInterface; class TestController { private $app; public function __construct(ContainerInterface $container) { $this->container = $container; } public function index(RequestInterface $request, ResponseInterface $response): ResponseInterface { $view = $this->container->get(Twig::class); return $view->render($response, 'index.twig', []); } }
コントローラー内でTwigを使用できるように、コンストラクタでContainerInterfaceをDIして、getでTwigのコンテナを取り出して使用しています。
routesでコントローラーを指定する
作成したコントローラーを使用するようにroutesに記述を変更します.
<?php // コメントアウト // $app->get('/', function (Request $request, Response $response) use ($app) { // $twig = $app->getContainer()->get(Twig::class); // return $twig->render($response, 'index.twig', []); // }); // 以下を追加 $app->get('/', '\App\Http\Controllers\TestController:index');
getの第2引数にコントローラー名:アクション名の形で記述すればOKです。
コントローラーが読み込まれるように設定する
上記のままではコントローラーが読み込まれないため、composerのautoloadに記述します。
"autoload": { "psr-4": { "App\\": "src/", "App\\Http\\Controllers\\": "app/http/controllers" }
ネームスペースと実際のパスを合うように追記します.
記述したら slimのあるディレクトリで以下を実行します。
composer dump-autoload
これでコントローラーを使用してviewが表示されるようになりました。
DBに接続する
今度はDBの接続をやっていきます。
Laravelで使用している「Eloquent」も利用できるようですが、今回はシンプルにPDOでの接続を行います。
app/settings.phpにDBの設定を追加します。
<?php declare(strict_types=1); use App\Application\Settings\Settings; use App\Application\Settings\SettingsInterface; use DI\ContainerBuilder; use Monolog\Logger; return function (ContainerBuilder $containerBuilder) { // Global Settings Object $containerBuilder->addDefinitions([ SettingsInterface::class => function () { return new Settings([ 'displayErrorDetails' => true, // Should be set to false in production 'logError' => false, 'logErrorDetails' => false, 'logger' => [ 'name' => 'slim-app', 'path' => isset($_ENV['docker']) ? 'php://stdout' : __DIR__ . '/../logs/app.log', 'level' => Logger::DEBUG, ], 'twig' => [ 'strict_variables' => true, 'cache' => __DIR__ . '/../var/cache/twig', ], // 以下を追加 // 設定内容は適宜書き換えてください 'db' => [ 'host' => 'localhost', 'user' => 'xxxxx', 'password' => 'xxxxx', 'dbname' => 'xxxx_db', ] ]); } ]); };
今回は直接記述していますが、本来はphpdotenvなどを使った方が良いですね。
次にコンテナに登録をします。
<?php declare(strict_types=1); use App\Application\Settings\SettingsInterface; use DI\ContainerBuilder; use Monolog\Handler\StreamHandler; use Monolog\Logger; use Monolog\Processor\UidProcessor; use Psr\Container\ContainerInterface; use Psr\Log\LoggerInterface; use Slim\Views\Twig; use App\Application\Settings\Settings; return function (ContainerBuilder $containerBuilder) { $containerBuilder->addDefinitions([ LoggerInterface::class => function (ContainerInterface $c) { $settings = $c->get(SettingsInterface::class); $loggerSettings = $settings->get('logger'); $logger = new Logger($loggerSettings['name']); $processor = new UidProcessor(); $logger->pushProcessor($processor); $handler = new StreamHandler($loggerSettings['path'], $loggerSettings['level']); $logger->pushHandler($handler); return $logger; }, Twig::class => function (ContainerInterface $container) { $settings = $container->get(SettingsInterface::class); return Twig::create(__DIR__ . '/../templates', $settings->get('twig')); }, // 以下を追加します 'db' => function(ContainerInterface $container) { $settings = $container->get(SettingsInterface::class); $dsn = 'mysql:host=%s;dbname=%s;charset=utf8mb4'; $db = $settings->get('db'); $pdo = new \PDO(sprintf($dsn, $db['host'], $db['dbname']), $db['user'], $db['password']); $pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION); $pdo->setAttribute(\PDO::ATTR_DEFAULT_FETCH_MODE, \PDO::FETCH_ASSOC); return $pdo; } ]); };
これでコントローラー内で使えるようになりました。
Twigと同じ様にコンテナを呼び出して使用します。
<?php public function index(RequestInterface $request, ResponseInterface $response): ResponseInterface { $view = $this->container->get(Twig::class); $container = $this->container->get('db'); $sql = 'SELECT * FROM users'; $query = $container->prepare($sql); $query->execute(); $data = $query->fetchAll(\PDO::FETCH_ASSOC); return $view->render($response, 'index.twig', ['data' => $data]); }
まとめ
無事にコントローラーとDBを使用できるようになりました。
やはりフルスタックのフレームワークと違い準備までに時間が掛かりますね。
取り敢えずここまで試せたので、Slimは一段落とします。
これからも引き続きSlimなどのフレームワークを触っていきたいと思います。