YYPHP#64「エディタ」「フレームワーク」「CSVを読み込ませる」「PHP 7.3.0の新機能」「単体テストの置き場」「リポジトリクラスが肥大化してくる」「リポジトリクラスが肥大化」「開発環境の構築」「DockerでPHP運用」

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

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

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

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

## みんなが使ってるエディタとかフレームワークについて聞きたい

* Editor
    * PhpStorm x 4
    * IntelliJ IDEA + PHP Plugin
    * VS Code x 3
    * vim
* Framework
    * Laravel x 6
    * Yii (v1)
    * CakePHP3 x 3
    * Bear.Sunday
    * まだつかってない
    * Lumen

* BEAR.Sunday
    * REST, AOP, DI
    * アスペクト指向とDependency Injectionが強力なのが強み
    * 全員に進められるフレームワークではない
        * Laravelとかオブジェクト指向を理解した上でBEAR.Sundayに来るのがおすすめ。
    * ORM
        * ORMはないので、他のフレームワークのORMとか、PDOとかを使う
* フレームワークが自由に選べるとかしたら？
    * 今だったらLaravel
    * 人口が多いから
* Symfonyはどうか？
    * 最近はあんまり新規では聞かない
* Laravelの学習コスト
    * 低い方だと思う。
* LaravelのORMは何？ Doctorine系？
    * EloquentというLaravel向けのORMが入ってる 
* Laravelの5系でも、マイナーバージョンが違うだけで、破壊的な変更があったりする

## 初歩的な質問

掲示板のアプリを作っている。CSVを読み込ませて、表示するのがうまくいかない件。


[PHP: array_reverse - Manual](http://php.net/manual/ja/function.array-reverse.php)

* CSVつらいので早めにDB使うようにすることをおすすめ。DBの勉強が必要なのでちょっと最初はハードル高く感じると思いますがわかってしまえばなぜ早く使わなかったんだと思うでしょう。
* そうですね。データ量が増えると処理も遅くなりますし。全体が見えないのでよくわかりませんが、排他制御など考えるとCSVでは辛いかも。

## PHP 7.3.0の新機能について
### 引数の最後に`,`を書けるようになった

```diff
 $this->someFunction(
     $arg,
+    $arg2,
 );
```

### array_key_first(last)関数の追加

```diff
 $items = [
     1 => 'a',
     2 => 'b',
 ];

-reset($items);
-$firstKey = key($items);
+$firstKey = array_key_first($items);
 var_dump($firstKey); // 1
```

### is_countable関数の追加


```diff
$items = null;

+if (is_countable($items)) {
-echo sprintf('There is %d items', count($items));
+     echo sprintf('There is %d items', count($items));
+}
```

### 安全なJSONパース

```diff
-json_encode($data);
+json_encode($data, JSON_THROW_ON_ERROR);
```

```diff
-json_decode($json);
+json_decode($json, null, null, JSON_THROW_ON_ERROR);
```

### Heredoc/NewdocのEOTがインデントできるようになった

```php
<?php   
class foo { 
    public $bar = <<<EOT 
        bar 
        EOT; 
}
````


### FFI(Foreign Function Interface)

→ https://github.com/dstogov/php-ffi

```php
<?php
$libc = FFI::cdef("
    int printf(const char *format, ...);
    const char * getenv(const char *);
    unsigned int time(unsigned int *);

    typedef unsigned int time_t;
    typedef unsigned int suseconds_t;

    struct timeval {
        time_t      tv_sec;
        suseconds_t tv_usec;
    };

    struct timezone {
        int tz_minuteswest;
        int tz_dsttime;
    };

	int gettimeofday(struct timeval *tv, struct timezone *tz);
", "libc.so.6");

$libc->printf("Hello World from %s!\n", "PHP");
var_dump($libc->getenv("PATH"));
var_dump($libc->time(null));

$tv = $libc->new("struct timeval");
$tz = $libc->new("struct timezone");
$libc->gettimeofday(FFI::addr($tv), FFI::addr($tz));
var_dump($tv->tv_sec, $tv->tv_usec, $tz);
?>
```

### 正規表現がPCRE2にアップグレードされる

* 振る舞いがかわる正規表現があるかもって書いてある
* こわ

[PHP: News Archive - 2018](http://php.net/archive/2018.php#id2018-12-06-1)


## 単体テストの置き場、どうあるべきか？

* Angularの単体テスト
    * テスト対象のコンポーネントの隣にテストコードを置くのが普通
        * Component.js と Component.test.js のように
        * 大きいテストは、testというディレクトリを切ることもある
    * メリット
        * テスト漏れがわかる
        * 仕様がわかる
        * ディレクトリごと移動できる
* Angularはこうだけど、PHPはどこに置くのが普通なのか？
* Repository.php
* RepositoryTest.php
* パターン
    * __test__/RepositoryTest.php
    * Tests/RepositoryTest.php
* テストファイルは近くにあったほうが良いと思ったが、PhpStormを使ったとき、所定のテストディレクトリに置くルールがあって、テストファイルとして認識されないのでPhpStorm都合で諦めた。
* JavaとかPHPだとsrcとtestsできっちりわける
* 同じnamespaceにするかどうか
    * 同じにした場合、間違えてuseしないように人間が気をつける必要がある
    * クラスが多くなると機械的に検出できるように明確に分けるようにしたほうが良いので、分けるべき
    * PSR-0だと、ベンダー名のところにTest/を入れるとか
        * grep 'use Test'とかで一網打尽できたらいいな
* 規模が大きくなったらディレクトリもnamespaceも分けるほうがいい
* 変更に追従するために
    * テストコードを直してから実装を直す

## リポジトリクラスが肥大化してくるのどうしたらいいか

* 分ける
    * 同じドメインにリポジトリが複数ある
* 責務は単一か？
* findByたくさんできる問題
    * Queryオブジェクトを渡す
    * Specification Patternを使う
    * 凝集性を考える必要がある
    * 1つのfindByごとに1クラスに分ける

## 開発環境の構築、みんなどうやってる？

* 開発サーバがあって、みんなでSSHで入って、そこで作業している。(OpenStack上)
    * 開発用インスタンスがひとつある
    * Ansibleでプロビジョンして、Composerとかもろもろ入った環境が自動的に立ち上がる。
    * ローカルにマウントして使う人もいる
    * みんなで共有するのはApacheとNginx
    * ソースはgitで管理している
    * オンプレで動いている
* DockerもしくはVagrantが多い
    * Vagrantが8割、Dockerは2割くらいじゃない？
    * Vagrantはバージョンアップすると壊れることが……
    * WindowsはDocker for Windowsがまともにうごかない
    * Windows 10 Proの人はSubsystem for Linuxが動くという噂も
    * MacはDocker for Macが一番簡単

## DockerでPHPで運用している人の話を聞きたい

* Dockerコンテナをそのままプロダクションで使っている？
    * Kubernatesでやってます
* CIからもデプロイできます？
    * できる
* PHP特有の問題はあった？
    * なかった
* スペックは結構高いマシンが必要？
    * Kubernatesでやるなら、5,6台は欲しい
    * 1台だけなら, docker-composeが一番手軽
    * 2台くらいなら、swarm

## 雑談開始前の雑談

* Bear.Sunday
    * PHP7.3に対応している
    * PHP7.0はもうすでにサポート切っている
* 「ウェブ魚拓」の作者のプログラマー新沼さん、握力160kgで腕相撲日本4位
    * [ちょまどMadoka＠エンジニア兼マンガ家さんのツイート: "握力日本一💪 && 腕相撲日本4位💪 の記録を持つプログラマー(「ウェブ魚拓」の作者)の 新沼さんと腕相撲(のフリ)をしてもらった！！ 改めて写真見ると 腕の太さ違い過ぎてめっちゃ笑ったwww 凄すぎる！… "](https://twitter.com/chomado/status/1053967470912917504)
* ジオシティーズが2019年03月で終わる
    * [サービス終了のお知らせ - Yahoo!ジオシティーズ](https://info-geocities.yahoo.co.jp/close/index.html)
        * 1994年アメリカで誕生
        * 1997年に日本法人ジオシティーズ株式会社が設立
        * 2019年3月31日にサービス終了
        * 2020年3月31日に全データ削除
    * IBMホームページビルダーで作ってFFFTPでアップするのをよくやってた