PHP7.2から7.3へのマイグレーションガイド

PHP公式の[マイグレーションガイド](https://php.net/manual/ja/migration73.php)がまだ日本語訳されていない。


# PHP 7.2.x から PHP 7.3.x への移行

このマイナーバージョンアップには数多くの新機能があります。
また、互換性がない変更 が多少あるので、実運用環境のPHPをこのバージョンにあげる前にはテストすべきです。


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

PHP7.3の新機能。

### More Flexible Heredoc and Nowdoc Syntax

フレキシブルなヒアドキュメント。
[詳細はこちら](https://qiita.com/rana_kualu/items/a7c6be77e165bca0f3fc#flexible-heredoc-and-nowdoc-syntaxes)

### Array Destructuring supports Reference Assignments

分割代入および`list`がリファレンスを受け付けるようになった。
[詳細はこちら](https://qiita.com/rana_kualu/items/a7c6be77e165bca0f3fc#list-reference-assignment)

```php
[&$a, [$b, &$c]] = $d;
```

### Instanceof Operator accepts Literals

instanceofの左辺が[リテラルを受け入れる](https://3v4l.org/5AWfR)。

```php
	var_dump( 1 instanceof stdClass ); // false
```

ただし値は常にfalseになる。
いったい何の意味があるのかはよくわからない。

### CompileError Exception instead of some Compilation Errors

[ParseError](https://php.net/manual/ja/class.parseerror.php)と[Error](https://php.net/manual/ja/class.error.php)の間に[CompileError](https://php.net/manual/ja/class.compileerror)が追加された。
現在は[token_get_all](https://php.net/manual/ja/function.token-get-all.php)でTOKEN_PARSEフラグを使った際にしか発生しないが、今後増える可能性はある。

### Trailing Commas are allowed in Calls

関数呼び出しの末尾カンマが許可される。
[詳細はこちら](https://qiita.com/rana_kualu/items/a7c6be77e165bca0f3fc#allow-a-trailing-comma-in-function-calls)

### Argon2id Support

[password_hash](https://php.net/manual/ja/function.password-hash.php)関数の対応アルゴリズムにArgon2idが追加される。
[詳細はこちら](https://qiita.com/rana_kualu/items/48e6e4baaeb265ab9fa7#argon2-password-hash-enhancements)

### FastCGI Process Manager

ロギングのカスタマイズ用パラメータlog_limit、log_buffering、decorate_workers_outputが追加された。

#### log_limit

1行の文字数制限を指定する。

#### log_buffering

バッファを使わない実験的なログ書き出しを許可する。

#### decorate_workers_output

`catch_workers_output`が有効なときにログに出力される文字列装飾を無効化する。


### BC Math Functions

[bscale](https://php.net/manual/ja/function.bcscale.php)の引数がオプションになる。
返り値の型はboolからintになり、変更前のscale値が入ってくる。
[詳細はこちら](https://qiita.com/rana_kualu/items/a7c6be77e165bca0f3fc#no-way-to-get-current-scale-in-use)

### Lightweight Directory Access Protocol

LDAP関数の引数にLDAP Controlsが追加された。
[詳細はこちら](https://qiita.com/rana_kualu/items/e0aa20dc7f50173c3791#ldap-controls-support)

### Full Case-Mapping and Case-Folding Support

マルチバイト関数において、完全なケースマッピングがサポートされた。
[詳細はこちら](https://qiita.com/rana_kualu/items/e0aa20dc7f50173c3791#mbstring-support-for-full-case-mapping-and-case-folding)

```php
var_dump(mb_strtoupper("Straße"));
    // STRASSE >=7.3
    // STRAßE  < 7.3
```

### Case-Insensitive String Operations use Case-Folding

大文字小文字を区別しない関数が、文字列比較においてこれまでのcase-mappingではなくCase-Foldingを使うようになる、というようなことが書かれているようなのだが、どうも[そうは見えない気がして](https://3v4l.org/FEtd4)よくわからない。

### MB_CASE_TITLE performs Title-Case Conversion

mb_convert_caseにMB_CASE_TITLEを渡したときの挙動が変更になる。
のだが、`Cased and CaseIgnorable derived Unicode properties`というのが何なのかわから。
特にクオートやアポストロフィーが改善されるとも書いてあるのだが、[特に変化が無い](https://3v4l.org/DhHl2)ように見える。


### Unicode 11 Support

[Unicode 11](http://unicode.org/versions/Unicode11.0.0/)をサポートした。

### Long String Support

マルチバイト関数が2GB以上の文字列を扱えるようになった。
関数は耐えてもサーバが死にそう。

### Performance Improvements

マルチバイト関数のパフォーマンスが大幅に上昇した。
これは新機能に書くようなことなのだろうか？

### Named Captures Support

`mb_ereg`系の正規表現が[名前付きキャプチャに対応](https://3v4l.org/45KPM)した。

```php
mb_regex_encoding("UTF-8");
mb_ereg('(?<year>\d+)-(?<month>\d+)-(?<day>\d+)', '2018-12-31', $matches);
var_dump($matches);

/*
array(7) {
  [0]=>
  string(10) "2018-12-31"
  [1]=>
  string(4) "2018"
  [2]=>
  string(2) "12"
  [3]=>
  string(2) "31"
  ["day"]=>
  string(2) "31"
  ["year"]=>
  string(4) "2018"
  ["month"]=>
  string(2) "12"
}
*/
```

7.3未満の場合は同じ正規表現でもエラーにはならないが、単に無視されてyear/month/dayが入ってこない。

また[mb_ereg_replace](https://php.net/manual/ja/function.mb-ereg-replace.php)は`\k<>`で名前付きキャプチャを[参照できる](https://3v4l.org/1qDWQ)。

### Readline 

[readline_info](https://php.net/manual/ja/function.readline-info.php)にパラメータ`completion_append_character`、`completion_suppress_append`が追加された。
[libedit](https://www.thrysoee.dk/editline/)ではなく[libreadline](https://tiswww.case.edu/php/chet/readline/rltop.html)を使っている場合のみ使用可能。


## [新しい関数](https://php.net/manual/ja/migration73.new-functions.php)

PHP7.3で増えた関数、およびメソッド。

### array_key_first() / array_key_last()

配列のキーを取得する関数。
[詳細はこちら](https://qiita.com/rana_kualu/items/48e6e4baaeb265ab9fa7#array_key_first-array_key_last)

### hrtime()

ナノ秒単位の時刻を取得する関数。
[詳細はこちら](https://qiita.com/rana_kualu/items/b09ce2c20b2d8b70d916)

### is_countable()

count()できるかどうかを判断する関数。
[詳細はこちら](https://qiita.com/rana_kualu/items/a7c6be77e165bca0f3fc#is_countable-function)

### net_get_interfaces()

ネットワークインターフェイスを取得する関数。
[詳細はこちら](https://qiita.com/rana_kualu/items/a7c6be77e165bca0f3fc#add-net_get_interfaces)

### fpm_get_status()

FastCGIの情報を取得できるみたいだが、英語版ドキュメントすらまだなく、近場にFastCGI環境がなかったので詳細不明。
[このような出力になる](https://github.com/php/php-src/blob/php-7.3.0/sapi/fpm/tests/fpm_get_status_basic.phpt)ようだ。

### DateTime::createFromImmutable()

DateTimeImmutableからDateTimeを生成する。
[詳細はこちら](https://qiita.com/rana_kualu/items/a7c6be77e165bca0f3fc#add-datetimecreatefromimmutable-method)

### gmp_binomial() / gmp_kronecker() / gmp_lcm() / gmp_perfect_power()

gmpに二項分布、クロネッカー関数、最小公倍数、累乗数が追加された。
[詳細はこちら](https://qiita.com/rana_kualu/items/a7c6be77e165bca0f3fc#added-gmp_-function)

### Normalizer::getRawDecomposition() / normalizer_get_raw_decomposition() / Spoofchecker::setRestrictionLevel()

UTF-8文字列の[Decomposition Mappingプロパティ](http://unicode.org/reports/tr44/)を取得するらしいのだが、何のことだか[さっぱりわからない](http://nomenclator.la.coocan.jp/unicode/normalization.htm)。
[例](https://php.net/manual/ja/normalizer.getrawdecomposition.php#refsect1-normalizer.getrawdecomposition-examples)を手元で試してみたら、全て"no decomposition mapping"と[言われてしまった](https://3v4l.org/M4S2l)。

### ldap_add_ext() 他8関数

LDAP関連関数が[一](https://php.net/manual/ja/function.ldap-add-ext.php)[気](https://php.net/manual/ja/function.ldap-bind-ext.php)[に](https://php.net/manual/ja/function.ldap-delete-ext.php)[8](https://php.net/manual/ja/function.ldap-exop-refresh.php)[個](https://php.net/manual/ja/function.ldap-mod_add-ext.php)[増](https://php.net/manual/ja/function.ldap-mod_replace-ext.php)[え](https://php.net/manual/ja/function.ldap-mod_del-ext.php)[た](https://php.net/manual/ja/function.ldap-rename-ext.php)。
それぞれ[extの付かない関数](https://php.net/manual/ja/function.ldap-add.php)と同じだが、返り値がリソースになる。

### openssl_pkey_derive()

公開鍵暗号の共有鍵を生成する。
[詳細はこちら](https://qiita.com/rana_kualu/items/a7c6be77e165bca0f3fc#added-openssl_pkey_derive-function)

### socket_wsaprotocol_info_export() / socket_wsaprotocol_info_import() / socket_wsaprotocol_info_release()

何も情報が無いので詳細不明。
[テスト](https://github.com/php/php-src/blob/php-7.3.0/ext/sockets/tests/wsaprotocol_info_0.phpt)でも特に有用なことが書かれていない。
試してみたところではsocket_wsaprotocol_info_exportすると"php_wsa_for_1"のような文字列が得られ、それをsocket_wsaprotocol_info_importに渡すとSocketリソースに戻った。
Socketの永続化というイメージでいいのだろうか。


## [新しいグローバル定数](https://php.net/manual/ja/migration73.constants.php)


定数が100以上増えていてとても多いのだが、ほとんどは外部ライブラリの定数をPHPでもそのまま使えるようにしているだけのようだ。


### PASSWORD_ARGON2ID

password_hash関数のハッシュアルゴリズムArgon2idを表す定数。
[詳細はこちら](https://qiita.com/rana_kualu/items/48e6e4baaeb265ab9fa7#argon2-password-hash-enhancements)

### CURLAUTH_BEARER 他79定数

Curl関連の定数がやたら増えた。
単に[libcurl](https://curl.haxx.se/libcurl/)のオプションをそのまま持ってきただけ。

### FILTER_SANITIZE_ADD_SLASHES

FILTER_SANITIZE_MAGIC_QUOTESと同じ。
[詳細はこちら](https://qiita.com/rana_kualu/items/48e6e4baaeb265ab9fa7#added-the-add_slashes-sanitization-mode)

### JSON_THROW_ON_ERROR

json_decodeに失敗したときに例外を出すようにする。
[詳細はこちら](https://qiita.com/rana_kualu/items/a7c6be77e165bca0f3fc#json_throw_on_error)

### LDAP_CONTROL_ASSERT 他26定数

LDAP定数もやたら増えた。
こちらも[LDAPの定数](https://github.com/openldap/openldap/blob/master/include/ldap.h)を持ってきただけのようだ。

### MB_CASE_FOLD / MB_CASE_LOWER_SIMPLE / MB_CASE_UPPER_SIMPLE / MB_CASE_TITLE_SIMPLE / MB_CASE_FOLD_SIMPLE

[mb_convert_case](https://php.net/manual/ja/function.mb-convert-case.php)などで指定する変換モード。

### STREAM_CRYPTO_PROTO_SSLv3 / STREAM_CRYPTO_PROTO_TLSv1_0 / STREAM_CRYPTO_PROTO_TLSv1_1 / STREAM_CRYPTO_PROTO_TLSv1_2

SSLストリームに接続する際のTLSバージョンを限定する定数。
[stream_context_create](https://php.net/manual/ja/function.stream-context-create.php)の第二引数コンテキストパラメータに渡す。

### PGSQL_DIAG_SCHEMA_NAME 他6定数

PostgreSQLの[PGSQL_DIAG_SCHEMA_NAME](https://doxygen.postgresql.org/postgres__ext_8h.html)等をそのまま持ってきた。


## [下位互換性のない変更点](https://php.net/manual/ja/migration73.incompatible.php)

## Heredoc/Nowdoc Ending Label Interpretation

ヒアドキュメントのシンタックス改善に伴い、これまで問題なかったテキストがエラーになる可能性がある。
[詳細はこちら](https://qiita.com/rana_kualu/items/a7c6be77e165bca0f3fc#flexible-heredoc-and-nowdoc-syntaxes)

```php
$str = <<<FOO
   FOO
FOO;
// 7.3ではParse error、7.2まではOK
```

### Continue Targeting Switch issues Warning

Switch内でcontinueを使うとE_WARININGが発生する。

```php
while ($foo) {
    switch ($bar) {
      case "baz":
         continue;
   }
}
```

このcontinueは[switchからの脱出](https://php.net/manual/ja/control-structures.continue.php)を表しており[breakと同じ意味](https://qiita.com/msd_fms/items/de6eb5234960dc4125d2)だった。
他言語では『次のwhileに進む』を表すことが多いので、混同を避けるため警告を出すようにしたようだ。
"continue 2"は問題なく動作する。

### Strict Interpretation of Integer String Keys on ArrayAccess

[ArrayAccess](https://php.net/manual/ja/class.arrayaccess.php)を実装したクラスのオブジェクトに`$obj['1']`とアクセスした場合、offsetGetの引数には自動型変換により数値1が渡されていた。
今後は型変換しないようになる。

```php
class Test implements ArrayAccess {
  public function offsetGet($index){
      var_dump($index); // 7.3では'1'、7.2までは1
  }
}

$test = new Test();
$test['1'];
```

通常の配列は今までどおり自動型変換されるので注意。


### Static Properties no longer separated by Reference Assignment

これまではpublic staticプロパティを親クラスと子クラスで異なる値にすることができるという裏技があったのだが、この抜け穴が塞がれた。

```php
class Test {
    public static $x = 0;
}
class Test2 extends Test {}

Test2::$x = &$x;
$x = 1;

var_dump(Test::$x, Test2::$x); // 7.3では『1, 1』、7.2までは『0, 1』
```

裏技つーかバグだな。


### References returned by Array and Property Accesses are immediately unwrapped

ひとつの式でリファレンスに値を設定しつつ同時に使用した場合の動作が変更される。

```php
$arr = [1];
$ref =& $arr[0];
var_dump($arr[0] + ($arr[0] = 2)); // 7.3では3、7.2までは4
```

リファレンスを使わなければ問題は起こらないので問題は無い。

### Argument Unpacking of Traversables with non-Integer Keys no longer supported

Traversableが非整数キーの配列を返してきた場合、それを直接`...`に入れるとエラーが出るようになった。

```php
function gen() {
    yield 1.0 => 2;
}
var_dump(...gen()); // 7.3ではFatal error、7.2までは2
```

これまで動作していたのは偶然らしい。


### Miscellaneous


[ext_skel](https://php.net/manual/ja/internals2.buildsys.skeleton.php)が刷新された。
[PHP製](https://github.com/php/php-src/blob/php-7.3.0/ext/ext_skel.php)になり、外部依存がなくなった。つまりWindowsでも動作する。

BeOSがサポートされなくなった。

エラーハンドリングのEH_THROWモードについて、通常の例外と同様に[error_get_last](https://php.net/manual/ja/function.error-get-last.php)を出力しないようになった。
EH_THROWはエラーを例外に変換するという内部フラグで、たとえばDateTimeが使っている。

```php
try{
    new \DateTime("aa");
}catch(\Exception $e){
    var_dump(error_get_last()); // 7.3ではnull、7.2までは値が入っている
}
```

[TypeError](https://php.net/manual/ja/class.typeerror.php)で表示されるメッセージの型が、これまで『integer』『boolean』だったのが『int』『bool』になった。
なんで？

```php
new SplFixedArray('a');
    // 7.3はexpects parameter 1 to be int, string given
    // 7.2まではexpects parameter 1 to be integer, string given
```

[compact](https://php.net/manual/ja/function.compact.php)が存在しない変数にE_NITOCEを出すようになった。
[詳細はこちら](https://qiita.com/rana_kualu/items/48e6e4baaeb265ab9fa7#make-compact-function-reports-undefined-passed-variables)

[getimagesize](https://php.net/manual/ja/function.getimagesize.php)がこれまでBMP画像に"image/x-ms-bmp"を返していたのを、今後は"image/bmp"を返す。

[stream_socket_get_name](https://php.net/manual/ja/function.stream-socket-get-name.php)で返ってくるIPv6アドレスに大括弧が入るようになる。
たとえばこれまで`::1:1337`だったものが`[::1]:1337`になる。


### BCMath Arbitrary Precision Mathematics

[BCMath](https://php.net/manual/ja/ref.bc.php)のエラーが全てPHPでハンドリングされるようになった。
以前は一部のエラーが直接stderrに出力されていた。

```php
bcpow('1', '12345678901234567890');
    // 7.3ではE_WARNING
    // 7.2まではbc math error
```

[bcmul](https://php.net/manual/ja/function.bcmul.php)と[bcpow](https://php.net/manual/ja/function.bcpow.php)が第三引数の小数点以下桁数を律儀に守るようになった。
これまでは不要なら省略していた。

```php
var_dump(bcpow('1234567890', '1', 2));
    // 7.3では"1234567890.00"
    // 7.2までは"1234567890"
```

### IMAP, POP3 and NNTP

rshおよびsshで接続するIMAP設定オプション[imap.enable_insecure_rsh](https://github.com/php/php-src/commit/4288674651e18360e8e3988c528e9a8c66666ff0)が追加され、デフォルトが無効になった。
無効にしないとセキュリティの問題があるみたいなんだけどよくわからない。

### Multibyte String

名前付きキャプチャに対応したので、mb_ereg*関数の結果が変わる可能性がある。

### MySQL Improved Extension

プリペアドステートメントがDATETIME、TIME、TIMESTAMP型の小数点以下桁数を正しく処理するようになった。

### MySQL Functions (PDO_MYSQL)

PDO::ATTR_EMULATE_PREPARES=falseの場合、プリペアドステートメントについて同上。
PDO::ATTR_EMULATE_PREPARES=trueの場合は元々適切な処理を行っていたので影響を受けない。

### Reflection

[Reflection](https://php.net/manual/ja/book.reflection.php)で表示される型が、これまで『integer』『boolean』だったのが『int』『bool』になった。

ちなみに[gettype](https://php.net/manual/ja/function.gettype.php)は『integer』『boolean』のまま。

### Standard PHP Library (SPL)

SPLのオートロードが例外を出した場合、オートロードはそこで中断される。
これまではその後のオートロードも実行されていた。

### SimpleXML

[SimpleXML](https://php.net/manual/ja/book.simplexml.php)オブジェクトを計算式に突っ込んだ場合、値を適切な型で扱うようになった。
これまでは強制的に整数にされていた。

```php
  $foo = new SimpleXMLElement('<foo>1.9</foo>');
  echo $foo * 3; // 7.3では5.7  7.2までは3
```


## [PHP 7.3.x で推奨されなくなる機能](https://php.net/manual/ja/migration73.deprecated.php)

7.3から非推奨になる機能。
今回からE_DEPRECATEDなどが発生するようになり、基本的に次のメジャーバージョンで削除される。

### Case-Insensitive Constants

[define](https://php.net/manual/ja/function.define.php)の第三引数、大文字小文字を区別しないオプションが削除される。
[詳細はこちら](https://qiita.com/rana_kualu/items/48e6e4baaeb265ab9fa7#deprecate-and-remove-case-insensitive-constants)

### Namespaced assert()

名前空間内であろうともassert関数が定義できなくなる。
[詳細はこちら](https://qiita.com/rana_kualu/items/23b10fcefb552533b067#defining-a-free-standing-assert-function)

### Searching Strings for non-string Needle

[strpos](https://php.net/manual/ja/function.strpos.php)などの検索関数に数値を渡してもコードポイントと解釈されなくなる。
[詳細はこちら](https://qiita.com/rana_kualu/items/23b10fcefb552533b067#string-search-functions-with-integer-needle)

### Strip-Tags Streaming

fgetss、gzgetss、SplFileObject::fgetss、string.strip_tagsストリームフィルタが削除される。
[詳細はこちら](https://qiita.com/rana_kualu/items/23b10fcefb552533b067#fgetss-function-and-stringstrip_tags-filter)

### Data Filtering

定数FILTER_FLAG_SCHEME_REQUIREDとFILTER_FLAG_HOST_REQUIREDが削除される。
[詳細はこちら](https://qiita.com/rana_kualu/items/23b10fcefb552533b067#filter_flag_scheme_required-and-filter_flag_host_required-flags)

### Image Processing and GD

[image2wbmp](https://php.net/manual/ja/function.image2wbmp.php)が削除される。
[詳細はこちら](https://qiita.com/rana_kualu/items/23b10fcefb552533b067#deprecate-and-remove-image2wbmp)

### Internationalization Functions

[Normalizer::NONE](https://php.net/manual/ja/class.normalizer.php)が削除される。
これはPHPではなく[Normalizerの仕様](http://icu-project.org/apiref/icu4j/com/ibm/icu/text/Normalizer.html#NONE)のようだ。

### Multibyte String

`mb_ereg_**`系関数のエイリアス`mbereg_**`が削除される。
[詳細はこちら](https://qiita.com/rana_kualu/items/23b10fcefb552533b067#undocumented-mbstring-function-aliases)

### ODBC and DB2 Functions (PDO_ODBC)

ディレクティブ`pdo_odbc.db2_instance_name`が削除される。
[詳細はこちら](https://qiita.com/rana_kualu/items/23b10fcefb552533b067#pdo_odbcdb2_instance_name-phpini-directive)


## [その他の変更](https://php.net/manual/ja/migration73.other-changes.php)

### Set(raw)cookie accepts $option Argument

[setcookie](https://php.net/manual/ja/function.setcookie.php)および[setrawcookie](https://php.net/manual/ja/function.setrawcookie.php)が配列形式の引数を受け取れるようになった。
[詳細はこちら](https://qiita.com/rana_kualu/items/48e6e4baaeb265ab9fa7#same-site-cookie)

```php
setcookie('hoge', 'fuga', [
    'expires' => 3600,
    'path' => '/',
    'secure' => true,
    'httponly' => true,
    'samesite' => 'Strict',
]);
```

### New Syslog ini Directives

[error_log](https://php.net/manual/ja/errorfunc.configuration.php#ini.error-log)をsyslogにした際に、以下のディレクティブが使えるようになる。

#### syslog.facility

[ファシリティコード番号](https://tools.ietf.org/html/rfc3164#section-4.1.1)。

#### syslog.filter

メッセージフィルタ。現在は"all"・"no-ctrl"・"ascii"の3種類に対応。

#### syslog.ident

全てのメッセージの頭に付加される識別用文字列。


### Garbage Collection

[cyclic GC](https://php.net/manual/ja/features.gc.collecting-cycles.php)が強化されたため、パフォーマンスが大きく向上する可能性があるらしい。

### Miscellaneous

[var_export](https://php.net/manual/ja/function.var-export.php)が`(object)`キャストをそのまま出力するようになった。
これまでは`stdClass::__set_state()`を出力していた。

```php
var_export((object)'str');

// 7.3
(object) array(
   'scalar' => 'str',
)

// 7.2まで
stdClass::__set_state(array(
   'scalar' => 'str',
))
```	

[debug_zval_dump](https://php.net/manual/ja/function.debug-zval-dump.php)と[var_dump](https://php.net/manual/ja/function.var-dump.php)で循環参照をどこまで表示するかの階層が異なっていたのだが、var_dumpの出力に揃えられた。

```php
$a = new stdClass();
$a->a = &$a;

debug_zval_dump($a);

// 7.3
object(stdClass)#1 (1) refcount(2){
  ["a"]=>
  *RECURSION*
}

// 7.2
object(stdClass)#1 (1) refcount(2){
  ["a"]=>
  &object(stdClass)#1 (1) refcount(2){
    ["a"]=>
    *RECURSION*
  }
}

// var_dump 7.2も7.3も同じ
object(stdClass)#1 (1) {
  ["a"]=>
  *RECURSION*
}
```

[array_push](https://php.net/manual/ja/function.array-push.php)および[array_unshift](https://php.net/manual/ja/function.array-unshift.php)の第二引数がオプションになった。
何も渡さない場合は何もしない。


### Interactive PHP Debugger

未使用だった定数PHPDBG_FILE、PHPDBG_METHOD、PHPDBG_LINENO、PHPDBG_FUNCが削除された。

### FastCGI Process Manager

FastCGIで[getallheaders](https://php.net/manual/ja/function.getallheaders.php)が使えるようになった。
マニュアルでは5.4.0で使えるようになったとか書いてあるのだが全くそんなことはなく、[2012年に出されたバグレポ](https://bugs.php.net/bug.php?id=62596)が今回ようやく[マージされた](https://github.com/php/php-src/pull/3363)。

### Client URL Library

libcurl 7.15.5以上が必須になった。

### Data Filtering

FILTER_VALIDATE_FLOATが1000の位区切りを指定する`thousand`オプションをサポートしている。
デフォルトの`',.`はこれまでと互換性がある。
と書いてあるのだがFILTER_FLAG_ALLOW_THOUSANDは昔からあったような？

フィルタFILTER_SANITIZE_ADD_SLASHESがFILTER_SANITIZE_MAGIC_QUOTESのエイリアスとして追加された。
FILTER_SANITIZE_MAGIC_QUOTESは今後削除される可能性がある。

### FTP

デフォルトの転送モードがバイナリになった。

### Internationalization Functions

ICU56以降を使用している場合、`Normalizer::NONE`がDeprecatedになる。
また[Normalizer::normalize](https://php.net/manual/ja/normalizer.normalize.php)の引数として`Normalizer::FORM_KC_CF`が使えるようになる。

### JavaScript Object Notation

[json_decode](https://php.net/manual/ja/function.json-decode.php)および[json_encode](https://php.net/manual/ja/function.json-encode.php)のオプションJSON_THROW_ON_ERRORが追加された。
なおJSON_THROW_ON_ERRORよりもJSON_PARTIAL_OUTPUT_ON_ERRORが優先される。

### Multibyte String

configureオプション`--with-libmbfl`が削除された。

### ODBC (Unified)

ODBCRouterとBirdstepのサポートが廃止された。

### OPcache

`opcache.inherited_hack`ディレクティブが削除された。
実際にはPHP5.3以降[無視されていた](https://php.net/manual/ja/opcache.configuration.php#ini.opcache.inherited-hack)。

### OpenSSL

SSLストリームで`max_proto_version`および`min_proto_version`オプションに対応した。

### Regular Expressions (Perl-Compatible)

[Perl互換正規表現](https://php.net/manual/ja/book.pcre.php)がPCRE2にアップグレードされた。
[詳細はこちら](https://qiita.com/rana_kualu/items/a7c6be77e165bca0f3fc#pcre2-migration)

[preg_quote](https://php.net/manual/ja/function.preg-quote.php)が`#`をエスケープするようになった。


### Microsoft SQL Server and Sybase Functions (PDO_DBLIB)

空行をスキップする`PDO::DBLIB_ATTR_SKIP_EMPTY_ROWSETS`オプションが追加された。
TDSバージョンを取得する`PDO::DBLIB_ATTR_TDS_VERSION`オプションが追加された。
DATETIME2型はDATETIME型と同じように扱われるようになった。

### SQLite Functions (PDO_SQLITE)

データベースを読み取り専用で開く`[PDO::SQLITE_ATTR_OPEN_FLAGS=>PDO::SQLITE_READONLY]`オプションが追加された。

### Session Handling

[session_set_cookie_params](https://php.net/manual/ja/function.session-set-cookie-params.php)が配列形式引数を受け取れるようになった。

```php
session_set_cookie_params([
    'lifetime' => 3600,
    'path' => '/',
    'domain' => '.php.net',
    'secure' => true,
    'httponly' => true,
    'samesite' => 'Strict',
]);
```

samesiteには`Lax`および`Strict`を指定できる。

ディレクティブ`session.cookie_samesite`が追加された。
デフォルトは""で、これまでと同じ動作。

### Tidy

[tidyp](https://github.com/petdance/tidyp)でも動くようになった。
ただしリリース日を返すAPIが無いため[tidy::getRelease](https://php.net/manual/ja/tidy.getrelease.php)は"unknown"を返す。

### XML Parser

libxmlを使用している場合でも[xml_set_external_entity_ref_handler](https://php.net/manual/ja/function.xml-set-external-entity-ref-handler.php)のコールバックの返り値を評価するようになった。
これまでは単に無視されていた。

### Zip

バンドルされているlibzipは古いのでビルドは勧められないが、`--without-libzip`を指定すればいまだに可能。

### Zlib Compression

[compress.zlib](https://php.net/manual/ja/wrappers.compression.php)プロトコルラッパーに、圧縮レベルを指定できる`zlib/level`コンテキストオプションが追加された。


## [Windowsサポート](https://php.net/manual/ja/migration73.windows-support.php)

### More POSIX Conforming File Deletion

ファイルディスクリプタはデフォルトでread/write/deleteモードで開かれる。
これによって使用中のファイルを削除することが可能になる。
ファイル削除後は、そのファイルを開いているハンドルが全てクローズされるまで、同名のファイルを作ることはできない。


# 感想

新機能はこれまでに調べたことのある内容が大半でしたが、それ以外にも色々と細かい変化が多々ありますね。
非互換な部分も意外とたくさんありますが、現実的に問題が出そうなのはヒアドキュメントくらいではないでしょうか。

文字コード関連は正直さっぱりわからないので詳しい人頼んだ。