PHP公式のマイグレーションガイドがまだ日本語訳されていない。
PHP 7.2.x から PHP 7.3.x への移行
このマイナーバージョンアップには数多くの新機能があります。
また、互換性がない変更 が多少あるので、実運用環境のPHPをこのバージョンにあげる前にはテストすべきです。
新機能
PHP7.3の新機能。
More Flexible Heredoc and Nowdoc Syntax
フレキシブルなヒアドキュメント。
詳細はこちら
Array Destructuring supports Reference Assignments
分割代入およびlist
がリファレンスを受け付けるようになった。
詳細はこちら
[&$a, [$b, &$c]] = $d;
Instanceof Operator accepts Literals
instanceofの左辺がリテラルを受け入れる。
var_dump( 1 instanceof stdClass ); // false
ただし値は常にfalseになる。
いったい何の意味があるのかはよくわからない。
CompileError Exception instead of some Compilation Errors
ParseErrorとErrorの間にCompileErrorが追加された。
現在はtoken_get_allでTOKEN_PARSEフラグを使った際にしか発生しないが、今後増える可能性はある。
Trailing Commas are allowed in Calls
関数呼び出しの末尾カンマが許可される。
詳細はこちら
Argon2id Support
password_hash関数の対応アルゴリズムにArgon2idが追加される。
詳細はこちら
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の引数がオプションになる。
返り値の型はboolからintになり、変更前のscale値が入ってくる。
詳細はこちら
Lightweight Directory Access Protocol
LDAP関数の引数にLDAP Controlsが追加された。
詳細はこちら
Full Case-Mapping and Case-Folding Support
マルチバイト関数において、完全なケースマッピングがサポートされた。
詳細はこちら
var_dump(mb_strtoupper("Straße"));
// STRASSE >=7.3
// STRAßE < 7.3
Case-Insensitive String Operations use Case-Folding
大文字小文字を区別しない関数が、文字列比較においてこれまでのcase-mappingではなくCase-Foldingを使うようになる、というようなことが書かれているようなのだが、どうもそうは見えない気がしてよくわからない。
MB_CASE_TITLE performs Title-Case Conversion
mb_convert_caseにMB_CASE_TITLEを渡したときの挙動が変更になる。
のだが、Cased and CaseIgnorable derived Unicode properties
というのが何なのかわから。
特にクオートやアポストロフィーが改善されるとも書いてあるのだが、特に変化が無いように見える。
Unicode 11 Support
Unicode 11をサポートした。
Long String Support
マルチバイト関数が2GB以上の文字列を扱えるようになった。
関数は耐えてもサーバが死にそう。
Performance Improvements
マルチバイト関数のパフォーマンスが大幅に上昇した。
これは新機能に書くようなことなのだろうか?
Named Captures Support
mb_ereg
系の正規表現が名前付きキャプチャに対応した。
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は\k<>
で名前付きキャプチャを参照できる。
Readline
readline_infoにパラメータcompletion_append_character
、completion_suppress_append
が追加された。
libeditではなくlibreadlineを使っている場合のみ使用可能。
新しい関数
PHP7.3で増えた関数、およびメソッド。
array_key_first() / array_key_last()
配列のキーを取得する関数。
詳細はこちら
hrtime()
ナノ秒単位の時刻を取得する関数。
詳細はこちら
is_countable()
count()できるかどうかを判断する関数。
詳細はこちら
net_get_interfaces()
ネットワークインターフェイスを取得する関数。
詳細はこちら
fpm_get_status()
FastCGIの情報を取得できるみたいだが、英語版ドキュメントすらまだなく、近場にFastCGI環境がなかったので詳細不明。
このような出力になるようだ。
DateTime::createFromImmutable()
DateTimeImmutableからDateTimeを生成する。
詳細はこちら
gmp_binomial() / gmp_kronecker() / gmp_lcm() / gmp_perfect_power()
gmpに二項分布、クロネッカー関数、最小公倍数、累乗数が追加された。
詳細はこちら
Normalizer::getRawDecomposition() / normalizer_get_raw_decomposition() / Spoofchecker::setRestrictionLevel()
UTF-8文字列のDecomposition Mappingプロパティを取得するらしいのだが、何のことだかさっぱりわからない。
例を手元で試してみたら、全て"no decomposition mapping"と言われてしまった。
ldap_add_ext() 他8関数
LDAP関連関数が一気に8個増えた。
それぞれextの付かない関数と同じだが、返り値がリソースになる。
openssl_pkey_derive()
公開鍵暗号の共有鍵を生成する。
詳細はこちら
socket_wsaprotocol_info_export() / socket_wsaprotocol_info_import() / socket_wsaprotocol_info_release()
何も情報が無いので詳細不明。
テストでも特に有用なことが書かれていない。
試してみたところではsocket_wsaprotocol_info_exportすると"php_wsa_for_1"のような文字列が得られ、それをsocket_wsaprotocol_info_importに渡すとSocketリソースに戻った。
Socketの永続化というイメージでいいのだろうか。
新しいグローバル定数
定数が100以上増えていてとても多いのだが、ほとんどは外部ライブラリの定数をPHPでもそのまま使えるようにしているだけのようだ。
PASSWORD_ARGON2ID
password_hash関数のハッシュアルゴリズムArgon2idを表す定数。
詳細はこちら
CURLAUTH_BEARER 他79定数
Curl関連の定数がやたら増えた。
単にlibcurlのオプションをそのまま持ってきただけ。
FILTER_SANITIZE_ADD_SLASHES
FILTER_SANITIZE_MAGIC_QUOTESと同じ。
詳細はこちら
JSON_THROW_ON_ERROR
json_decodeに失敗したときに例外を出すようにする。
詳細はこちら
LDAP_CONTROL_ASSERT 他26定数
LDAP定数もやたら増えた。
こちらもLDAPの定数を持ってきただけのようだ。
MB_CASE_FOLD / MB_CASE_LOWER_SIMPLE / MB_CASE_UPPER_SIMPLE / MB_CASE_TITLE_SIMPLE / MB_CASE_FOLD_SIMPLE
mb_convert_caseなどで指定する変換モード。
STREAM_CRYPTO_PROTO_SSLv3 / STREAM_CRYPTO_PROTO_TLSv1_0 / STREAM_CRYPTO_PROTO_TLSv1_1 / STREAM_CRYPTO_PROTO_TLSv1_2
SSLストリームに接続する際のTLSバージョンを限定する定数。
stream_context_createの第二引数コンテキストパラメータに渡す。
PGSQL_DIAG_SCHEMA_NAME 他6定数
PostgreSQLのPGSQL_DIAG_SCHEMA_NAME等をそのまま持ってきた。
下位互換性のない変更点
Heredoc/Nowdoc Ending Label Interpretation
ヒアドキュメントのシンタックス改善に伴い、これまで問題なかったテキストがエラーになる可能性がある。
詳細はこちら
$str = <<<FOO
FOO
FOO;
// 7.3ではParse error、7.2まではOK
Continue Targeting Switch issues Warning
Switch内でcontinueを使うとE_WARININGが発生する。
while ($foo) {
switch ($bar) {
case "baz":
continue;
}
}
このcontinueはswitchからの脱出を表しておりbreakと同じ意味だった。
他言語では『次のwhileに進む』を表すことが多いので、混同を避けるため警告を出すようにしたようだ。
"continue 2"は問題なく動作する。
Strict Interpretation of Integer String Keys on ArrayAccess
ArrayAccessを実装したクラスのオブジェクトに$obj['1']
とアクセスした場合、offsetGetの引数には自動型変換により数値1が渡されていた。
今後は型変換しないようになる。
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プロパティを親クラスと子クラスで異なる値にすることができるという裏技があったのだが、この抜け穴が塞がれた。
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
ひとつの式でリファレンスに値を設定しつつ同時に使用した場合の動作が変更される。
$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が非整数キーの配列を返してきた場合、それを直接...
に入れるとエラーが出るようになった。
function gen() {
yield 1.0 => 2;
}
var_dump(...gen()); // 7.3ではFatal error、7.2までは2
これまで動作していたのは偶然らしい。
Miscellaneous
ext_skelが刷新された。
PHP製になり、外部依存がなくなった。つまりWindowsでも動作する。
BeOSがサポートされなくなった。
エラーハンドリングのEH_THROWモードについて、通常の例外と同様にerror_get_lastを出力しないようになった。
EH_THROWはエラーを例外に変換するという内部フラグで、たとえばDateTimeが使っている。
try{
new \DateTime("aa");
}catch(\Exception $e){
var_dump(error_get_last()); // 7.3ではnull、7.2までは値が入っている
}
TypeErrorで表示されるメッセージの型が、これまで『integer』『boolean』だったのが『int』『bool』になった。
なんで?
new SplFixedArray('a');
// 7.3はexpects parameter 1 to be int, string given
// 7.2まではexpects parameter 1 to be integer, string given
compactが存在しない変数にE_NITOCEを出すようになった。
詳細はこちら
getimagesizeがこれまでBMP画像に"image/x-ms-bmp"を返していたのを、今後は"image/bmp"を返す。
stream_socket_get_nameで返ってくるIPv6アドレスに大括弧が入るようになる。
たとえばこれまで::1:1337
だったものが[::1]:1337
になる。
BCMath Arbitrary Precision Mathematics
BCMathのエラーが全てPHPでハンドリングされるようになった。
以前は一部のエラーが直接stderrに出力されていた。
bcpow('1', '12345678901234567890');
// 7.3ではE_WARNING
// 7.2まではbc math error
bcmulとbcpowが第三引数の小数点以下桁数を律儀に守るようになった。
これまでは不要なら省略していた。
var_dump(bcpow('1234567890', '1', 2));
// 7.3では"1234567890.00"
// 7.2までは"1234567890"
IMAP, POP3 and NNTP
rshおよびsshで接続するIMAP設定オプションimap.enable_insecure_rshが追加され、デフォルトが無効になった。
無効にしないとセキュリティの問題があるみたいなんだけどよくわからない。
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で表示される型が、これまで『integer』『boolean』だったのが『int』『bool』になった。
ちなみにgettypeは『integer』『boolean』のまま。
Standard PHP Library (SPL)
SPLのオートロードが例外を出した場合、オートロードはそこで中断される。
これまではその後のオートロードも実行されていた。
SimpleXML
SimpleXMLオブジェクトを計算式に突っ込んだ場合、値を適切な型で扱うようになった。
これまでは強制的に整数にされていた。
$foo = new SimpleXMLElement('<foo>1.9</foo>');
echo $foo * 3; // 7.3では5.7 7.2までは3
PHP 7.3.x で推奨されなくなる機能
7.3から非推奨になる機能。
今回からE_DEPRECATEDなどが発生するようになり、基本的に次のメジャーバージョンで削除される。
Case-Insensitive Constants
defineの第三引数、大文字小文字を区別しないオプションが削除される。
詳細はこちら
Namespaced assert()
名前空間内であろうともassert関数が定義できなくなる。
詳細はこちら
Searching Strings for non-string Needle
strposなどの検索関数に数値を渡してもコードポイントと解釈されなくなる。
詳細はこちら
Strip-Tags Streaming
fgetss、gzgetss、SplFileObject::fgetss、string.strip_tagsストリームフィルタが削除される。
詳細はこちら
Data Filtering
定数FILTER_FLAG_SCHEME_REQUIREDとFILTER_FLAG_HOST_REQUIREDが削除される。
詳細はこちら
Image Processing and GD
image2wbmpが削除される。
詳細はこちら
Internationalization Functions
Normalizer::NONEが削除される。
これはPHPではなくNormalizerの仕様のようだ。
Multibyte String
mb_ereg_**
系関数のエイリアスmbereg_**
が削除される。
詳細はこちら
ODBC and DB2 Functions (PDO_ODBC)
ディレクティブpdo_odbc.db2_instance_name
が削除される。
詳細はこちら
その他の変更
Set(raw)cookie accepts $option Argument
setcookieおよびsetrawcookieが配列形式の引数を受け取れるようになった。
詳細はこちら
setcookie('hoge', 'fuga', [
'expires' => 3600,
'path' => '/',
'secure' => true,
'httponly' => true,
'samesite' => 'Strict',
]);
New Syslog ini Directives
error_logをsyslogにした際に、以下のディレクティブが使えるようになる。
syslog.facility
syslog.filter
メッセージフィルタ。現在は"all"・"no-ctrl"・"ascii"の3種類に対応。
syslog.ident
全てのメッセージの頭に付加される識別用文字列。
Garbage Collection
cyclic GCが強化されたため、パフォーマンスが大きく向上する可能性があるらしい。
Miscellaneous
var_exportが(object)
キャストをそのまま出力するようになった。
これまではstdClass::__set_state()
を出力していた。
var_export((object)'str');
// 7.3
(object) array(
'scalar' => 'str',
)
// 7.2まで
stdClass::__set_state(array(
'scalar' => 'str',
))
debug_zval_dumpとvar_dumpで循環参照をどこまで表示するかの階層が異なっていたのだが、var_dumpの出力に揃えられた。
$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およびarray_unshiftの第二引数がオプションになった。
何も渡さない場合は何もしない。
Interactive PHP Debugger
未使用だった定数PHPDBG_FILE、PHPDBG_METHOD、PHPDBG_LINENO、PHPDBG_FUNCが削除された。
FastCGI Process Manager
FastCGIでgetallheadersが使えるようになった。
マニュアルでは5.4.0で使えるようになったとか書いてあるのだが全くそんなことはなく、2012年に出されたバグレポが今回ようやくマージされた。
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の引数としてNormalizer::FORM_KC_CF
が使えるようになる。
JavaScript Object Notation
json_decodeおよびjson_encodeのオプション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以降無視されていた。
OpenSSL
SSLストリームでmax_proto_version
およびmin_proto_version
オプションに対応した。
Regular Expressions (Perl-Compatible)
Perl互換正規表現がPCRE2にアップグレードされた。
詳細はこちら
preg_quoteが#
をエスケープするようになった。
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が配列形式引数を受け取れるようになった。
session_set_cookie_params([
'lifetime' => 3600,
'path' => '/',
'domain' => '.php.net',
'secure' => true,
'httponly' => true,
'samesite' => 'Strict',
]);
samesiteにはLax
およびStrict
を指定できる。
ディレクティブsession.cookie_samesite
が追加された。
デフォルトは""で、これまでと同じ動作。
Tidy
tidypでも動くようになった。
ただしリリース日を返すAPIが無いためtidy::getReleaseは"unknown"を返す。
XML Parser
libxmlを使用している場合でもxml_set_external_entity_ref_handlerのコールバックの返り値を評価するようになった。
これまでは単に無視されていた。
Zip
バンドルされているlibzipは古いのでビルドは勧められないが、--without-libzip
を指定すればいまだに可能。
Zlib Compression
compress.zlibプロトコルラッパーに、圧縮レベルを指定できるzlib/level
コンテキストオプションが追加された。
Windowsサポート
More POSIX Conforming File Deletion
ファイルディスクリプタはデフォルトでread/write/deleteモードで開かれる。
これによって使用中のファイルを削除することが可能になる。
ファイル削除後は、そのファイルを開いているハンドルが全てクローズされるまで、同名のファイルを作ることはできない。
感想
新機能はこれまでに調べたことのある内容が大半でしたが、それ以外にも色々と細かい変化が多々ありますね。
非互換な部分も意外とたくさんありますが、現実的に問題が出そうなのはヒアドキュメントくらいではないでしょうか。
文字コード関連は正直さっぱりわからないので詳しい人頼んだ。