YYPHP#63「EOLを迎えるPHP7.0を7.2に、PHP-FIGからSymfonyが離脱、大きめの機能の設計、リポジトリの使い方、LaravelでDDD風、初心者にLaravelのテスト、キーボードとエディタ、なぜtrueが返る」

これは2018年11月30日に開催したPHPerイベント[YYPHP#63]のイベントレポートです。

[YYPHP]は一言で「PHPerの部室」です。PHPについて、雑に、ゆるく、ワイワイ話し合う集いです。毎回お題を決めずに雑談を出発点にいろいろなことを突発的にやります。集まった人でコードリーディングをすることもあれば、一緒に開発ツールを触ってみたり、フレームワークについての情報交換をすることもあります。開催はほぼ**毎週**、高田馬場にて。

[YYPHP#63]: https://yyphp.connpass.com/event/106395/
[YYPHP]: https://yyphp.connpass.com/
YouTubeでの配信映像はこちら-> [#YYPHP #63【PHPの情報交換・ワイワイ話そう・仲間作り・ゆるめ・にぎやかめ】](https://youtu.be/X6BaydOwyRk)

![](https://qiita-image-store.s3.amazonaws.com/0/5354/6d9ce33d-f7df-be3e-66c2-9fd4078524f5.jpeg)

## EOLを迎えるPHP7.0を7.2にしたい

* PHP7.0が数日後にEOLを迎える、7.2にバージョンアップするときに気をつけたらいいことを聞きたい
* ローカルで7.2にあげてみたが、一発ではうまくいかなかった。
    * 10分くらいしかやってないので、原因特定はまだだけど。
* 時間がないなかでいかにやっていくかが課題
    * 1週間くらいでやりたい
* フレームワークはPhalconを使っている。
* クラス数は1000くらいのボリューム。
    * それなりにでかい。
* 5.4とか5.6→7にあげたことがあるが、
    * 本格的に上げる前に、ローカルで試して、問題点をリストアップしておいて、チームに共有するところまでしかやったことない。
* PhpUnitさえあれば・・
    * テストコードがあれば……
    * 全体的に書いてあるわけでないので……
* とりあえずChangelogを読む
    * http://php.net/manual/ja/migration71.incompatible.php
    * http://php.net/manual/ja/migration72.incompatible.php
* 4日で全単体テストを書いて1日で修正する
* PhpStanとかPhanの静的解析ツールで
    * [PHP開発でCIするならScrutinizer使ってみよう - Qiita](https://qiita.com/k-motoyan/items/a63d7add9dc35ae8317a)
* PhpStormのlanguage levelを7.2に引き上げて、Inspectionでチェックしてみるとか？
* そんなに無理やりアップデートしないといけないの？
    * いきなりやろうとなった
    * やめようと言ったほうが
* 5から7はけっこう直したけど7から7.2は互換性のない変更にひっかかるような凝ったプログラムは書いてないので外部パッケージが対応すればだいたいok
* composer.jsonにリストアップされてる、特定のライブラリーがPHPの新バージョンに、非対応だったりして動かなかったりするんですよね
    * Office系のファイルを触るのにphp-spreadsheetを使っているが、
        * 前身のphp-excelはPHP5までしか対応していなかった経験があるので、そのへんの互換性は気になるところです。

## PHP-FIGからSymfonyが離脱する件

* [PHP-FIG](https://www.php-fig.org/)からSymfonyが離脱することになって、PSRがなくなっちゃうかも？
* FIG(framework interop group) フレームワーク間の相互運用性を確保しようぜというグループ
* PHP-FIGとSymfonyの方針が合わないから抜けることに。
    * Symfony以外でもPHP-FIGから離脱するグループは、Laravel, Propel, Guzzle, Doctrine がある。
    * FIGが決めるプロトコルが
* 脱FIG組がPSRと違うプロトコルを定めていく可能性も……。
* PHPがフォークするわけではない。
* コーディング規約を始めとしたプロトコルに影響があるかも
* Symfonyプロジェクトのデベロッパは60万人いるので相当でかい。
* fabianさんがいやだーとなっているっぽい
    * [Fabien Potencierさんのツイート: "PHP-FIG is **not** about interoperability anymore, it's about creating an opinionated framework, a framework by committee..."](https://twitter.com/fabpot/status/1064946913596895232)
* [Symfony leaves PHP-FIG, the framework interoperability group | Packt Hub](https://hub.packtpub.com/symfony-leaves-php-fig-the-framework-interoperability-group/)
* autoloaderとcoding styleとphpdocあたりが残ればあとはまあいいかなという気も


## 大きめの機能の設計時に、将来をいかに予測して設計していくか？

* 大きめの機能の設計時に、将来をいかに予測して設計していくか？ その考え方を聞きたい
* データベース設計やクラス設計
    * 今後どんな機能が追加されるかわからない時に保守性をどうあげていくか
* 今わかってる必要最小限の機能を実装するのが一番いいと思う。
    * YAGNIみたいな？
    * これめっちゃ変更はいるって言ってたのに、1回も変わらなかったこともあるし。
    * 2回くらい変更が来たら、設計をちゃんとするという考え方もある
* 過度に対変更を考慮せず実際の設計の仕方でやっておくといい
* 大きめな機能とは
    * 会計システムに銀行連携を組み込みたいんだ、みたいな規模感
    * 順次大きい機能を分解して、ひとつひとつ実装していく
        * 最初は残高を参照できる機能を、次に振込できる機能をというかんじ
* 全く新規で開発していく時に、DB設計してリリースしたら設計を後悔した
* DBの設計や構造もリファクタリングしていく必要がある
    * DBの設計に直接依存しない層を作る
    * 諦めて作って、早々に作り直す
* うまくいって1年
* 知識がないときに設計しきるのは無理
    * その場合のしっぺ返しがひどい
    * あとでがっと作り変えないといけない
    * 最初はドメインの知識がないのでドメイン駆動も失敗しやすい
    * どんどん方向修正が必要になってくる
* ドメインがどんどん変更していってもいいように、DBはドメイン層から切り離された設計になってるといい
* スタートアップとかコンテキストが違うと
    * ビジネスが確立するのが先で、成功するか失敗するか自体不明のプロジェクトは、何も考えないで作っていく戦略もある。
        * その場合、しっぺ返し(書き直し)が来ることを覚悟しておく必要がある
* やっぱりYAGNIかな。気を回しすぎて無駄に複雑化すると後が大変なのでなるべくすっきり書いておくのがいいような気がする
* ユビキタス言語化した概念の関係が1対1, 1対多, 多対多は注意深く確認しておいた方がDBの手戻りを最小限にできると思います
* データベースの設計に依存しない層を作るには？
    * フレームワークのORMとかは、インフラ層に押し込めておく。
    * DBの変更がインフラ層にとどまる。
* 層を分けるほうが大事な場合もあるし、開発スピードが大事な場合もあるので、一概には言えない。
* あと、ここだけCRUD、ここだけ層を分けるといった、使い分けもできる。

## 私のリポジトリの使い方合ってる？

* Laravel: アーキテクチャ、サービス層とリポジトリを追加したが、モデルっぽい使い方をしてる気がして、どんなふうな考え方をしたらいいか聞きたい
* この記事を見てRepositoryを入れてみた
    * [バーガーショップで例えるオールアバウトでのLaravelアーキテクチャ - オールアバウトTech Blog](https://allabout-tech.hatenablog.com/entry/2016/11/29/100000)
    * Eloquentでどっからでも取ってくるようにしていたら、ぐちゃぐちゃなコードになってきたいのでRepositoryを導入した
* 「モデルっぽい」のモデルとは？
    * EloquentのModelのことです。
* LaravelでRepositoryパターン使わないという考えの人もいた
    * Model自体がRepositoryのように振る舞えるから
    * Eloquent以外のORMに差し替えたとき、Repositoryだけ差し替えればいいというメリットもあるが
* インターフェースの使い方も聞きたい
    * 抽象クラスの使い方はなんとなくわかるが
    * いろんなパターンがある
        * 実装を気にしたくないパターン
            * Repositoryの中でどのDBに依存するか気にしたくない場合
                * クライアントコードはRepositoryインターフェイスだけ気にする
                * Repository ... interface 
                * InmemoryRepository ... class
                * MySQLRepository ... class
    * インターフェイスは外とつなぐための見た目を定義するもの
        * ドリンクに「注ぐ」ってメソッドのシグネチャがったとして、
            * お茶もオレンジジュースも「注ぐ」を実装する必要がある
    * 実装がかわるシチュエーション
        * 単体テストを書くために
            * モックにさしかえたい
            * 最も頻繁に使う
        * ログの送信方法切り替える
        * 通知方法をEmailからSlackにきりかえる
    * あとで決めたいものはインターフェイスにできる
    * 実装が違うものを切り替える
        * クレジットカードのペイメントゲートウェイの切り替えとか
        * ソーシャルログインを切り替えるときとか
    * HDMIがインターフェイスだとすると、HDMIに対応したモニタは実装クラス


* [P of EAA: Active Record](https://www.martinfowler.com/eaaCatalog/activeRecord.html)

![](https://i.imgur.com/sIRlT2I.gif)


## LaravelでDDD風の実装をするには？

* LaravelでDDD風のコーディングに取り組み始めてみたところだが、Entityクラスの実装手法について伺いたい
* DDDの書籍を読むと概念的な説明が多くて頭に入ってこない。
    * ボトムアップDDDとか、ウェブ上の記事を見ている。
* DDDの集約(aggregate)
    * EntityがEntityを保つ場合、どう表現したらいいのか
    * Value Objectについても実装のしかたがこんなんでいいか気になっている
* Eventエンティティ
    * 参加者枠
    * 開催ステータス: Value Object
        * Enum
    * Eloquentを使わず深層までDDDでやる場合、基本的に全てをValue Objectにする
        * LaravelでやりたいならEloquent Adaptorを作って結合するなど
* Query Modelを作ったほうがいいタイミング
    * イベント一覧ページを出すとき、Entityを何百個も復元していると、手間ということもあるかもしれない
* CQRS
    * Stateを変更しないQueryの場合はValue Objectにせずデータだけ取ってくればいい
* DDD的なEntity上で子Entityをどう表現するか？
    * 操作できるのは集約ルート、保存も集約ルートごと。
    * 子Entityだけ保存するとかはだめ

## 初心者にLaravelのテストを教えたい

* PHP Laravelのテストについて、初心者に向けて体系的に教える場合、どんなコンテンツにしたらいいか相談したい
* Laravelでテストを書いたことある人
    * 7人(多い)
* 体系的というのは難しいですね
* Laravelに特価する理由は？
    * 一般論でもいいかなと思ったけど、文脈的にLaravelがいいかなと
* Railsチュートリアルはテスト書かせるので参考になるかも
* シンプルな機能をテスト駆動で作っていくドキュメントがあればいいかも
* 体系的に教えたい理由
    * 3時間のセッションをやる予定だから
* まず触ってもらって、あとで理由を説明するほうが、理解しやすいかも
* テストはこうあるべきみたいなことを10分位話してからがいいかも
* テストを書かなかったこうなるみたいな事例
    * 5.6が切れるて7.2に上げるのに大変
* LaravelにしかないAssertion
    * DB系、リクエスト系
* phpunitはじめての人対象だと基礎を教えるだけで終わりそうですが、laravel向けだとHTTPテスト(https://readouble.com/laravel/5.7/ja/http-tests.html)とかちょっと独特ですよね

## みんなキーボード何使ってる？ エディタ何使ってる？

* RubyはIDEじゃなくてもいいかんがあって、vim使ってるが、PHP書くときはPhpStorm使ってる。
    * 型とかアノテーションとかメソッド探索とかあっていいかなと
* Happy Hackingが2台が最高？
* Ergodoxを使っているがキーピッチが広すぎて
* うち心地で言ったらHappy Hackが最強
* PFUがErgodoxみたいなちゃんとしたキーボードを作ってください(願い)
* Happy Hacking User: 4名
* キーボード3万使った「頭おかしいんじゃない」と言われたことある
* キーボードは1日で一番触れている部分だから、高いものでもいいんじゃない？
* 使うインターフェイスが切り替わると、めっちゃ生産性おちる

## このコードはなぜtrueが返る？

```php
if(‘８’ == 0){echo ‘ture’;} // 8は全角
```

* [PHP: 比較演算子 - Manual](http://php.net/manual/ja/language.operators.comparison.php)
* [PHP: PHP 型の比較表 - Manual](http://php.net/manual/ja/types.comparisons.php)

これを全部覚えていなければ"=="は使わない

![](https://files.slack.com/files-pri/T6VH89ANP-FEHGJLRRC/php__php_________________-_manual.png)

## 開始前の雑談

### Connpassをスクレイピング
* 参加者一覧のHTMLを取ってきて、参加者のリストをMarkdwonで出力するプログラムを作た。
* 関数で組んでたが、クラスを使ってみようと思い、書き換えに着手してる。
* PhpQueryというライブラリ使ってる。
    * PhpQueryは7年位メンテされてないから、今は[symfony/dom-crawler]がいい気がする
    * CSS風のクエリーは、symfony/dom-crawlerに加えて、[symfony/css-selector]入れるとできるようになるよ

### エンジニアの登壇を応援する会

* エンジニアのアウトプットを応援する
* ぼくエンジニアの登壇を配信する会しようかな(reoring)
    * クラッシュアカデミーさんは結構やってますよね
    * [ITエンジニアのための動画サイト | crash.academy](https://crash.academy/)
    * 動画を撮影しに来てくれて、編集までやってくれる

### 差し入れありがとうございます

ariakiさん肉まんの差し入れありがとうございます！


[symfony/dom-crawler]: https://symfony.com/doc/current/components/dom_crawler.html
[symfony/css-selector]: https://symfony.com/doc/current/components/css_selector.html