PHPバージョン変更点をピックアップ(5.4.x ～ 7.4.x)

どのバージョンで使えるようになった機能か、探すのに苦労することがあったので、一覧にしてみました。

8.0移行は[こちらです](https://qiita.com/RyutaKojima/items/b365df1bb58b7b876ce1)

# <i class="fa fa-leanpub"></i>[PHP 5.2.x から PHP 5.3.x への移行](http://php.net/manual/ja/migration53.php)

**新機能**

- [名前空間](http://php.net/manual/ja/language.namespaces.php) のサポートが追加されました。 
- [遅延静的束縛](http://php.net/manual/ja/language.oop5.late-static-bindings.php) のサポートが追加されました。 
- ジャンプラベル (制限付きgoto) のサポートが追加されました。 
- ネイティブ[クロージャ](http://php.net/manual/ja/functions.anonymous.php) (ラムダ/無名関数) のサポートが追加されました。 
- マジックメソッドが二つ追加。 __callStatic() と __invoke() 。 
- [Nowdoc](http://php.net/manual/ja/language.types.string.php#language.types.string.syntax.nowdoc) 構文がサポートされました。これは ヒアドキュメント のように動作しますが、シングルクォートで囲まれた文字列として扱われます。 
- [ヒアドキュメント](http://php.net/manual/ja/language.types.string.php#language.types.string.syntax.heredoc) 構文は、静的な クラスプロパティ/定数 を初期化できるようになりました。 
- ヒアドキュメント 構文は、ダブルクォートを使って宣言できるようになりました。これは Nowdoc 構文を補完するものです。 
- 定数 はクラスの外でも const キーワードを使って宣言できるようになりました。 
- [三項演算子](http://php.net/manual/ja/language.operators.comparison.php#language.operators.comparison.ternary) の短縮形式として ?: が使えます。 
- HTTPストリームラッパー は、200 から 399 までのステータスコードを成功したものとみなすようになりました。 
- 静的なメソッドに動的にアクセスできるようになりました。 

```php
class C {
   public static $foo = 123;
}

$a = "C";
echo $a::$foo;
```

- 例外 をネストできるようになりました。 
- 循環参照用のガベージコレクタが追加され、デフォルトで有効になりました。 
- mail() 関数が送信メールのログを記録できるようになりました (注意: この関数を使って送信されたメールのみが対象です)。 

# <i class="fa fa-leanpub"></i>[PHP 5.3.x から PHP 5.4.x への移行](http://php.net/manual/ja/migration54.php)

**新機能**

- [トレイト](http://php.net/manual/ja/language.oop5.traits.php)のサポートが追加されました。
- 配列の短縮構文が追加されました。 `$a = array(1, 2, 3); => $a = [1, 2, 3];`
- `foo()[0]` のように、関数の返り値を配列として扱えるようになりました。
- [クロージャ](http://php.net/manual/ja/functions.anonymous.php)(無名関数) が `$this` をサポートするようになりました。
- <?= が常に有効になりました。 short_open_tag の設定にかかわらずいつでも使えます。
- クラスのインスタンスを生成するときに、そのメンバーにアクセスできるようになりました (例: (new Foo)->bar())。
- Class::{expr}() 構文をサポートするようになりました。
- 二進数フォーマットが追加されました。0b001001101 のように使えます。
- パースエラー時のパーサからのメッセージや関数コール時の引数が間違っている場合の警告メッセージが改善されました。
- セッションモジュールで、ファイルのアップロード状況を追跡できるようになりました。
- [CLI モードで動く、開発用のウェブサーバー](http://php.net/manual/ja/features.commandline.webserver.php)が組み込まれました。


# <i class="fa fa-leanpub"></i>[PHP 5.4.x から PHP 5.5.x への移行](http://php.net/manual/ja/migration55.php)

**新機能**

- [ジェネレータ](http://php.net/manual/ja/language.generators.php)の追加。`yield`キーワードで利用します。
- [`finally`](http://php.net/manual/ja/language.exceptions.php#language.exceptions.finally) キーワードの追加
- `foreach` が `list()` に対応
- `empty()` が任意の式に対応
- array リテラルと string リテラルのデリファレンス
- ::class によるクラス名の解決
- OPcache 拡張モジュールの追加
- foreach が非スカラーのキーに対応
- GD の改良

**PHP コア関数のポリフィル（後方互換）**

- [array_column](https://github.com/ramsey/array_column)


# <i class="fa fa-leanpub"></i>[PHP 5.5.x から PHP 5.6.x への移行](http://php.net/manual/ja/migration56.php)

**新機能**

- 定数式:定数やプロパティの宣言、関数のデフォルト引数などで、スカラー式を扱えるようになりました。
- 配列も、 const キーワードで定数として定義できるようになりました。
- ... による[可変個引数関数](http://php.net/manual/ja/functions.arguments.php#functions.variable-arg-list)
- 累乗演算子 ** 
- use function および use const
- [hpdbg](http://phpdbg.com/docs)
- php://input が再利用可能に
- 2 ギガバイトより大きいサイズのファイルもアップロードできるようになりました。
- GMP での演算子オーバーロードのサポート
- hash_equals() による、タイミング攻撃に対応した文字列比較
- [__debugInfo()](http://php.net/manual/ja/language.oop5.magic.php#language.oop5.magic.debuginfo)
- gost-crypto ハッシュアルゴリズム
- SSL/TLS の改良
- pgsql の非同期サポート


# <i class="fa fa-leanpub"></i>[PHP 5.6.x から PHP 7.0.x への移行](http://php.net/manual/ja/migration70.php)

**[下位互換性のない変更点](http://php.net/manual/ja/migration70.incompatible.php)**

- エラーや例外の取り扱いの変更
- 変数の取り扱いの変更
- foreach の変更
- integer の取り扱いの変更
- 文字列の取り扱いの変更
- 削除された関数
 - `call_user_method()` および `call_user_method_array()`
 - `ereg*` 系のすべての関数
 - mcrypt のエイリアス
 - すべての ext/mysql 関数
 - すべての ext/mssql 関数
 - intl のエイリアス
 - set_magic_quotes_runtime()
 - set_socket_blocking()
     - かわりに stream_set_blocking() を使いましょう。
 - PHP-FPM における dl()
 - GD Type1 関数群
- 削除された INI 項目
 - 削除された機能
     - always_populate_raw_post_data
     - asp_tags
     - xsl.security_prefs
- 下位互換性のないその他の変更
 - 新しいオブジェクトを参照渡しで代入できない
     - new 文の結果を参照渡しで変数に代入することができなくなりました。
 - 無効なクラス名、インターフェイス名、トレイト名
 - ASP タグと script タグの廃止
 - 非互換のコンテキストからの呼び出しの削除
 - yield が右代入演算子に
 - 同じ名前のパラメータをひとつの関数に複数定義できない
 - 引数を調べる関数は、パラメータの その時点での 値を報告する
 - Switch 文に複数の default ブロックを書けない
 - $HTTP_RAW_POST_DATA の削除
 - INI ファイルにおける # 形式のコメントの削除
 - JSON 拡張モジュールが JSOND に置き換わる
 - 内部関数がオーバーフローしたときの挙動
 - 同値な要素の並び順
 - Mhash is not an extension anymore

**[新機能](http://php.net/manual/ja/migration70.new-features.php)**

- [スカラー型宣言](http://php.net/manual/ja/functions.arguments.php#functions.arguments.type-declaration) `function sumOfInts(int ...$ints)`
- 戻り値の型宣言 `function arraysSum(array ...$arrays): array`
- Null 合体演算子 `$username = $_GET['user'] ?? 'nobody';  // $username = isset($_GET['user']) ? $_GET['user'] : 'nobody';と同じ`
- 宇宙船演算子 `<=>`
- define() を用いた配列定数の定義
- 無名クラスをサポート
- Unicode コードポイントエスケープ構文
- Closure::call()
- unserialize() のフィルタリング
- IntlChar 
- Expectation
- use 宣言のグループ化
- ジェネレータでの return
- ジェネレータの委譲
- intdiv() による整数の除算
- session_start() にオプションの配列を渡せるようになりました。
- CSPRNG 関数：暗号論的に安全な整数値および文字列を生成する、 プラットフォームに依存しない二つの新しい関数が追加されました。 random_bytes() と random_int() です。
- list() が常に、 ArrayAccess を実装したオブジェクトをアンパックできるように
- [無名関数の即時実行(即時関数)に対応](http://qiita.com/shin1x1/items/b11cd22210fbb3305255) `(function(){echo'hoge';})();`
 - <i class="fa fa-exclamation-triangle" aria-hidden="true"></i>公式のドキュメントが見つからない:sweat_smile:

# <i class="fa fa-leanpub"></i>[PHP 7.0.x から PHP 7.1.x への移行](http://php.net/manual/ja/migration71.php)

**[新機能](http://php.net/manual/ja/migration71.new-features.php)**

- nullable な型 `function testReturn(): ?string { return null; }`
- void 関数 `function swap(&$left, &$right) : void {}`
- 対称的な配列の分解
    - 配列の短縮構文 ([]) を使って、 代入用に配列の値を取り出せるようになりました
    - `list($id1, $name1) = $data[0];`
    - `[$id1, $name1] = $data[0];`
- クラス定数のアクセス範囲指定 `public const, protected const, private const`
- iterable 擬似型 
- 例外処理における複数の例外の catch `catch (FirstException | SecondException $e)`
- list() におけるキーのサポート `list("id" => $id1, "name" => $name1) = $data[0];`
- 負の文字列オフセットのサポート
- ext/openssl における AEAD のサポート
- Closure::fromCallable() による callables から Closure への変換
- 非同期シグナルハンドリング
- ext/curl における HTTP/2 サーバープッシュのサポート

### 合わせて読みたい
- [PHP7.1β1の新機能](http://qiita.com/rana_kualu/items/572494021917fbb93c95)

# <i class="fa fa-leanpub"></i>[PHP 7.1.x から PHP 7.2.x への移行](http://php.net/manual/ja/migration72.php)

**[新機能](http://php.net/manual/ja/migration72.new-features.php)**

- object 型が新たに導入されました。
- 名前指定による拡張モジュールのロード
- 抽象メソッドのオーバーライド
- Sodium がコアモジュールに
- Argon2 によるパスワードハッシュ
- PDO の拡張文字列型 (以下の定数が追加されています。)
  - `PDO::PARAM_STR_NATL`
  - `PDO::PARAM_STR_CHAR`
  - `PDO::ATTR_DEFAULT_STR_PARAM`
- PDO のデバッグ情報にプリペアのエミュレートの内容を追加
- LDAP における拡張オペレーションのサポート
- ソケット 拡張モジュールでのアドレス情報の対応
  - `socket_addrinfo_lookup()`
  - `socket_addrinfo_connect()`
  - `socket_addrinfo_bind()`
  - `socket_addrinfo_explain()`
- パラメータの型の拡大変換
  - メソッドをオーバーライドしたりインターフェイスを実装したりする際に、 元のパラメータの型指定を省略できるようになりました。
- 名前空間のグループ指定における最後のカンマの許可
- Windows での proc_nice() のサポート
- pack() と unpack() でのエンディアンのサポート
- EXIF 拡張モジュールの機能追加
- PCRE の新機能
- SQLite3 での BLOB の書き込み
- Oracle OCI8 Transparent Application Failover コールバック
- ZIP 拡張モジュールの機能追加

# <i class="fa fa-leanpub"></i>[PHP 7.2.x から PHP 7.3.x への移行](http://php.net/manual/ja/migration73.php)

**[新機能](http://php.net/manual/ja/migration73.new-features.php)**

- PHP コア
    - ヒアドキュメントと Nowdoc構文 がより柔軟に
        - 文字列を閉じるマーカーの後に、セミコロンや改行文字を続ける必要はなくなりました。
        - それに加えて、文字列を閉じるマーカーはインデントされていても構いません。 この場合、インデントは文字列の全ての行から取り除かれます。
    - 配列へ分割して代入する操作が、リファレンスへの代入をサポート
        - `[&$a, [$b, &$c]] = $d`という文法を用いて、リファレンスへの代入をサポートしました。 同じ操作は、[list() ](https://www.php.net/manual/ja/function.list.php)関数でもサポートされています。
    - instanceof 演算子が、リテラルを受け入れるように
        - instanceof 演算子が、最初のオペランドにリテラルを受け入れるようになりました。この場合、結果は常に FALSE を返します。
    - いくつかのコンパイルエラーが、CompileError 例外に
        - [CompileError](https://www.php.net/manual/ja/class.compileerror.php) 例外が新たに追加されました。
    - 関数やメソッド呼び出しの後に、カンマを付けられるように
    - Argon2id のサポート
        - configure コマンドに `--with-password-argon2[=dir]` オプションを与えることで、Argon2i と Argon2id ハッシュが password_hash(), password_verify(), password_get_info(), および password_needs_rehash() でサポートされるようになります。
        - `PASSWORD_ARGON2ID` を使うことで、パスワードはハッシュ化され、検証されます。
        - password_*() 関数で Argon2i と Argon2id のサポートを使うには、PHP を libargon2 ≥ 20161029 とリンクする必要があります。
- php-fpm
    - FRM のロギングをカスタマイズするために、新しいオプションが追加されました。
        - `log_limit`
        - `log_buffering`
        - `decorate_workers_output`
- BC Math 関数
    - [bcscale()](https://www.php.net/manual/ja/function.bcscale.php) 関数は、現在使われている基数を取得する getter としても使えるようになりました。
- LDAP (Lightweight Directory Access Protocol)
    - LDAPコントロールの完全なサポートが [LDAP](https://www.php.net/manual/ja/book.ldap.php) クエリ関数と [ldap_parse_result()](https://www.php.net/manual/ja/function.ldap-parse-result.php) 関数に追加されました:
- マルチバイト文字列関数
    - 完全なケースマッピングとケースフォールディングのサポート
    - 大文字小文字を区別しない文字列操作は、ケースフォールディングを使う
        - 大文字小文字を区別しない文字列操作は、比較の際にケースマッピングではなく、ケースフォールディング を使うようになりました。 これは、より多くの文字が (大文字小文字を区別しないという意味で) 等価と見做されるようになったことを意味します。
    - MB_CASE_TITLE による Title-Case 変換
    - Unicode 11 のサポート
        - [マルチバイト文字列](https://www.php.net/manual/ja/book.mbstring.php) のデータテーブルは、Unicode 11 をサポートするように更新されました。
    - 長い文字列のサポート
        - [マルチバイト文字列関数](https://www.php.net/manual/ja/ref.mbstring.php) は 2GB 以上の文字列を正しくサポートするようになりました。
    - パフォーマンスの向上
        - マルチバイト文字列 拡張機能のパフォーマンスが全体的に大きく向上しました。大文字小文字のケースの変換関数で、一番大きな改善が見られます。
    - 名前付きキャプチャのサポート
        - mb_ereg_* 関数は、名前付きキャプチャをサポートしました。 mb_ereg() のようなマッチング関数は グループ番号と名前の両方を使って名前付きキャプチャを返します。これは PCRE に似た動作です:
        - `mb_ereg('(?<word>\w+)', '国', $matches); // => [0 => "国", 1 => "国", "word" => "国"];`
- Readline
    - completion_append_character と completion_suppress_append オプションのサポートが readline_info() 関数に追加されました。
    - これらのオプションは PHP が (libedit ではなく) libreadline とリンクされた場合のみ利用できます。

# <i class="fa fa-leanpub"></i>[PHP 7.3.x から PHP 7.4.x への移行](https://www.php.net/manual/ja/migration74.php)

**[新機能](https://www.php.net/manual/ja/migration74.new-features.php)**

- PHP Core
    - 型付きプロパティ
        - クラスのプロパティは、新たに型宣言をサポートするようになりました
    - アロー関数
        - [アロー関数](https://www.php.net/manual/ja/functions.arrow.php)は、暗黙的な値スコープを持った関数を定義する簡便な文法を提供します。
            - `$fnUpper = fn(string $lower) => mb_strtoupper($lower);`
    - [返り値の型を狭めたり、引数の型を広げたりする](https://www.php.net/manual/ja/migration74.new-features.php#migration74.new-features.core.type-variance)
    - Null 合体代入演算子(`??=`)
        ```
        $array['key'] ??= computeDefault();
        // は、以下にほぼ等しい
        if (!isset($array['key'])) {
            $array['key'] = computeDefault();
        }
        ```
    - 配列内での値のアンパック
        - ※連想配列(文字列をキーとして持つ配列)のアンパックには対応していないので注意が必要です（8.1でサポートされました）
        ```
        $parts = ['apple', 'pear'];
        $fruits = ['banana', 'orange', ...$parts, 'watermelon'];
        // ['banana', 'orange', 'apple', 'pear', 'watermelon'];
        ```
    - 数値リテラルのセパレータ 
        - 数値リテラルは、桁と桁の間にアンダースコアを挿入できるようになりました。
        - `299_792_458;   // decimal`
    - 弱参照
        - 弱い参照により、オブジェクトが破棄されるのを防がないオブジェクトへの参照を保持することが可能です。
    - __toString() から例外をスロー可能に
        - __toString() から例外をスローできるようになりました。以前は、この場合には致命的なエラーが発生していました。この関数内に既に存在する、回復可能な致命的なエラーは Error 例外クラスに変換されます。
- Standard
    - strip_tags() をタグ名の配列とともに使う
        - [strip_tags()](https://www.php.net/manual/ja/function.strip-tags.php) 関数は、許可するタグの配列も受け入れるようになりました。つまり、`strip_tags($str, '<a><p>')` の代わりに、 `strip_tags($str, ['a', 'p'])` と書けるようになったということです。
    - カスタムオブジェクトのシリアル化
        - 新しいカスタムオブジェクトのシリアル化の機構が追加されました。これは、新しいふたつのマジックメソッド __serialize と __unserialize を使います。
    - 引数を渡さずに array_merge 系の関数を使用する
        - [array_merge()](https://www.php.net/manual/ja/function.array-merge.php) および [array_merge_recursive()](https://www.php.net/manual/ja/function.array-merge-recursive.php) 関数は、引数なしでも呼び出せるようになりました。この場合、空の配列が返されます。これは、`array_merge(...$arrays)` のように、... 演算子と組み合わせて使う時に便利です。
    - [proc_open()](https://www.php.net/manual/ja/function.proc-open.php) 関数
        - proc_open() 関数は、コマンドの文字列ではなく、配列を受け入れるようになりました。この場合、プロセスは(shellを通さず) 直接オープンされ、PHP が必要な引数のエスケープをすべて行います。
        - proc_open() が、 redirect と null ディスクリプタをサポートしました。
    - libargon なしでの argon2i(d)
        - PHP が libargon を使わずにビルドされた場合、[password_hash()](https://www.php.net/manual/ja/function.password-hash.php) 関数は sodium 拡張機能の argon2i と argon2id を使った実装を使うようになります。