アップグレードのポイント Electronic Service Initiative, Ltd. http://www.es-i.jp/ 2016/6/27 © Electronic Service Initiative, Ltd. All Rights Reserved. 1
 Migrating from PHP 5.6.x to PHP 7.0.x を訳し、移行のポイントが解りやすいよ うに編集した文書です。 ◦ http://jp2.php.net/manual/en/migration70.php  ライセンス:Creative Commons Attribution 3.0 License ◦ https://creativecommons.org/licenses/by/3.0/legalcode  PHP 5.6からPHP 7.0へアップグレードする際に必要な情報を最初に記載しています。  新機能は後半に記載しています。  より詳しい情報はPHPのオンラインマニュアル、PHPのWikiページを参照してくだ さい。 ◦ http://jp2.php.net/manual/en/index.php ◦ https://wiki.php.net/rfc#php_70 2016/6/28© Electronic Service Initiative, Ltd. All Rights Reserved. 2
2016/6/28© Electronic Service Initiative, Ltd. All Rights Reserved. 3 弊社のコメント サンプルコードの出力結果 セキュリティ関連のコメント
2016/6/27© Electronic Service Initiative, Ltd. All Rights Reserved. 4
 廃止された拡張モジュール ◦ ereg ◦ mssql ◦ mysql ◦ sybase_ct  廃止されたSAPI ◦ aolserver ◦ apache ◦ apache_hooks ◦ apache2filter ◦ caudium ◦ continuity ◦ isapi ◦ milter ◦ nsapi ◦ phttpd ◦ pi3web ◦ roxen ◦ thttpd ◦ tux ◦ webjames 2016/6/28© Electronic Service Initiative, Ltd. All Rights Reserved. 5 PECLモジュールとして提供され ているが、メンテナンスされてい ない。基本的にはmysqliか PDO mysqlに移行する。 Apache HTTDを利用する場合、 apache2handler SAPIが利用 可能。
2016/6/27© Electronic Service Initiative, Ltd. All Rights Reserved. 6
 PHP7から多くの致命的エラー、回復可能エラーが例外に変更された。これらのエ ラーの例外はThrowableインターフェースを実装したErrorクラスを継承する。 ◦ Throwableインターフェースは全ての例外が継承している。 ◦ 例外オブジェクトのルートとなるインタフェースが変更されたため、カスタムエラー例外ハ ンドラーが、致命的な例外エラーなど、全ての例外を補足できない場合がある。 (Throwableを実装したオブジェクトを利用) ◦ PHP7でエラーがどのように処理されるか、より完全な解説はPHP7のマニュアルを参照する。 上記の記述は互換性に関する部分のみであることに注意する。 2016/6/28© Electronic Service Initiative, Ltd. All Rights Reserved. 7 Exception MyException FooException BarException Throwable Exception MyException FooException BarException Error MyError FooError BarError 従来 PHP7
 set_exception_handler() が登録した例外ハンドラーが受け取るエラーオブジェク トは、致命的なエラーの場合、Exceptionを実装したオブジェクトとは限らない。  PHP5と7の両方で例外ハンドラーを動作させる場合、タイプヒントを取り除かなけ ればならない。  PHP7専用の場合、ExecptionではなくThrowableをタイプヒントとして利用する。 <?php // PHP 5 era code that will break. function handler(Exception $e) { ... } set_exception_handler('handler'); // PHP 5 and 7 compatible. function handler($e) { ... } // PHP 7 only. function handler(Throwable $e) { ... } ?> 2016/6/27© Electronic Service Initiative, Ltd. All Rights Reserved. 8 PHP5とPHP7の両方で動作さ せる場合、例外ハンドラーの 引数のデータ型指定をしない。
 PHP7以前の内部クラスはコンストラクターが失敗した場合、NULLまたは利用不可 能なオブジェクト返していた。  全ての内部クラスはユーザー定義クラスと同様にExceptionを実装した例外クラスを 生成する。 2016/6/27© Electronic Service Initiative, Ltd. All Rights Reserved. 9 内部クラスとはPHP本体、拡張モジュール が定義するクラスのこと。
 PHP7はパースエラーでErrorを拡張したParseError例外を生成する。 ◦ 従来は例外ではなく致命的エラーが発生しプログラムの実行が停止されていた。  この変更によりeval()により評価されるコードはParseError例外に対応するコード 記述してパースエラーを処理できる。 2016/6/27© Electronic Service Initiative, Ltd. All Rights Reserved. 10 PHPコードを実行する場合にパース エラーをより取り扱いやすくなった
 全てのE_STRICTエラーは他のエラーレベルに変更された。 ◦ E_STRICT定数は定義されているが、error_reporting(E_ALL|E_STRICT)は追加のエラーを 捕捉しない。 状況 新しいエラー/動作 Resource型によるインデックス E_NOTICE 抽象スタティックメソッドへのアクセス エラー無し コンストラクターの再定義 エラー無し 継承シグニチャーのミスマッチ E_WARNING 複数のトレイトでの同じ(互換性あり)プロパティ エラー無し 静的プロパティへの非静的プロパティアクセス E_NOTICE 変数のみが参照として代入可能 Only variables should be assigned by reference E_NOTICE 変数のみが参照としてパラメーターとして利用可能 Only variables should be passed by reference E_NOTICE 非スタティックメソッドのスタティック呼び出し E_DEPRECATED 2016/6/27© Electronic Service Initiative, Ltd. All Rights Reserved. 11
 PHP 7はAST(抽象文法木)を利用する。  ASTにより以前のPHPではパーサーの制限により不可能であった事が可能になった。 しかし幾つかの特別なケースで後方互換性を損なう修正が行われた。 2016/6/27© Electronic Service Initiative, Ltd. All Rights Reserved. 12 ASTを取り扱う為の3rdパーティモジュールも公開さ れており、PHPスクリプトの内容より詳細に確認したり、 コードの挿入・削除を行える
 変数、プロパティ及びメソッドは 厳格に左から右に評価される。  古いPHPは評価順序が場合によって異なっていた。  PHP5と互換のコードを書くには、上記のルールに従い{}利用し明示的に評価順序を 指定する。(PHP5の解釈のように{}を利用する)  {}を利用して明示的に結合性を指定すればPHP5/7両方に互換性があるコードを記 述できる。 表現 PHP5の解釈 PHP7の解釈 $$foo['bar']['baz'] ${$foo['bar']['baz']} ($$foo)['bar']['baz'] $foo->$bar['baz'] $foo->{$bar['baz']} ($foo->$bar)['baz'] $foo->$bar['baz']() $foo->{$bar['baz']}() ($foo->$bar)['baz']() Foo::$bar['baz']() Foo::{$bar['baz']}() (Foo::$bar)['baz']() 2016/6/27© Electronic Service Initiative, Ltd. All Rights Reserved. 13 表現を見ただけで評価順序を判断でき るようになった
 list() は変数の逆の順序で代入しない。  list() は逆順でなく、順序通りに代入する。これは以下のサンプルコードの様に配列 []オペレーターを利用した場合にのみ影響する。 <?php list($a[], $a[], $a[]) = [1, 2, 3]; var_dump($a); ?>  一般的に、list()が代入する順序に頼るべきでない。これらの内部に依存する実装は 将来変わる可能性がある。 2016/6/27© Electronic Service Initiative, Ltd. All Rights Reserved. 14 注意事項として記載されている が、この動作が変わることはほ ぼ無いと思われる。 将来、コンパイラーや言語仕様の拡張で変更が 必要になる可能性は若干ある。 少なくともPHP7では変わらない。 出力は次のページ
 PHP 5: array(3) { [0]=> int(3) [1]=> int(2) [2]=> int(1) }  PHP 7: array(3) { [0]=> int(1) [1]=> int(2) [2]=> int(3) } 2016/6/27© Electronic Service Initiative, Ltd. All Rights Reserved. 15 PHP7からは直観通りに順序通 りに初期化される 本来、“,”(カンマ)オペレーターで区切られた 要素は“独立”しているはずで、同時実行性の 実装が行われた場合にこの動作が修正される 可能性はある。
 空のlist()はPHP7では利用できない。  以下はPHP7では利用できない。 <?php list() = $a; list(,,) = $a; list($x, list(), $y) = $a; ?>  list()による文字列の分割はできない。  list()の代わりに str_split()を利用する。 2016/6/28© Electronic Service Initiative, Ltd. All Rights Reserved. 16 致命的エラーが発生する PHP Fatal error: Cannot use empty list in - on line 2
 参照の代入で自動生成された配列の順序が変更された。  サンプルコード <?php $array = []; $array["a"] =& $array["b"]; $array["b"] = 1; var_dump($array); ?> 2016/6/28© Electronic Service Initiative, Ltd. All Rights Reserved. 17 PHP 5: array(2) { ["b"]=> &int(1) ["a"]=> &int(1) } PHP 7: array(2) { ["a"]=> &int(1) ["b"]=> &int(1) }
 変数の変数はglobal宣言できない。  {}を利用した構文を利用する。 <?php function f() { // Valid in PHP 5 only. global $$foo->bar; // Valid in PHP 5 and 7. global ${$foo->bar}; } ?>  一般的な原則として、単純な変数以外をグローバル変数として利用すべきではない。 2016/6/27© Electronic Service Initiative, Ltd. All Rights Reserved. 18 互換性が必要な場合、{}を利 用する。
 PHP5では冗長な()を利用して参照渡しパラメータの警告エラーを排除できた。  参照渡しパラメータの警告エラーは常に有効となった。 <?php function getArray() { return [1, 2, 3]; } function squareArray(array &$a) { foreach ($a as &$v) { $v **= 2; } } // PHP 7でE_NOTICEエラー squareArray((getArray())); ?> 2016/6/28© Electronic Service Initiative, Ltd. All Rights Reserved. 19 Notice: Only variables should be passed by reference in /tmp/test.php on line 13
 foreachがイテレートする変数に対する動作に変更が加えられた。  基本的にはイテレートする配列(変数)の内部ポインターとイテレートしている変 数に対する更新の動作が変更されている。  foreach は内部ポインターを更新しない  foreach への値渡しの配列はコピーに行われる  foreach 参照渡しの配列に対するイテレーションの改善  非Traversableオブジェクトのイテレーション 2016/6/27© Electronic Service Initiative, Ltd. All Rights Reserved. 20
 PHP5以前は、foreachでイテレーションすると内部ポインターが更新されていた。  以下のサンプルコードで示されるように、この動作は廃止された。 <?php $array = [0, 1, 2]; foreach ($array as &$val) { var_dump(current($array)); } ?> 2016/6/28© Electronic Service Initiative, Ltd. All Rights Reserved. 21 PHP 5: int(1) int(2) bool(false) PHP 7: int(0) int(0) int(0)
 デフォルトの値渡しモードの場合、foreachはイテレートされる変数のコピーに対し て変更を加える。  これはforeachがイテレートする配列に対して変更を全く加えない事を意味する。 <?php foreach ($array as $k => $v) { $k++; $v++; } 2016/6/27© Electronic Service Initiative, Ltd. All Rights Reserved. 22 イテレーション後の $arrayに影響しない
 参照渡しでイテレートする場合、foreachはイテレーションしている変数への変更は より直観的な動作となる。  例えば、配列に要素が追加される場合にイテレーションする場合、要素が追加され た配列をイテレートする。 <?php $array = [0]; foreach ($array as &$val) { var_dump($val); $array[1] = 1; } ?> 2016/6/28© Electronic Service Initiative, Ltd. All Rights Reserved. 23 イテレーション中の $arrayへの変更はイテ レーション動作に影響を 与える PHP 5: int(0) PHP 7: int(0) int(1)
 非Trabersableオブジェクトに対するイテレーションは参照渡しの配列と同様に動作 する。  これはオブジェクトにプロパティが追加・削除されるなど、変更を加えた場合の動 作がより直観に近い動作となる。 2016/6/27© Electronic Service Initiative, Ltd. All Rights Reserved. 24
2016/6/27© Electronic Service Initiative, Ltd. All Rights Reserved. 25
 PHP5以前は、無効な8進数リテラルはエラー無しに丸められていた。 ◦ 0128 は 012 として処理された。  PHP7からは無効な8進数はパースエラーを発生させる。 <?php $i = 0128; 2016/6/28© Electronic Service Initiative, Ltd. All Rights Reserved. 26 PHP Parse error: Invalid numeric literal in - on line 2
 負のビットシフトはArithmeticError例外を発生させる。 <?php var_dump(1 >> -1); ?> 2016/6/28© Electronic Service Initiative, Ltd. All Rights Reserved. 27 PHP 5: int(0) PHP 7: Fatal error: Uncaught ArithmeticError: Bit shift by negative number in /tmp/test.php:2 Stack trace: #0 {main} thrown in /tmp/test.php on line 2
 範囲外のビットシフト(シフト方向と無関係)は常に0となる。  PHP5以前はアーキテクチャーにより結果が異なった。 2016/6/27© Electronic Service Initiative, Ltd. All Rights Reserved. 28 システムが異なると実行結果を 予測できなかった
 PHP5 以前は、除算(/)モジュロ(%)オペレーターによる0除算でE_WARNING が発生しFALSEが結果として返された。  PHP7から、除算オペレーターは浮動小数点として、+INF,-INFまたはNANが返され る。モジュロオペレーターはE_WARNINGの代わりにDivisionByZeroError例外が 発生する。 <?php var_dump(3/0); var_dump(0/0); var_dump(0%0); ?> 2016/6/28© Electronic Service Initiative, Ltd. All Rights Reserved. 29 PHP 5: Warning: Division by zero in %s on line %d bool(false) Warning: Division by zero in %s on line %d bool(false) Warning: Division by zero in %s on line %d bool(false) PHP 7: Warning: Division by zero in %s on line %d float(INF) Warning: Division by zero in %s on line %d float(NAN) PHP Fatal error: Uncaught DivisionByZeroError: Modulo by zero in %s line %d
2016/6/27© Electronic Service Initiative, Ltd. All Rights Reserved. 30
 HEX(16進数)文字列を含む文字列は数値として扱わない。  サンプルコード <?php var_dump("0x123" == "291"); var_dump(is_numeric("0x123")); var_dump("0xe" + "0x1"); var_dump(substr("foo", "0x1")); ?> 2016/6/28© Electronic Service Initiative, Ltd. All Rights Reserved. 31 PHP 5: bool(true) bool(true) int(15) string(2) "oo" PHP 7: bool(false) bool(false) int(0) Notice: A non well formed numeric value encountered in /tmp/test.php on line 5 string(3) "foo“
 filter_var()は文字列が16進数の数値を含むかチェックでき、16進数文字列を整数に 変換できる。 <?php $str = "0xffff"; $int = filter_var($str, FILTER_VALIDATE_INT, FILTER_FLAG_ALLOW_HEX); if (false === $int) { throw new Exception("Invalid integer!"); } var_dump($int); // int(65535) ?> 2016/6/27© Electronic Service Initiative, Ltd. All Rights Reserved. 32
 Unicodeコードポイントエスケープ構文が追加された為、¥u{ を含む文字列は致命 的エラーを生成する可能性がある。  エラーを防ぐ為には最初の¥を¥でエスケープしなければならない。 2016/6/27© Electronic Service Initiative, Ltd. All Rights Reserved. 33 変数展開が無い‘(シングルクオート)やnowdoc では文字列がそのまま出力される
 call_user_method() と call_user_method_array() ◦ PHP 4.1.0 で非推奨とされ、代わりに call_user_func() と call_user_func_array() を利用 すべきとされていた。 ◦ これらの関数の代わりに変数関数と...オペレーターを検討しても良い。  Mcryptモジュールのエイリアス ◦ 非推奨の mcrypt_generic_end() は削除された。代わりに mcrypt_generic_deinit() を利 用する。 ◦ 非推奨の mcrypt_ecb(), mcrypt_cbc(), mcrypt_cfb() と mcrypt_ofb() は削除された。 代わりに mcrypt_decrypt() と適切な MCRYPT_MODE_* 定数を利用する。  Intlモジュールのエイリアス ◦ 非推奨の datefmt_set_timezone_id() の IntlDateFormatter::setTimeZoneID() エイリア スは削除された。代わりに datefmt_set_timezone() と IntlDateFormatter::setTimeZone() を利用する。 2016/6/27© Electronic Service Initiative, Ltd. All Rights Reserved. 34
 set_magic_quotes_runtime() ◦ set_magic_quotes_runtime() とそのエイリアスの magic_quotes_runtime() は削除され た。PHP 5.3.0で非推奨となり、PHP 5.4.0からmagic quote機能は削除され機能していない。  set_socket_blocking() ◦ set_socket_blocking() エイリアスは削除された。 stream_set_blocking() を利用する。  dl() in PHP-FPM ◦ dl() はPHP-FPMできなくなった。dl() はCLIとembed SAPIでのみ利用可能。  GDモジュールの Type1関数 ◦ PostScript Type1フォント対応関数がGDモジュールから削除された。 ◦ imagepsbbox() imagepsencodefont() imagepsextendfont() imagepsfreefont() imagepsloadfont() imagepsslantfont() imagepstext() ◦ 代わりにTrueTypeフォントとその関数を利用する。 2016/6/27© Electronic Service Initiative, Ltd. All Rights Reserved. 35
 以下のINI設定と関連する機能は削除された。 ◦ asp_tags ◦ xsl.security_prefs  xsl.security_prefs は削除された。代わりにXsltProcessor::setSecurityPrefs() メソッド 利用してプロセッサーごとにセキュリティプリファレンスを制御する。 ◦ always_populate_raw_post_data 2016/6/28© Electronic Service Initiative, Ltd. All Rights Reserved. 36 生のPOSTデータはphp://inputを 利用してアクセス可能
2016/6/27© Electronic Service Initiative, Ltd. All Rights Reserved. 37
 newステートメントで生成されたオブジェクトは参照として代入できない。 <?php class C {} $c =& new C; ?> 2016/6/28© Electronic Service Initiative, Ltd. All Rights Reserved. 38 PHP 5: Deprecated: Assigning the return value of new by reference is deprecated in /tmp/test.php on line 3 PHP 7: Parse error: syntax error, unexpected 'new' (T_NEW) in /tmp/test.php on line 3
 以下の名前はクラス、インターフェース、トレイト名として利用できない。 ◦ bool int float string NULL TRUE FALSE  上記に加えて、PHP7.0 ではエラーは発生しないが将来の為に予約されており、こ れらの名前を使うことは非推奨である。 ◦ resource object mixed numeric 2016/6/27© Electronic Service Initiative, Ltd. All Rights Reserved. 39 クラス名の制約は追加されたが、プロパティ・メソッ ド・定数名の制約はPHP7から緩和されている
 ASPタグとSCRIPTタグを利用したPHPコードの開始・終了は削除された。  削除されたタグ ◦ <% %> ◦ <%= %> ◦ <script language="php"> </script> 2016/6/27© Electronic Service Initiative, Ltd. All Rights Reserved. 40 scriptタグはほぼ利用されていな かったが、その存在がPHPスクリプト 実行脆弱性などの原因となっていた
 PHP5.6で非推奨となった非スタティックメソッドを非互換コンテクストから呼びだ しは、$thisの未定義によりE_NOTICEエラーが発生しNULLが返る。 <?php class A { public function test() { var_dump($this); } } // Note: Does NOT extend A class B { public function callNonStaticMethodOfA() { A::test(); } } (new B)->callNonStaticMethodOfA(); ?> 2016/6/27© Electronic Service Initiative, Ltd. All Rights Reserved. 41 出力は次のページ
 PHP 5.6: Deprecated: Non-static method A::test() should not be called statically, assuming $this from incompatible context in /tmp/test.php on line 8 object(B)#1 (0) { }  PHP 7: Deprecated: Non-static method A::test() should not be called statically in /tmp/test.php on line 8 Notice: Undefined variable: this in /tmp/test.php on line 3 NULL 2016/6/27© Electronic Service Initiative, Ltd. All Rights Reserved. 42
 結合性の変更により()が不必要になり、オペレーターの優先度がprintと=>の間に設定さ れた。  変更による動作の違いは以下のようになる <?php echo yield -1; // Was previously interpreted as echo (yield) - 1; // And is now interpreted as echo yield (-1); yield $foo or die; // Was previously interpreted as yield ($foo or die); // And is now interpreted as (yield $foo) or die; ?>  これらの違いをなくすには明示的に()を利用する。 2016/6/27© Electronic Service Initiative, Ltd. All Rights Reserved. 43 結合性と優先度の変更でより コードが記述し易くなった
 PHP7から同じ名前の引数を2つ以上定義できない。  以下のコードはE_COMPILE_ERRORとなる。 <?php function foo($a, $b, $unused, $unused) { // } ?> 2016/6/27© Electronic Service Initiative, Ltd. All Rights Reserved. 44 そもそもコードとしておかしいモノがエラーで 検出可能になった
 PHP7からswitch文に複数のdefaultブロックは記載できない。  以下のコードはE_COMPILE_ERRORを発生させる。 <?php switch (1) { default: break; default: break; } ?> 2016/6/28© Electronic Service Initiative, Ltd. All Rights Reserved. 45 そもそもコードとしておかしいモノがエラーで 検出可能になった
 $HTTP_RAW_POST_DATA は削除された。  代わりに php://input を利用する。 2016/6/27© Electronic Service Initiative, Ltd. All Rights Reserved. 46 標準入力。 他のストリームリソースと同様に扱える。
 # によるINIファイルのコメントは廃止された。  ; (セミコロン)を代わりに利用する。  この変更はphp.iniファイル、 parse_ini_file() と parse_ini_string() に適用される。 2016/6/27© Electronic Service Initiative, Ltd. All Rights Reserved. 47
 JSON拡張モジュールはJSONDライブラリを利用するように変更された。この為、 以下の互換性問題が生まれた。  数値は小数点(ピリオド)で終わってはならない。 ◦ 34. は 34.0 または 34 でなければならない  べき乗記号(e)の直前に小数点(ピリオド)があってはならない。 ◦ 3.e3 は 3.0e3 または 3e3 と記載しなければならない 2016/6/27© Electronic Service Initiative, Ltd. All Rights Reserved. 48 PHP以外の処理系でも問題となる為、 そもそもこのような記述はすべきで はない
 PHP5の内部関数は浮動小数点型から整数型に変換する場合に大きすぎる浮動小数 点データが丸められてもエラー・例外が無かった。  PHP7からE_WARNINGエラーが発生し、NULLが返される。 2016/6/27© Electronic Service Initiative, Ltd. All Rights Reserved. 49 オーバーフローは無視するのではなく、 対処するモノ セキュアなプログラミングの基本
 論理値を返すべきカスタムセッションハンドラーでFALSEまたは-1を返した場合は E_ERRORとなる。 ◦ GCハンドラーは削除したセッション数を返す。GCハンドラーは-1を返した場合、GC機能が 無いまたは不必要であることを意味する。  これらの関数で論理値、-1、0以外の戻り値を返した場合、E_WARNINGが発生す る。 2016/6/27© Electronic Service Initiative, Ltd. All Rights Reserved. 50 出鱈目な戻り値を受け付けなくなっただけ
 func_get_arg() と func_get_args() はパラメーターが変更されている場合でも、 渡された際の値を返していた。  PHP7からは現在の値を返す。 ◦ パラメーター変数が変更された場合、変更後の値が返る。 2016/6/27© Electronic Service Initiative, Ltd. All Rights Reserved. 51
2016/6/27© Electronic Service Initiative, Ltd. All Rights Reserved. 52
 PHP 4形式のコンストラクター(クラス名と同じメソッ名)は非推奨となり、将来 削除される。 ◦ PHP8で削除される可能性が高い。  PHP 7はPHP 4形式のコンストラクターのみが定義されている場合、 E_DEPRECATEDエラーを発生させる。 ◦ __construct()メソッドがある場合は影響しない。 <?php class foo { function foo() { echo 'I am the constructor'; } } ?> 2016/6/28© Electronic Service Initiative, Ltd. All Rights Reserved. 53 Deprecated: Methods with the same name as their class will not be constructors in a future version of PHP; foo has a deprecated constructor in example.php on line 3
 非スタティックメソッドのスタティックコールは非推奨となり、将来削除される可 能性がある。 ◦ PHP8で削除される可能性が高い。 <?php class foo { function bar() { echo 'I am not static!'; } } foo::bar(); ?> 2016/6/28© Electronic Service Initiative, Ltd. All Rights Reserved. 54 Deprecated: Non-static method foo::bar() should not be called statically in - on line 8 I am not static!
 password_hash() のソルトオプションの利用は非推奨となった。 ◦ この関数は自動的に暗号理論的に安全なランダムなソルトを生成し、手動によるソルト値の 設定を必要としない。  これはユーザーが安全でないソルトを設定することが多いことが理由である。 ◦ ソルトの値はランダムな値でなければならない 2016/6/27© Electronic Service Initiative, Ltd. All Rights Reserved. 55 password_hash()のようにセキュリティに直接 影響するAPIにも誤用が多い!!
 capture_session_meta SSL コンテクストオプションは非推奨となった。  SSLメタデータは stream_get_meta_data() を利用して取得する。 2016/6/27© Electronic Service Initiative, Ltd. All Rights Reserved. 56
 以下の関数は非推奨となった ◦ ldap_sort() 2016/6/27© Electronic Service Initiative, Ltd. All Rights Reserved. 57
2016/6/27© Electronic Service Initiative, Ltd. All Rights Reserved. 58
 debug_zval_dump() は“int” ではなく “long”, “float” ではなく “double” と出力 する。  dirname() はオプションの第二引数(深さ)を取り、与えられたディレクトリから 深さ引数までのディレクトリ文字列を返す。  getrusage() Windowsプラットフォームでもサポートされた。  mktime() と gmmktime() は is_dst 引数を受け付けなくなった。  preg_replace() は “¥e” (PREG_REPLACE_EVAL)のサポートを廃止した。代わり に preg_replace_callback() を利用する。  setlocale() 文字列カテゴリのサポートを廃止した。代わりに LC_* 定数を利用する。  substr() はstartの文字列と同じ長さの場合、空文字列を返すようになった。  exec(), system() と passthru() はヌル文字インジェクションの対策が取られた。 2016/6/28© Electronic Service Initiative, Ltd. All Rights Reserved. 59 後方互換性の為に古いPHPはヌル文字イン ジェクション対策がない。必要な場合、プロ グラマが対策する。 普通に入力バリデーションを行っている場 合、この仕様は問題とならない。
2016/6/27© Electronic Service Initiative, Ltd. All Rights Reserved. 60
 スカラー型の宣言(タイプヒント)は2種類の動作モードがある ◦ coercive (default)とstrict  次のデータ型を動作モードに応じて強制できる ◦ strings (string), integers (int), floating-point numbers (float), booleans (bool). ◦ 次のデータ型はPHP 5から強制可能。クラス,インターフェース,array および callable. <?php // Coercive mode function sumOfInts(int ...$ints) { return array_sum($ints); } var_dump(sumOfInts(2, '3', 4.1)); 2016/6/28© Electronic Service Initiative, Ltd. All Rights Reserved. 61 int(9) 自動的にintにキャストされ、 関数内で$intsがint型である ことが保証される
 Strictモードを利用するにはdeclare宣言をファイルの先頭で行う。 ◦ データ型のミスマッチは致命的エラーとなる  これはファイル単位で動作モードを変えれることを意味する。  Strictモード設定は引数のみでなく戻り値にも影響する。 ◦ 戻り値型の宣言、組み込み関数、拡張モジュール関数の戻り値も参照 <?php declare(strict_types=1); // Strict mode function sumOfInts(int ...$ints) { return array_sum($ints); } var_dump(sumOfInts(2, '3', 4.1)); 2016/6/28© Electronic Service Initiative, Ltd. All Rights Reserved. 62 PHP Fatal error: Uncaught TypeError: Argument 2 passed to sumOfInts() must be of the type integer, string given, called in - on line 8 and defined in -:4 Next TypeError: Argument 3 passed to sumOfInts() must be of the type integer, float given, called in - on line 8 and defined in -:4
 PHP 7は戻り値型の宣言が追加された。引数の型と同じく、関数の戻り値のデータ 型を指定できる。  引数指定で利用できるデータ型を利用できる。 <?php function arraysSum(array ...$arrays): array { return array_map(function(array $array): int { return array_sum($array); }, $arrays); } print_r(arraysSum([1,2,3], [4,5,6], [7,8,9])); 2016/6/28© Electronic Service Initiative, Ltd. All Rights Reserved. 63 Array ( [0] => 6 [1] => 15 [2] => 24 ) Hackと同じ文法
 ヌルCOALECEオペレーター(??)が追加された.  最初のオペランドが存在しNULLでない場合、それが返される。それ以外は次のオペ ランドが返される。 <?php // $_GET[‘user’] が存在する場合、その値。無い場合は ‘nobody’ $username = $_GET['user'] ?? 'nobody'; // 同等の表現 $username = isset($_GET['user']) ? $_GET['user'] : 'nobody'; // Coalescing can be chained: this will return the first // defined value out of $_GET['user'], $_POST['user'], and 'nobody'. $username = $_GET['user'] ?? $_POST['user'] ?? 'nobody'; ?> 2016/6/27© Electronic Service Initiative, Ltd. All Rights Reserved. 64 必須のパラメーターの存在確認はセキュリティ対策と して実施しなければならない項目である点に注意!
 スペースシップオペレーターは二つの表現を比較する場合に用いる。  PHPの通常の比較ルールで比較しその結果を-1, 0 または 1 で返す。 <?php // Integers echo 1 <=> 1; // 0 echo 1 <=> 2; // -1 echo 2 <=> 1; // 1 // Floats echo 1.5 <=> 1.5; // 0 echo 1.5 <=> 2.5; // -1 echo 2.5 <=> 1.5; // 1 // Strings echo "a" <=> "a"; // 0 echo "a" <=> "b"; // -1 echo "b" <=> "a"; // 1 ?> 2016/6/27© Electronic Service Initiative, Ltd. All Rights Reserved. 65 見慣れないオペレーターだがMySQL などには実装されている
 define()によって定数の配列が定義できるようになった。  PHP 5.6はconstでのみ配列の定数が定義できた。 <?php define('ANIMALS', [ 'dog', 'cat', 'bird' ]); echo ANIMALS[1]; // outputs "cat" ?> 2016/6/27© Electronic Service Initiative, Ltd. All Rights Reserved. 66
 “new class”によって匿名クラスによるオブジェクト生成が可能となった。 <?php interface Logger { public function log(string $msg); } class Application { private $logger; public function getLogger(): Logger { return $this->logger; } public function setLogger(Logger $logger) { $this->logger = $logger; } } $app = new Application; $app->setLogger(new class implements Logger { public function log(string $msg) { echo $msg; } }); var_dump($app->getLogger()); ?> 2016/6/28© Electronic Service Initiative, Ltd. All Rights Reserved. 67 object(class@anonymous)#2 (0) { }
 HEX形式のUnicodeコードポイント構文が追加されダブルクオート文字列か heredoc文字列のUTF-8文字列で利用できる。  先頭の0はオプションとして利用でき、妥当なコードポイントは全て利用できる。 <?php echo "¥u{aa}"; echo "¥u{0000aa}"; echo "¥u{9999}"; 2016/6/28© Electronic Service Initiative, Ltd. All Rights Reserved. 68 ª ª (オプションの0がある場合と同じ) 香
 Closure::call() 一時的にクロージャーをオブジェクトスコープにバインドし、呼び 出すより性能が良く簡潔な方法である。 <?php class A {private $x = 1;} // Pre PHP 7 code $getXCB = function() {return $this->x;}; $getX = $getXCB->bindTo(new A, 'A'); // intermediate closure echo $getX(); // PHP 7+ code $getX = function() {return $this->x;}; echo $getX->call(new A); 2016/6/28© Electronic Service Initiative, Ltd. All Rights Reserved. 69 1 1 PHPのクロージャーはオブ ジェクトとして実装されている。 bindTo()で別のオブジェクト にバインド可能
 信頼できないオブジェクトデータをより安全に処理する機能です。ホワイトリスト を利用してアンシリアライズによるコードインジェクション攻撃から防御できます。 <?php // converts all objects into __PHP_Incomplete_Class object $data = unserialize($foo, ["allowed_classes" => false]); // converts all objects into __PHP_Incomplete_Class object except those of MyClass and MyClass2 $data = unserialize($foo, ["allowed_classes" => ["MyClass", "MyClass2"]]); // default behaviour (same as omitting the second argument) that accepts all classes $data = unserialize($foo, ["allowed_classes" => true]); 2016/6/27© Electronic Service Initiative, Ltd. All Rights Reserved. 70 後方互換性の為にリスクがある オブジェクトのアンシリアライズが デフォルトで有効である点に注意!
 Intl拡張モジュールに追加されたIntlCharクラスは追加のICU機能を利用可能にしま す。IntlCharクラスはUnicode文字列を操作する多くのスタティックメソッドを定 義しています。 <?php printf('%x', IntlChar::CODEPOINT_MAX); echo IntlChar::charName('@'); var_dump(IntlChar::ispunct('!')); 2016/6/28© Electronic Service Initiative, Ltd. All Rights Reserved. 71 10ffff COMMERCIAL AT bool(true)
 Expectationsは従来のassert()と互換の機能で、運用環境でコストゼロのアサー ションを提供します。アサーションが失敗した時にカスタム例外を発生させること も可能です。  古いAPIとの互換性も保たれているが、assert()は第一引数は言語要素で論理値とし てテストを実行するPHPスクリプト文字列のみでなく表現も記述できる。 <?php ini_set('assert.exception', 1); class CustomError extends AssertionError {} assert(false, new CustomError('Some error message')); ?> 2016/6/28© Electronic Service Initiative, Ltd. All Rights Reserved. 72 Fatal error: Uncaught CustomError: Some error message Full details on this feature, including how to configure it in both development and production environments, can be found in the expectations section of the assert() reference.
 同じネームスペースからインポートされる、クラス、関数およびコンスタントは一 つのuse文でグループ化できる。 <?php // Pre PHP 7 code use some¥namespace¥ClassA; use some¥namespace¥ClassB; use some¥namespace¥ClassC as C; use function some¥namespace¥fn_a; use function some¥namespace¥fn_b; use function some¥namespace¥fn_c; use const some¥namespace¥Const; use const some¥namespace¥ConstB; use const some¥namespace¥ConstC; // PHP 7+ code use some¥namespace¥{ClassA, ClassB, ClassC as C}; use function some¥namespace¥{fn_a, fn_b, fn_c}; use const some¥namespace¥{ConstA, ConstB, ConstC}; ?> 2016/6/27© Electronic Service Initiative, Ltd. All Rights Reserved. 73 グループ化して簡潔に 記述可能
 ジェネレーターにより戻される最後の値をreturn文で返せる。(ただし参照は不可 能)  この値はジェネレーターが値の生成を完了した後、一度だけ Generator::getReturn() メソッドで取得できる。 <?php $gen = (function() { yield 1; yield 2; return 3; })(); foreach ($gen as $val) { echo $val, PHP_EOL; } echo $gen->getReturn(), PHP_EOL; 2016/6/28© Electronic Service Initiative, Ltd. All Rights Reserved. 74 明示的に最後の値を取得できると便利な機能で ある。最後の値が生成されたかチェックするより 簡単に簡単である。 1 2 3
 ジェネレーターはTraversableオブジェクトか配列の他のジェネレーターにデリゲートで きる。これにより無用なジェネレーターコードの繰り返しを防止できる。 <?php function gen() { yield 1; yield 2; yield from gen2(); } function gen2() { yield 3; yield 4; } foreach (gen() as $val) { echo $val, PHP_EOL; } 2016/6/28© Electronic Service Initiative, Ltd. All Rights Reserved. 75 1 2 3 4
 intdiv()は整数の除算を行い、結果を返す。 ◦ 整数型の除算結果を直接取得できる。 <?php var_dump(intdiv(10, 3)); ?> 2016/6/28© Electronic Service Initiative, Ltd. All Rights Reserved. 76 int(3)
 session_start() は通常php.iniで設定する項目をパラメータとして設定できる。 php.ini設定の他には以下の設定が行える。  session.lazy_write - セッションデータに変更があった場合のみ書き込む  read_and_close – セッションデータを読み込み、直ぐにクローズする  session.cache_limiterをprivateに設定し、セッションデータ読み出し後に直ぐにク ローズするには以下のようにする。 <?php session_start([ 'cache_limiter' => 'private', 'read_and_close' => true, ]); ?> 2016/6/27© Electronic Service Initiative, Ltd. All Rights Reserved. 77
 preg_replace_callback_array()はpreg_replace_callback() よりクリーンなコー ドを記述できる。PHPより前ではコールバック関数は正規表現毎に実行され、CPU の分岐を多数発生させていた。  preg_replace_callback_array()はコールバックをそれぞれ正規表現(キー)と コールバック(値)とする連想配列で登録できる。 <?php $subject = 'Aaaaaa Bbb'; preg_replace_callback_array( [ '~[a]+~i' => function ($match) { echo strlen($match[0]), ' matches for "a" found', PHP_EOL; }, '~[b]+~i' => function ($match) { echo strlen($match[0]), ' matches for "b" found', PHP_EOL; } ], $subject ); 2016/6/27© Electronic Service Initiative, Ltd. All Rights Reserved. 78
 プラットフォームに依存しない暗号理論的に安全な乱数生成器(整数とバイト列) が追加された。 ◦ random_bytes() ◦ random_int()  PHP5用のスクリプトによる実装 ◦ https://github.com/paragonie/random_compat 2016/6/28© Electronic Service Initiative, Ltd. All Rights Reserved. 79 セキュリティが必要な乱数・ランダム文字列にはこれ らの関数を利用する。 PHPスクリプトの実装もある。
 以前のPHPは, list()はArrayAccessを実装しているオブジェクトでも正しいアン パックを行えなかった。これが修正された。 2016/6/27© Electronic Service Initiative, Ltd. All Rights Reserved. 80
2016/6/27© Electronic Service Initiative, Ltd. All Rights Reserved. 81
 Closure ◦ Closure::call()  CSPRNG ◦ random_bytes() ◦ random_int()  Error Handling and Logging ◦ error_clear_last()  Generator ◦ Generator::getReturn()  GNU Multiple Precision ◦ gmp_random_seed()  Math ◦ intdiv()  PCRE ◦ preg_replace_callback_array()  PHP Options/Info ◦ gc_mem_caches() ◦ get_resources() 2016/6/27© Electronic Service Initiative, Ltd. All Rights Reserved. 82
 POSIX ◦ posix_setrlimit()  Reflection ◦ ReflectionParameter::getType() ◦ ReflectionParameter::hasType() ◦ ReflectionFunctionAbstract::getReturnType() ◦ ReflectionFunctionAbstract::hasReturnType()  Zip ◦ ZipArchive::setCompressionIndex() ◦ ZipArchive::setCompressionName()  Zlib Compression ◦ inflate_add() ◦ deflate_add() ◦ inflate_init() ◦ deflate_init() 2016/6/27© Electronic Service Initiative, Ltd. All Rights Reserved. 83
2016/6/27© Electronic Service Initiative, Ltd. All Rights Reserved. 84
 Intl ◦ IntlChar  Reflection ◦ ReflectionGenerator ◦ ReflectionType  Session Handling ◦ SessionUpdateTimestampHandlerInterface  Exception Hierarchy ◦ Throwable ◦ Error ◦ TypeError ◦ ParseError ◦ AssertionError ◦ ArithmeticError ◦ DivisionByZeroError 2016/6/28© Electronic Service Initiative, Ltd. All Rights Reserved. 85 Throwableを継承するError例外とそ の派生型のError例外が利用できる。 Error例外を継承しているError例外は PHP系のエラー。 Lazy_write(無用なセッションデータ書 き込みを防止する機能)を有効にする には、このインターフェースの実装が必 要
2016/6/27© Electronic Service Initiative, Ltd. All Rights Reserved. 86
 Core Predefined Constants ◦ PHP_INT_MIN  LibXML ◦ LIBXML_BIGLINES  PCRE ◦ PREG_JIT_STACKLIMIT_ERROR  POSIX ◦ POSIX_RLIMIT_AS POSIX_RLIMIT_CORE POSIX_RLIMIT_CPU POSIX_RLIMIT_DATA POSIX_RLIMIT_FSIZE POSIX_RLIMIT_LOCKS POSIX_RLIMIT_MEMLOCK POSIX_RLIMIT_MSGQUEUE POSIX_RLIMIT_NICE POSIX_RLIMIT_NOFILE POSIX_RLIMIT_NPROC POSIX_RLIMIT_RSS POSIX_RLIMIT_RTPRIO POSIX_RLIMIT_RTTIME POSIX_RLIMIT_SIGPENDING POSIX_RLIMIT_STACK POSIX_RLIMIT_INFINITY  Zlib ◦ ZLIB_BLOCK ZLIB_FINISH ZLIB_FULL_FLUSH ZLIB_NO_FLUSH ZLIB_PARTIAL_FLUSH ZLIB_SYNC_FLUSH 2016/6/27© Electronic Service Initiative, Ltd. All Rights Reserved. 87
 予約語の緩和 ◦ グローバルの予約語の制限を緩和した。  クラス・インターフェース・トレイト内のプロパティ、定数、メソッド名 ◦ 新しく予約語が追加された場合に、ユーザーが定義したAPIどの競合を防ぐ。  DSLなどを書く場合に便利 <?php // 'new', 'private', and 'for' were previously unusable Project::new('Project Name')->private()->for('purpose here')->with('username here'); ?> ◦ “class”キーワードのみ定数として利用できない。  ClassName::classが動作しなくなる  date.timezone警告を削除 ◦ date.timezone INI設定が空の場合の警告が削除された。 ◦ デフォルトはUTC。 2016/6/28© Electronic Service Initiative, Ltd. All Rights Reserved. 88
 Migrating from PHP 5.6.x to PHP 7.0.x を訳し、移行のポイントが解りやすいよ うに編集した文書です。 ◦ http://jp2.php.net/manual/en/migration70.php  より詳しい変更内容はマニュアルおよびWikiで確認できます。 ◦ http://jp2.php.net/manual/en/index.php ◦ https://wiki.php.net/rfc#php_70  この文書はPHPマニュアルと同じくクリエイティブコモンズ(Attribution 3.0 License)で利用可能です。 ◦ https://creativecommons.org/licenses/by/3.0/legalcode お問い合わせ先 エレクトロニック・サービス・イニシアチブ http://www.es-i.jp/ info@es-i.jp 2016/6/28© Electronic Service Initiative, Ltd. All Rights Reserved. 89 弊社ではソースコード検査サービスやパッチ済みレガシーPHP、 PHP用互換性検査ツールの提供などを行っています。 詳しくは弊社Webサイトをご覧ください。

PHP5.6からPHP7.0への移行