PHPWeekly 191114 簡単サマリー


PHPWeeklyの内容を簡単に翻訳し、興味のある内容に対してコメントを残します。

知っている知識の中で、ブログを書こうと思っていますが、間違ってる内容が含まれている可能性もあります。

間違っているところに対する指摘はいつも歓迎ですが、`非難・悪口`は求めていません。

## 始まる前に

1. PHP 7.4が発表され、SymfonyとLaravelにも7.4が適用されました。

2. ブログを作成しながら知らなかったことを調べたり、補足したりするのにかなり時間がかかりました。
やっぱり勉強し続けないとプログラマーとして衰えることも改めて思いました。

## 記事


### [PHP 7.4 ガイド](https://anastasionico.uk/blog/php-7-4-new-featureshttps://anastasionico.uk/blog/php-7-4-new-features)

新しく追加された機能を簡単に記録します。

#### 1. タイプ指定が可能になりました。

```php
class User {
    private int $id;
    public string $name = "Nico";
    public iterable $iterables;
    protected ClassName $classType;
    public ?string $void = null;
    public float $x, $y;
    var bool $flag;
}
```

#### 2. スプレッド演算子

Argument Unpackingとも呼ばれるスプレッド演算子は実は 5.6 バージョンから使用可能でしたが、関数の引数だけ使用可能でした。

PHP 7.4 バージョンからは配列を定義する時から使用可能になりました。

```php
$mammals = ['bear', 'ape'];
$animals = ['owl', 'crocodile', ...$mammals, 'frog'];
$domain = [...$animals, …$fungus, …$plant];
```

#### 3. アローファンクション

JavaScriptでアローファンクションが楽っていうことをわかりました。

やっとPHPでも使えるようになりました。

```php
$domain = ['bear', 'ape', 'pine', 'lettuce','porcino', 'portobello'];
$plurals = array_map(fn($domains) => count($domains), $domains);
```

#### 4. データが NULLの場合の対応演算子

```php
$this->request->data['theAnimalSpecieThatIsTheKingOfTheSavanna'] ??= 'none';
// 위의 문법은 정확히 아래와 같다.
$this->request->data['theAnimalSpecieThatIsTheKingOfTheSavanna'] = $this->request->data['theAnimalSpecieThatIsTheKingOfTheSavanna'] ?? 'none';
```

#### 5. Covariant リターン値と Contravariant 引数

説明がまとまらないため、二つに分けて説明します。

##### 5-1. Covariant リターン値

以前には関数をOverrideするとき、リターン値は親クラスのリターンタイプから帰ることができませんでした。

でも7.4バージョンではリターンタイプをサブタイプに変更することができます。


```php
interface Factory
{
    function make(): object;
}

class UserFactory implements Factory
{
    function make(): User
    {
        // implements ...
    }
}
```

##### 5-2. Contravariant 引数

子クラスで関数をOverrideする場合、引数をスーパータイプに変更することができます。

```php
interface Concatable
{
    function concat(Iterator $input)
}

class Collection implements Concatable
{
    function concat(iterable $input)
    {
        // implements ...
    }
}
```

#### 6. Weak References

C#, Java, Pythonには既に実装されているWeak ReferencesがPHPにも実装されました。

Weak Referencesは参照されたオブジェクトが破壊されると、参照したオブジェクトも破壊される参照の形態を意味します。

```php
$obj = new stdClass;
$weakref = WeakReference::create($obj);
var_dump($weakref->get());
unset($obj);
var_dump($weakref->get());
```

#### 7. プリローディング(Preloading)

サービスの速度を改善するために`OPCache`を使用してリクエストされたファイルを`Opcodes`に変換した経験があるかと思います。

その言葉の中で、`リクエストされた時に変換される`というのは`Opcodes`に変換されるのに時間がかかるとのことです。

7.4 バージョンではプリローディングを利用し、サーバーが起動されるときに特定の PHP ファイルセットをメモリーにロードすることで返還にかかる時間をなくすことができます。

問題は、一回プリローディングされたファイル変更の追跡ができないことです。

プリローディングされたファイルに変更がある場合、サーバーを再起動する必要があります。

#### 8. 新しいカスタムオブジェクト直列化(Serialization)方法

オブジェクトを直列化する方法として`__sleep()`マジックファンクション、`__wakeup()`マジックファンクション、
`Serializable`インタフェースを使用する3つの方法があったが、そこには問題がありました。 

7.4バージョンではこれを解決するため、`__serialize()`と`__unserialize()`マジックファンクションを追加しました。

```php
class A {
    private $prop_a;
    public function __serialize(): array {
        return ["prop_a" => $this->prop_a];
    }
    public function __unserialize(array $data) {
        $this->prop_a = $data["prop_a"];
    }
}
class B extends A {
    private $prop_b;
    public function __serialize(): array {
        return [
            "prop_b" => $this->prop_b,
            "parent_data" => parent::__serialize(),
        ];
    }
    public function __unserialize(array $data) {
        parent::__unserialize($data["parent_data"]);
        $this->prop_b = $data["prop_b"];
    }
}
```

#### 9. Foreign Function Interface: FFI

PHPで C 関数を呼出する時・C データ構造にアクセスするライブラリーがロードできるようになりました。

速度改善の側面ではよいところがあると思いますが、個人的に使うことがあるかと思ったら、あまりないかも...との感想です。

```php
$ffi = FFI::cdef(
    "int printf(const char *format, ...);",
    "libc.so.6");
$ffi->printf("Hello %s!\n", "world");
```

#### 10. 数字リテラルセパレーター(Numeric Literal Separator)

PHP 7.4では数字を分けるためにUnderscoreを使用することが可能になりました。

```php
6.674_083e-11; // float
299_792_458;   // decimal
0xCAFE_F00D;   // hexadecimal
0b0101_1111;   // binary
```

#### 11. Reflection for references

なんと翻訳すればいいかわかりません。
翻訳するとしたら `参照値を反映するためのもの`くらいですか？

以前には2つの変数が同じ内容を参照しているかを確認する作業が結構重い作業でしたが、
PHP 7.4に導入された`Reflection for references`を使用すればコストを削減することが可能になりました。

#### 12. `mb_str_split()` 함수 추가

`str_split()`関数は文字列を配列に変換します。

`mb_str_split()`は文字を`chunks(大きいかたまり)`でパーシングすることができます。

```php
print_r(mb_str_split("победа", 2));
 
--EXPECT--
 
Array
(
    [0] => по
    [1] => бе
    [2] => да
)
```

#### 13. パスワードハッシングレジストリ

`password_algos()`関数が追加され、登録済みのパスワードハッシングアルゴリズムのリストを確認することが可能になりました。


### [2019年度 Impact Awards 受賞者発表](https://www.phparch.com/2019/11/announcing-the-2019-impact-awards-winners/)

ベストツール、ベストフレームワークおよびアプリケーション、ベスト開発者経験、PHPコントリビューター、PHP 関連の会社に対するアワードがありました。

それぞれComposer、Laravel/Symfoy、GitHub、Sara Golemon、Automatticが受賞しました。

### [2019年ワードプレスで人気のあった5つのポートグラフィーテーマー](https://www.cloudways.com/blog/best-wordpress-photography-themes/)

WP関連内容はパスします。

### [ソーシャル戦略をアップグレードすることができる10個のワードプレスのFacebookプラグイン](https://kinsta.com/blog/wordpress-facebook-plugins/)

WP関連内容はパスします。

## チュートリアルおよびスキール

### [ワードプレスカレンダープラグインでコースのスケジュール・タイムテーブルを見せる方法](https://code.tutsplus.com/tutorials/show-course-schedules-and-timetables-with-a-wordpress-calendar-plugin--cms-34082)

WP関連内容はパスします。

### [APIの速度改善のためLaravelでHTTPセッションを無効化する方法](https://ma.ttias.be/disable-http-sessions-in-laravel-to-speed-up-your-api/)

API サーバーではセッションを利用して得られる利点がないし、セッション関連のファイルを探索するためにかなりのコストが必要です。

Laravelでセッションを無効かすることで簡単にAPIサーバーの性能を改善することが可能です。

`app/Http/Kernel.php`ファイルの`protected $middlewareGroups`から下記のミドルウェアを削除したら終わりです。

```php
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
```

### [Laminasへのマイグレーションテスト](https://akrabat.com/testing-migrating-to-laminas/)

Zend FrameworkがLaminasという名に代わりました。

変更点が結構あり、マイグレーションが簡単ではないそうです。

このブログを参考し、マイグレーションをテストしてみるのがおすすめです。

### [動的分析を使って0個のドキュメントタイプからフルドキュメントタイプ宣言まで](https://www.tomasvotruba.cz/blog/2019/11/11/from-0-doc-types-to-full-type-declaration-with-dynamic-analysis/)

PHPで引数とリターン値のタイプを宣言できるようになったのは多くの方々が知っていると思います。

ドキュメントを作成する為にいろんな方法を使ってきましたが、レガシーコードに対して手をつけることはやっぱり難しいですよね。

このブログでは`TypeCollector::collect($value, __METHOD__, 0)`という関数を利用し、１〜４週間のデータ収集を通じ、引数とリターン値にタイプを追加することを提案しています。

タイプ追加をしないといけない状況で不具合を起こさずタイプ追加ができる一つのいい方法ではないかと思います。


### [あなたのReactをビルドしてみましょう](https://pomb.us/build-your-own-react/)

Reactを使ってない為、パスします。

### [マルウェアをもっと深く分析する：パート２](https://securityboulevard.com/2019/11/down-the-malware-rabbit-hole-part-ii/)

マルウェアがどんな方式で動作しているのか分析したブログです。

内容を理解した訳ではないですが、動作原理を少しわかった後気づいたことは`だからネットからいろんなファイルをダウンロードするのが危ないんだ`ということでした。 

### [PHPのコードスタイルをコントロールしよう](https://tsh.io/blog/tips-on-keeping-php-code-under-control/)

コード品質を維持する為に使える３つのツールを紹介しました。

ECS、PHPStan、Psalmです。

実は現在僕は一人で作業しているので、今までコード品質・CIなどを全く考えてなかったです。

最近勉強会などを参加しながらコード品質に対して気づき、いろんなことを適用して見ようと思っているので、少しずつプロジェクトに導入することを考えています。

Unitテストから頑張ります。

※ 勉強しなきゃいけないところがが本当に多いですね。

### [ElasticsearchおよびKibanaを利用して開発環境のSymfonyログをビジュアル化する方法](https://jolicode.com/blog/how-to-visualize-symfony-logs-in-dev-with-elasticsearch-and-kibana)

Symfonyフレームワークを使っている方々にはいいブログかと思います。

### [Laravelアプリの新しいユーザーにウェルカムノーティフィケーション送信](https://freek.dev/1500-sending-a-welcome-notification-to-new-users-of-a-laravel-app)

[laravel-welcome-notification](https://github.com/spatie/laravel-welcome-notification) ライブラリーを利用して新しいユーザーにウェルカムメールとパスワード再設定を送信する方法に対して書いています。

### [PHPでjQueryを利用し、複数のテキストボックスを自動完成させる](https://www.webslesson.info/2019/11/autocomplete-textbox-with-multiple-field-using-jquery-in-php.html)

ユーザー経験を向上させる為のAjaxをどうやって利用するかに関するブログ。

最近はjQueryをしようしていない為、チェックだけしました。


## アナウンスメント

1. [PHP 7.4.0RC6 リリース](https://www.php.net/archive/2019.php#2019-11-14-1)

2. [Symfony 5.0.0-RC1 リリース](https://symfony.com/blog/symfony-5-0-0-rc1-released)

3. [Symfony 4.4.0-RC1 リリース](https://symfony.com/blog/symfony-4-4-0-rc1-released)

4. [Laravel 6.5.1 リリース](https://laravel-news.com/laravel-6-5-1)

5. [ワードプレス 5.2.4 アップデート](https://wordpress.org/news/2019/11/wordpress-5-2-4-update/)

## おもしろいプロジェクト、ツール、ライブラリー

PHPWeeklyへ紹介されたプロジェクトリストです。

おもしろいと思ったら参加してもよいかと思います。

1. [scarlets](https://github.com/ScarletsFiction/Scarlets): ウェブフレームワーク

2. [arrayy](https://github.com/voku/Arrayy): 配列操作ライブラリー

3. [izend](https://github.com/izend/izend): コンテンツマネージングの為のMVCエンジン

4. [simple-cache](https://github.com/voku/simple-cache): キャッシュサーバーと簡単にインターれくと可能なキャッシュレイヤー

5. [php-iban](https://github.com/globalcitizen/php-iban): 銀行アカウント情報の生成・パーシング・検証・エラーチェックのためのライブラリー

6. [gravity-pdf](https://github.com/GravityPDF/gravity-pdf): メール、pdf ダウンロードフォームを作ってくれるワードプレスプラグイン

7. [pastebin-php](https://github.com/alcohol/pastebin-php): PHPで実装されたpastebin。何かよくわからない。

8. [generators](https://github.com/bpocallaghan/generators): カスタムLaravelファイルジェネレーター

9. [sncredisbundle](https://github.com/snc/SncRedisBundle): SymfonyのためのRedisバンドル

10. [enhavo](https://github.com/enhavo/enhavo): Symfonyで作られたオープンソースCMS

11. [munus](https://github.com/munusphp/munus): PHPで関数型プログラミングをするためのライブラリー。

12. [slim4-skeleton](https://github.com/odan/slim4-skeleton): Slim4フレームワークのSkeleton。名前通り！