Slim3 Framework×slim-skeleton不使用×twigでプロジェクトを作成する（3. LoggingとController）

# はじめに
[Slim3 Framework×slim-skeleton不使用×twigでプロジェクトを作成する
（2. DocumentRoot変更～Twigを使用）](https://qiita.com/erik_t/items/9d896867234c904409de)の続きです。

# 前提
下記記事で構築した環境を前提とします。

- Windows10にVagrantをを入れてCentOS7をインストールしよう([1](https://qiita.com/erik_t/items/d7f7abbf7deafa4c6fe4)、[2](https://qiita.com/erik_t/items/909efb63fd389f486ec3)、[3](https://qiita.com/erik_t/items/2e3c43cfe8731621b82d)、[4](https://qiita.com/erik_t/items/8d006b599815c8fbf38b)、[5](https://qiita.com/erik_t/items/9fbe7b5630b1f62893a1)、[6](https://qiita.com/erik_t/items/11f24633f4248e4f33f0)) 
- ローカルでLAMP環境を構築しよう（[0](https://qiita.com/erik_t/items/9c7c49db061a250cbc32)、[1](https://qiita.com/erik_t/items/e36235896b327f5cb461)、[2](https://qiita.com/erik_t/items/8dc3f2a5e8e8c9376e27)、[3](https://qiita.com/erik_t/items/617503557020a4a6ba82)、[4](https://qiita.com/erik_t/items/a898d0f547bff6b3d8ff)）
- [CentOS7にComposerをインストールしよう](https://qiita.com/erik_t/items/0b3492f38f6cd8605a4c)

- 私家版 Slim Framework チュートリアル ([1](https://qiita.com/nunulk/items/4b5c15f13ade660cafbc)、[2](https://qiita.com/nunulk/items/8492548678aac697d0aa#_reference-1dc558a7a78d9b00868b)、[3](https://qiita.com/nunulk/items/33adfbba55057a7d0c5c#_reference-8903d1023c2501e00d0b)、[4](https://qiita.com/nunulk/items/fb5ef759c1337e99d878#_reference-56dbec1889beef3f7f4d)、[5](https://qiita.com/nunulk/items/92d06bada7657ce212e7#_reference-1e4198f2501e274dbdd8)、[6](https://qiita.com/nunulk/items/99c12ac8e7b631bd8ed3#_reference-11f698acaecbfe32d5ff))
[@nunulk](https://qiita.com/nunulk)さんのチュートリアルを一通り。
ここで作成したDBを使いまわします。
- Slim3 Framework×slim-skeleton不使用×twigでプロジェクトを作成する([1](https://qiita.com/erik_t/items/14d0103e343e440f6dc5)、[2](https://qiita.com/erik_t/items/9d896867234c904409de)）

# 手順
~~1. 専用のユーザーを作成~~
~~2. プロジェクトディレクトリを作成・slim3インストール~~
~~3. 各種設定~~
~~4. DocumentRootを変更＆表示確認~~
~~5. Twigを使ってみよう~~
**6. Loggingしてみよう**
**7. Controllerを作成しよう**
8. PDOを使用してデータベースに接続しよう
9. @nunulkさんのチュートリアルで作成したチケット管理システムをtwigを使って再現しよう

# やってみよう
今回の記事では、手順6～7を行います。
## 6. Loggingしてみよう
### monologインストール
以下のコマンドでmonologをインストールします。

```
composer require monolog/monolog
```
### settings.phpに設定を追加
`config/settings.php`に下記設定を追加します。
ダニエルさんのサイトの記述のままだと、エラーログの日付が下記みたいになってしまうので、
`[2020-07-09T06:09:09.183042+00:00] app.ERROR: My error message! [] []`
日付と出力形式を追加します。

```:config/settings.php
$settings['logger'] = [
  'name'        => 'app',
  'file'        => $settings['temp'] . '/logs/app.log',
  'level'       => \Monolog\Logger::ERROR,
  'date_format' => 'Y-m-d H:i:s',
  'output'      => "[%datetime%] %level_name%: %message% %context% %extra%\n",
];
```
### container.phpに設定を追加
`config/container.php`に下記設定を追加します。
こちらも`config/settings.php`に追加した日付と出力形式を有効にするための記載が追加されています。

```:config/container.php
use Monolog\Formatter\LineFormatter;
use Monolog\Handler\RotatingFileHandler;
use Monolog\Logger;
use Psr\Log\LoggerInterface;

$container[LoggerInterface::class] = function (Container $container) {
    $settings = $container->get('settings')['logger'];
    $level = isset($settings['level']) ? $settings['level'] : Logger::ERROR;
    $logFile = $settings['file'];
    $date_format = $settings['date_format'];
    $output = $settings['output'];
    $formatter = new LineFormatter($output, $date_format);

    $logger = new Logger($settings['name']);
    $handler = new RotatingFileHandler($logFile, 0, $level, true, 0775);
    $handler->setFormatter($formatter);
    $logger->pushHandler($handler);

    return $logger;
};
```
### routes.phpにルートを追加
`config/routes.php`に下記ルートを追加します。

```:config/routes.php
use Psr\Log\LoggerInterface;

$app->get('/logger-test', function (Request $request, Response $response) {
    /** @var Container $this */
    /** @var LoggerInterface $logger */

    $logger = $this->get(LoggerInterface::class);
    $logger->error('My error message!');

    $response->getBody()->write("Success");

    return $response;
});
```
### 動作確認
ブラウザで以下のURLを開いてください。以下が確認できればOKです。
1. ブラウザに`Success`と表示される。
2. ログファイル`tmp/logs/app-2020-07-09.log`が生成される。
3. `tmp/logs/app-2020-07-09.log`に下記例のようなエラーログが記載されている。
例）`[2020-07-09 06:42:56] ERROR: My error message! [] []`

```
http://192.168.33.90/logger-test
```
## 7. Controllerを作成しよう
リクエストとレスポンスを処理するためのパブリックメソッドを1つだけ与えるSingle Action Controllersと
依存性の注入を行うDependency injectionの2パターンのControllerクラスを作成します。
ダニエルさんはControllerクラスといいながらクラスの命名を××Actionクラスとしているので、そこは踏襲します。

### Single Action Controllers
#### PingAction.php作成
srcディレクトリの下にActionディレクトリを作成し、PingAction.phpというファイルを作成します。
PingAction.phpには以下のように記述します。

```:src/Action/PingAction.php
<?php

namespace App\Action;

use Psr\Http\Message\ResponseInterface;
use Slim\Http\Request;
use Slim\Http\Response;

final class PingAction
{
    public function __invoke(Request $request, Response $response): ResponseInterface
    {
        return $response->withJson(['success' => true]);
    }
}
```
#### routes.phpにルートを追加

```:config/routes.php
$app->any('/ping', \App\Action\PingAction::class);
```
#### 動作確認
ブラウザで以下のURLを開き、`{"success":true}`と表示されればOKです。

```
http://192.168.33.90/ping
```
### Dependency injection
#### HomeIndexAction.php作成
`src/Action/HomeIndexAction.php`というファイルを作成し、以下のように記述します。
ダニエルさんはActionInterfaceクラスをimplementするようなことを書いてあったのですが、
implementすると動かないので省きました。

```:src/Action/HomeIndexAction.php
<?php

namespace App\Action;

use Psr\Http\Message\ResponseInterface;
use Slim\Http\Request;
use Slim\Http\Response;
use Slim\Views\Twig;

final class HomeIndexAction
{
    /**
     * @var Twig
     */
    private $twig;

    /**
     * Constructor.
     *
     * @param Twig $twig
     */
    public function __construct(Twig $twig)
    {
        $this->twig = $twig;
    }

    /**
     * Action.
     *
     * @param Request $request the request
     * @param Response $response the response
     *
     * @return ResponseInterface the response
     */
    public function __invoke(Request $request, Response $response): ResponseInterface
    {
        $viewData = [
            'name' => 'World',
        ];

        return $this->twig->render($response, 'Home/home-index.twig', $viewData);
    }
}
```
#### container.phpに設定を追加
`config/container.php`に下記設定を追加します。

```:config/container.php
$container[\App\Action\HomeIndexAction::class] = function (Container $container) {
    $twig = $container->get(\Slim\Views\Twig::class);
    return new \App\Action\HomeIndexAction($twig);
};
```

#### routes.phpにルートを追加

```:config/routes.php
$app->get('/home', \App\Action\HomeIndexAction::class);
```

#### home-index.twigを作成
templateディレクトリの下にHomeディレクトリを作成し、その下にhome-index.twigを作成します。
`template/Home/home-index.twig`には以下のように記述します。

```:template/Home/home-index.twig
Hello {{ name }}!
```

#### 動作確認
ブラウザで以下のURLを開き、`Hello World!`と表示されればOKです。

```
http://192.168.33.90/home
```
# 参考サイト
[Creating your first Slim 3 Framework Application](https://odan.github.io/2017/11/30/creating-your-first-slim-framework-application.html)
[PHP monologをカスタマイズしてみた](https://php-archive.net/php/twig-advanced/)

# 関連ページ
## Windows10にVagrantをを入れてCentOS7をインストールしよう
[1. VagrantインストールからVagrantfileを設置まで](https://qiita.com/erik_t/items/d7f7abbf7deafa4c6fe4)
[2. 仮想マシンの操作](https://qiita.com/erik_t/items/909efb63fd389f486ec3)
[3. WinSCP、Tera Termに秘密鍵でログイン ](https://qiita.com/erik_t/items/2e3c43cfe8731621b82d)
[4. WinSCP、Tera Termにrootユーザーでパスワードログイン](https://qiita.com/erik_t/items/8d006b599815c8fbf38b)
[5. zip/unzipをインストール](https://qiita.com/erik_t/items/9fbe7b5630b1f62893a1)
[6. Vagrantにて仮想環境を配布](https://qiita.com/erik_t/items/11f24633f4248e4f33f0)

## ローカルでLAMP環境を構築しよう
[0. 事前準備](https://qiita.com/erik_t/items/9c7c49db061a250cbc32)
[1. Apacheをインストール](https://qiita.com/erik_t/items/e36235896b327f5cb461)
[2. MySQLをインストール](https://qiita.com/erik_t/items/8dc3f2a5e8e8c9376e27)
[3. PHPをインストール](https://qiita.com/erik_t/items/617503557020a4a6ba82)
[4. ファイアウォールとか停止する](https://qiita.com/erik_t/items/a898d0f547bff6b3d8ff)

## Composerをインストール
[CentOS7にComposerをインストールしよう](https://qiita.com/erik_t/items/0b3492f38f6cd8605a4c)

## PHP Slim3フレームワークのサンプルアプリを作ろう
[2-1. First Application Walkthrough Getting Set Upまで](https://qiita.com/erik_t/items/9e9f6c93d2403ac90242)

## Apache
 [DocumentRootを変更しよう](https://qiita.com/erik_t/items/d8f4746d2dc2992f329e)

## Slim3 Framework×slim-skeleton不使用×twigでプロジェクトを作成する
[1. プロジェクト作成～各種設定](https://qiita.com/erik_t/items/14d0103e343e440f6dc5)
[2. DocumentRoot変更～Twigを使用](https://qiita.com/erik_t/items/9d896867234c904409de)
3. LoggingとController
[4.PDO使用](https://qiita.com/erik_t/items/7571f214142be628afac)
[5. チケット管理システムを再現➀](https://qiita.com/erik_t/items/fff0edee3ddfa509b2a5)
[6. チケット管理システムを再現➁](https://qiita.com/erik_t/items/28f2cabc460312ea5111)