【PHP】PHPフレームワーク「Flow」を試してみる～セッション編～

# 初めに
前回は[こちら](https://qiita.com/nnhkrnk/items/e98f25bec6cc067f24a4)の記事でFlowにおけるキャッシュの扱い方について解説しました。今回はセッションの扱いについて解説していきます。

# セッションの扱い方
セッションによくある「ECサイトの商品カゴ」の例で説明します。

まずは、セッションで扱いたい情報のクラスを用意しましょう。
以下のようなカゴEntityを作成しました。

```php

/**
 * @Flow\Scope("session")
 */
class CartEntity {

    /**
     * @var array
     */
    protected $items = array();

    /**
     * @param string $item
     * @return void
     * @Flow\Session(autoStart = true)
     */
    public function addItem($item) {
        $this->items[] = $item;
    }
    
}
```

## ポイント1：オブジェクトスコープをsessionに設定
オブジェクトスコープをsessionにすることで、CartEntityがセッション単位で作成されるようにします。

```php
/**
 * @Flow\Scope("session")
 */
class CartEntity {
```

## ポイント2：セッションを作成するタイミングを指定
``` @Flow\Session(autoStart = true)```を付与することで、そのメソッドが呼ばれたタイミングでセッションを作成するように指定します。すでにセッションが存在する場合は作成しません。

```php
    /**
     * @param string $item
     * @return void
     * @Flow\Session(autoStart = true)
     */
    public function addItem($item) {
        $this->items[] = $item;
    }
```

これだけでSessionを扱うことが可能になります。
続いて実際に試してみましょう。


# 試してみた
実際にセッションを扱ってみましょう。
プロジェクト構成は以下です。

```
Project/
  └ Packages/
      ├ Application/
      |    └ Neos.Welcome/
      |         ├ Classes/
      |              ├ Controller/
      |              |    └ CartController.php（★）
      |              |
      |              └ Domain/
      |                   └ Entity/
      |                        └ CartEntity.php（★）
      |
      ├ Framework/
      └ Libraries/
```

## 実装
まずはセッション管理するEntityを作成します。


```php CartEntity.php
<?php
namespace Neos\Welcome\Domain\Entity;

use Neos\Flow\Annotations as Flow;


/**
 * @Flow\Scope("session")
 */
class CartEntity {

    /**
     * @var array
     */
    protected $items = array();

    /**
     * @param string $item
     * @return void
     * @Flow\Session(autoStart = true)
     */
    public function addItem($item) {
        $this->items[] = $item;
    }
    
    /**
     * @return array
     */
    public function getItems() {
        return $this->items;
    }
    
}
```


Controllerクラスは以下です。
2つAPIを用意しました。
* カゴに商品を追加する
* カゴの商品を取得する

先ほど用意したCartEntityクラスは```@Flow\Inject```でDIするだけでOKです。


```php: CartController.php
<?php
namespace Neos\Welcome\Controller;

use Neos\Flow\Annotations as Flow;
use Neos\Flow\Mvc\Controller\ActionController;
use Neos\Welcome\Domain\Entity\CartEntity;

class CartController extends ActionController
{

    /**
     * @Flow\Inject
     * @var \Neos\Flow\Mvc\View\JsonView
     */
    protected $view;

    /**
     * @Flow\Inject
     * @var CartEntity
     */
    protected $cartEntity;

    /**
     * @return void
     */
    public function addAction(String $item)
    {
        $this->cartEntity->addItem($item);
        $this->view->assign('value', array('New item added'));
    }

    public function getAction()
    {
        $this->view->assign('value', $this->cartEntity->getItems());
    }
}
```

## 実行
実行してみます。

### 1. 初期状態確認
カートに商品が入ってないことを確認します。

* リクエスト
```
curl -i -X GET \
 'http://localhost:8081/Neos.Welcome/Cart/get'
```

* レスポンス
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/430841/c4b8b597-4b6e-6842-0d8d-d271ec1af193.png)


### 2. 商品追加
続いてカートにデータを登録してみます。

* リクエスト

```
curl -i -X POST \
   -H "Content-Type:application/json" \
   -d \
'{
  "item": "鉛筆"
}' \
 'http://localhost:8081/Neos.Welcome/Cart/add'
```

* レスポンス
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/430841/83a7da8f-c96c-92e1-2810-5f187cbb70f0.png)
レスポンスのSet-CookieでSessionIDを返してますね。


### 3. カゴ再確認
最後にもう一度カゴ取得APIをみたと呼んでみたところ、先ほどの商品が登録できたことを確認できました。
* リクエスト
```
curl -i -X GET \
 'http://localhost:8081/Neos.Welcome/Cart/get'
```

* レスポンス
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/430841/a1a23cda-281b-50b9-a57f-15109e4c08ad.png)


# 終わりに

今回はFlowにおけるセッションの扱い方について解説しました。
アノテーションを2つ追加するだけで簡単にセッション管理できて楽ですね。
また次の記事でお会いしましょう！

ここまで読んでいただきありがとうございました！

# 参考
https://flowframework.readthedocs.io/en/9.0/TheDefinitiveGuide/PartIII/SessionHandling.html