PHPのSlim3のリクエストオブジェクト・URLルーティング書き方まとめ

# 目次

[Slim3_PHP Advent Calendar 2018](https://qiita.com/advent-calendar/2018/slim3_php)
こちらから順番に追えます。

- 前回
    - [PHPのSlim3でサクッとHelloWorldを表示させてみよう（使い方）](https://qiita.com/http_kato83/items/2252b39e2499a43fcfd1)
- 次回
    - 未作成

# Slim3でのリクエスト振り分け方法
Slim3では基本的にpublicディレクトリのindex.phpでリクエストの振り分け（分岐）処理を行います。
では実際にどのような書き方があるか例を出していきます。

# 公式HPのトップのサンプルの場合

[公式HP](https://www.slimframework.com/)のトップページのサンプルは以下の通り
※コメントで補足を追加しています

```php
//前略

/**
 * GETメソッドのみ、他のメソッドでは弾く
 * {プロトコル}://{トップドメイン}/hello/{適当な文字（/とか?、#等を除く）1字以上}でマッチ
 */
$app->get('/hello/{name}', function (Request $request, Response $response, array $args) {
    //マッチした場合の処理を記述
    $name = $args['name'];
    $response->getBody()->write("Hello, $name");

    //最後に絶対レスポンス部をreturnするようにする
    return $response;
});

//以下略
```

試しに、[前回](https://qiita.com/http_kato83/items/2252b39e2499a43fcfd1)作ったHelloWorldの処理を少し変更してみましょう。
getをpostに変えるだけですが。

```php
<?php
use \Psr\Http\Message\ServerRequestInterface as Request;
use \Psr\Http\Message\ResponseInterface as Response;

//composerで追加したパッケージを一括でインポートしてくれる
require __DIR__. "/../vendor/autoload.php";

//インスタンス作成
$app = new \Slim\App;

//getをpostに変える
$app->post('/{name}', function ($request, $response, $args) {
	$name = isset($args['name']) ? $args['name'] : "World" ;
    $response->getBody()->write("Hello{$name}");

    return $response;
});

$app->run();
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/158800/39312b1f-f467-6c1f-5e5c-0cb6fcc6cd08.png)

しっかりと「このページはpostでしか受け付けてないのに、何でgetでアクセスしようとしているんだよ」と起こってくれました（ステータスコードも405になっています）。

# Slim3で対応しているリクエストメソッド

[公式HPドキュメント - リクエストについてのページ](http://www.slimframework.com/docs/v3/objects/request.html)

Slim3では以下のHTTPリクエストメソッドに対応しています。

- `GET`
- `POST`
- `PUT`
- `DELETE`
- `HEAD`
- `PATCH`
- `OPTIONS`
- ※全てのリクエストメソッドにマッチする`ANY`というのもある

前項のサンプルでgetをpostに変えた様にdeleteメソッドやputメソッドにすることも可能です。
※formのaction属性ではgetとpostしか選択できないので、他のメソッドを使うことはあまりないかと思いますが……

## 複数のリクエストに対応する方法

例えば、getとpostメソッド両方に対応したい場合はmapを利用し、以下のように記述します。
どのメソッドなのかの判定は2種類用意されています。

```php
$app->map(['get', 'post'], '/{name}', function ($request, $response, $args) {
    //getとpost両方にマッチさせつつ、それぞれ別の処理（分岐）をさせたい場合1
    if($request->getMethod() == 'GET'){
        //GETの場合
    }else{
        //POSTの場合
    }

    //getとpost両方にマッチさせつつ、それぞれ別の処理（分岐）をさせたい場合2
    var_export($request->isGet()); //getメソッドならtrueになる
    var_export($request->isPost()); //postメソッドならtrueになる
});
```

もちろん、`isGet`と`isPost`以外にも対応しています。

- $request->isGet()
- $request->isPost()
- $request->isPut()
- $request->isDelete()
- $request->isHead()
- $request->isPatch()
- $request->isOptions()

## 全てのリクエストメソッドに対応する方法

```php
$app->any('/{name}', function ($request, $response, $args) {
    //処理とreturn
});
```

# Slim3でののルーティングの書き方

[公式HPドキュメント - ルーティングについてのページ](http://www.slimframework.com/docs/v3/objects/router.html)

# `[]`オプション

`[]`に囲まれている箇所はあってもなくてもマッチするようにします。

```php
$app->post('/hoge[/{name}]', function ($request, $response, $args) {
    //処理とreturn
})
```

ネストにも対応しています。

```php
$app->post('/[hoge[/{name}]]', function ($request, $response, $args) {
    //処理とreturn
})
```

正規表現にも対応しています。

```php
$app->get('/hoge/{id:[0-9]+}', function ($request, $response, $args) {
    //処理とreturn
});
```

# 終わりの言葉

ここまでわかればだいぶWebアプリケーションをスムーズに作れるのではないでしょうか。
phpの標準で搭載されている`json_encode()`関数でapiを作ったりとか。

ただ、Slim3にもapi（json）を返すメソッドはあるので、それは次回以降にサンプルを交えて紹介していこうと思います。