Slim 3 Framework でMySQLとテンプレつかってみる。その２

# Slim-Skeleton の導入
slim セットアップは簡単ですぐに使えるいい感じだけど、はじめは素直に [Slim-Skeleton](https://github.com/slimphp/Slim-Skeleton) を導入し肉付けを行っていった方が学習効果は高いと思います。がインスコする際にphpunitなどインスコしていないと怒られるのでまず先に 「[CentOS7+PHP7+Nginx+MariaDB+Redisの環境を作る方法](http://qiita.com/yudsuzuk/items/94fdc3dff58d37a9806f)」をみつつ、必要そうなアプリを先にインスコする。

```
sudo yum --enablerepo=epel,remi,remi-php70 install php70 php70-php-mcrypt php70-php-mbstring php70-php-fpm php70-php-gd php70-php-pecl-xdebug php70-php-pecl-redis php70-php-pecl-imagick-devel php70-php-pecl-imagick php70-php-mysqlnd php70-php-intl php70-php-bcmath php70-php-pecl-zip php70-php-xmlrpc php70-php-xml  php70-php-pecl-http php70-php-pecl-http-devel php70-php-opcache phpunit
```

手順は [Slim-Skeleton](https://github.com/slimphp/Slim-Skeleton) にも書いてあるけど。slim3 は、インストールするアプリ名ね。

```
$ composer create-project slim/slim-skeleton slim3
```

WebService化は、[User Guide Web Service](http://www.slimframework.com/docs/start/web-servers.html#apache-configuration) 手順に従って行えばよし。ルートにアクセスすると下記のようにでるとこまで進めておきます。

![image](https://qiita-image-store.s3.amazonaws.com/0/44540/3a03b567-d012-72f2-9eb3-978a8a123e83.png)

## ディレクトリの確認
いい感じにディレクトが作成される。追加したのは、classesを読み込むディレクトリを追加で作成したぐらい。

```
slim3
├── composer.json
├── composer.lock
├── classes     ←　こいつだけ作成した
├── logs
├── public
│   └── index.php
├── src
│   ├── dependencies.php
│   ├── middleware.php
│   ├── routes.php
│   └── settings.php
├── templates
│   └── index.phtml
└── vendor
```

## サンプルDBの作成
とりあえず MySQL に接続して色々やってみるためにテーブルとデータをさくっと作っておく。

```sql
CREATE TABLE `book` (
  `id` int(11) NOT NULL,
  `title` varchar(64) DEFAULT NULL,
  `name` varchar(32) DEFAULT NULL,
  `price` int(5) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8   
```

データも適当にいれます

```sql
INSERT INTO `book` VALUES (1,'双子の帝國','ふたごのていこく',300),(2,'進撃の巨人','singeki',500),(3,'となりの関くん','となりのせきくん',50000);
```

# MySQLにアクセスしてみる、接続先の設定～アクセスクラス作成～アクセスまで
とりあえずテンプレみたいな形で進めていきます。サンプルとおりですけどねｗ

## 接続先の設定

### src/settings.php データベース接続先情報を追加します。

```php:src/settings.php
  // DataBase(MySQL) settings
  'db' => [
      'host' => 'hostname',
      'port' => '3306',
      'user' => 'user',
      'pass' => 'passwd',
      'dbname' => 'test',
  ],
```

### src/dependencies.php データベースコンテナの定義

```php:src/dependencies.php
// MySQL
$container['db'] = function ($c) {
    $settings = $c->get('settings')['db'];
    $pdo = new PDO("mysql:host=" . $settings['host'] . ";dbname=" . $settings['dbname'] . ";port=" . $settings['port'],
        $settings['user'], $settings['pass']);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    $pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
    return $pdo;
};
```

## アクセスクラス作成
slimはどこでも自由奔放に記述できますが、ある程度お作法は決めておいた方がいいかな？と思うのでアクセスクラスとか作ってみます。

### classes/Mapper.php

```php:class/Mapper.php
abstract class Mapper {
  protected $db;
  public function __construct($db) {
    $this->db = $db;
  }
}
```

### classes/TestMapper.php

```php:TestMapper.php
class TestMapper extends Mapper
{
  public function getTests() {
    $sql = "select * from book";
    $stmt = $this->db->query($sql);
    $results = [];
    while($row = $stmt->fetch()) {
      $results[] = $row;
    }
    return $results;
  }
}
```

## 作成したクラスを読み込む

### public/index.php 
`require vendor` している次の行あたりに追加する。

```php:public/index.php
// class load
spl_autoload_register(function ($classname) {
  require (__DIR__ . "/../classes/" . $classname . ".php");
});
```

## uriの作成
`src/routes.php` に アクセスuriを追加する。
※`$app->get('/[{name}]',`の関数はコメントしておく。

```php:src/routes.php
$app->get('/book_api', function ($request, $response, $args) {
  error_reporting(0);

  $mapper = new TestMapper($this->db);
  $test = $mapper->getTests();

  ob_start();
  var_dump($test);
  $t = ob_get_contents();
  ob_end_clean();
  var_dump($test);

  return $response;
});
```

# book_api にアクセスしてみる。
結果、下記のようになればとりあえず MySQL にアクセスできて結果も取得していることも確認できる。

```text
array(3) { [0]=> array(4) { ["id"]=> string(1) "1" ["title"]=> string(15) "双子の帝國" ["name"]=> string(24) "ふたごのていこく" ["price"]=> string(3) "300" } [1]=> array(4) { ["id"]=> string(1) "2" ["title"]=> string(15) "進撃の巨人" ["name"]=> string(7) "singeki" ["price"]=> string(3) "500" } [2]=> array(4) { ["id"]=> string(1) "3" ["title"]=> string(21) "となりの関くん" ["name"]=> string(24) "となりのせきくん" ["price"]=> string(5) "50000" } }
```

# PHP-View 使ってみる
PHP-View が使えるのでテンプレートを使って出力してみる。

## src/routes.php に追加
renderer に渡すためのテンプレートと変数を渡す。

```php:src/routes.php
$app->get('/book_api2', function ($request, $response, $args) {
  $mapper = new TestMapper($this->db);
  $test = $mapper->getTests();
  $response = $this->renderer->render($response, "book_api.phtml", ["books" => $test]);
});
```

## templates にテンプレートファイルを作成
`templates/book_api.phtml` を作成する。読み込んだデータを全て出力するサンプル。

```html:templates/book_api.phtml
<table class="pure-table">
  <tr>
    <th>id</th>
    <th>title</th>
    <th>name</th>
  </tr>
<?php foreach($data['books'] as $test): ?>
  <tr>
    <td><?=$test['id'] ?></td>
    <td><?=$test['title'] ?></td>
    <td><?=$test['name'] ?></td>
  </tr>
<?php endforeach; ?>
</table>
```

# book_api2 にアクセスしてみる。
結果、下記のようになればとりあえず MySQL にアクセスできてテンプレートで出力いることを確認できる。

```text
id	title	name
1	双子の帝國	ふたごのていこく
2	進撃の巨人	singeki
3	となりの関くん	となりのせきくん
```

ここまでできれば色々と簡単そうにできそうだ。次回は、ログ出力とかとかやってみる。
と、これまでに参考にさせて頂いたサイト。

> [こんにちは Slim PHP framework](http://senta.me/blog/2014-10-30/hello-slim-php-framework/)
> [Slim(PHP)を使う時に參考にしたページ](http://fjmk.jp/blog/570)