PHP 7.2 リファレンス
PHP 7.1 リファレンス
PHP 7 は、2015 年 12 月 3 日にリリースされました。これには、以下に概説する多数の新機能、変更点、および下位互換性の破壊が含まれています。
パフォーマンス
特徴
結合比較演算子
ヌル合体オペレーター
スカラー型の宣言
戻り値の型の宣言
匿名クラス
Unicode コードポイントのエスケープ構文
クロージャcall()
メソッド
フィルタリングされたunserialize()
IntlChar
クラス
期待
団体use
宣言
ジェネレータの戻り式
ジェネレーターの委任
intdiv()
による整数の除算
session_start()
オプション
preg_replace_callback_array()
関数
CSPRNG 関数
define()
での配列定数のサポート
反射の追加
変更点
予約語の制限を緩和する
統一変数構文
エンジンの例外
スロー可能なインターフェース
整数のセマンティクス
JSON 拡張子が JSOND に置き換えられる
オーバーフロー時の ZPP 障害
foreach()
の動作の修正
list()
の動作の変更
ゼロ除算のセマンティクスの変更
カスタムセッションハンドラーの戻り値の修正
PHP 4 スタイルのコンストラクターの非推奨
date.timezone 警告の削除
代替 PHP タグの削除
Switch ステートメント内の複数のデフォルト ブロックの削除
重複した名前を持つパラメータの再定義の削除
デッドサーバー API の削除
数値文字列における 16 進数サポートの削除
非推奨の機能の削除
E_STRICT 通知の再分類と削除
password_hash()
の Salt オプションの非推奨
無効な 8 進リテラルに関するエラー
substr()
戻り値の変更
よくある質問
PHP6はどうなったのでしょうか?
PHP 7 の最大の点は、間違いなく、アプリケーションに驚異的なパフォーマンスの向上をもたらすことです。これは、よりコンパクトなデータ構造を使用し、ヒープの割り当て/割り当て解除を減らすように Zend Engine をリファクタリングした結果です。
実際のアプリケーションでのパフォーマンスの向上はさまざまですが、多くのアプリケーションではメモリ消費量も削減され、パフォーマンスが最大 100% 向上するようです。
リファクタリングされたコードベースは、将来の最適化 (JIT コンパイルなど) のさらなる機会も提供します。したがって、将来の PHP バージョンでも引き続きパフォーマンスが向上すると思われます。
PHP 7 のパフォーマンス チャートの比較:
PHP 7 による Web の高速化
Rasmus のシドニー講演からのベンチマーク
結合比較演算子 (または宇宙船演算子) は、2 つのオペランドから 3 者間比較を実行するための簡略表記です。次のいずれかの整数の戻り値を持ちます。
正の整数 (左側のオペランドが右側のオペランドより大きい場合)
0 (両方のオペランドが等しい場合)
負の整数 (右側のオペランドが左側のオペランドより大きい場合)
この演算子は等価演算子 ( ==
、 !=
、 ===
、 !==
) と同じ優先順位を持ち、他の緩い比較演算子 ( <
、 >=
など) とまったく同じ動作をします。また、これらと同様に非結合であるため、オペランドの連鎖 ( 1 <=> 2 <=> 3
など) は許可されません。
// 文字列を比較します lexallyvar_dump('PHP' <=> 'Node'); // int(1)// sizevar_dump(123 <=> 456) によって数値を比較します。 // int(-1)// 対応する配列要素を one-anothervar_dump(['a', 'b'] <=> ['a', 'b']) と比較します。 // int(0)
オブジェクトは比較できないため、この演算子のオペランドとして使用すると、未定義の動作が発生します。
RFC: 結合比較演算子
null 合体演算子 (または isset 三項演算子) は、三項演算子でisset()
チェックを実行するための短縮表記です。これはアプリケーションでよく行われることであるため、まさにこの目的のために新しい構文が導入されました。
// PHP 7 以前のコード$route = isset($_GET['route']) ? $_GET['route'] : 'index';// PHP 7+ code$route = $_GET['route'] ?? '索引';
RFC: Null Coalesce オペレーター
スカラー型宣言には、 coercive (デフォルト) とstrictの 2 つの形式があります。パラメータの次のタイプを (強制的または厳密に) 強制できるようになりました: 文字列 ( string
)、整数 ( int
)、浮動小数点数 ( float
)、およびブール値 ( bool
)。これらは、PHP 5.x バージョンで導入された他の型 (クラス名、インターフェイス、 array
、およびcallable
) を拡張します。
// 強制モードfunction sumOfInts(int ...$ints) { return array_sum($ints); }var_dump(sumOfInts(2, '3', 4.1)); // int(9)
厳密モードを有効にするには、単一のdeclare()
ディレクティブをファイルの先頭に配置する必要があります。これは、スカラーの型指定の厳密さがファイルごとに設定されることを意味します。このディレクティブは、パラメーターの型宣言だけでなく、関数の戻り値の型 (「戻り値の型宣言」を参照)、組み込みの PHP 関数、およびロードされた拡張機能からの関数にも影響します。
型チェックが失敗すると、 TypeError
例外 (「エンジンの例外」を参照) がスローされます。厳密な型指定に存在する唯一の寛容さは、整数が浮動小数点コンテキストで提供された場合に、整数から浮動小数点への自動変換 (ただしその逆は不可) であることです。
宣言(strict_types=1);関数乗算(float $x, float $y) { $x * $y を返します; }関数 add(int $x, int $y) { $x + $y を返します; }var_dump(multiply(2, 3.5)); // float(7)var_dump(add('2', 3)); // 致命的なエラー: キャッチされません TypeError: add() に渡される引数 1 は、整数型、指定された文字列型である必要があります...
型チェックが実行されるときは、呼び出しコンテキストのみが適用されることに注意してください。これは、厳密な型指定は関数/メソッドの呼び出しにのみ適用され、関数/メソッドの定義には適用されないことを意味します。上記の例では、2 つの関数は strict ファイルまたは coercive ファイルで宣言できますが、strict ファイルで呼び出されている限り、strict 型指定規則が適用されます。
BCブレイク
int
、 string
、 float
、 bool
という名前のクラスは現在禁止されています。
RFC: スカラー型宣言
戻り値の型を宣言すると、関数、メソッド、またはクロージャーの戻り値の型を指定できます。次の戻り値の型がサポートされています: string
、 int
、 float
、 bool
、 array
、 callable
、 self
(メソッドのみ)、 parent
(メソッドのみ)、 Closure
、クラスの名前、およびインターフェイスの名前。
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]));/* OutputArray( [0] => 6 [1] => 15 [2] => 24)*/
サブタイプに関しては、戻り値の型には不変性が選択されています。これは単に、メソッドがサブタイプ化されたクラスでオーバーライドされるか、コントラクトで定義されているように実装される場合、その戻り値の型が、(再) 実装されるメソッドと正確に一致する必要があることを意味します。
クラス A {}クラス B は A を拡張します {}クラス C { パブリック関数 test() : A { 新しい A を返します; } }クラス D は C を拡張します { // オーバーライドメソッド C::test() : A public function test() : B // 分散の不一致による致命的なエラー { 新しい B を返します; } }
共分散が許可されていないため、オーバーライド メソッドD::test() : B
によりE_COMPILE_ERROR
が発生します。これが機能するためには、 D::test()
メソッドの戻り値の型がA
である必要があります。
クラス A {} インターフェイス SomeInterface { パブリック関数 test() : A; }クラス B は SomeInterface を実装します { public function test() : A // 大丈夫です! { null を返します。 // 致命的なエラー: キャッチされません TypeError: B::test() の戻り値は A のインスタンスである必要があり、null が返されます... } }
今回、実装されたメソッドにより、実行時にTypeError
例外 (「エンジンの例外」を参照) がスローされます。これは、 null
が有効な戻り値の型ではないためです。返されるのはクラスA
のインスタンスのみです。
RFC: 戻り値の型の宣言
匿名クラスは、単純な 1 回限りのオブジェクトを作成する必要がある場合に役立ちます。
// PHP 7 以前のコードクラス ロガー { パブリック関数ログ($msg) { エコー $msg; } }$util->setLogger(new Logger());// PHP 7+ code$util->setLogger(new class { public function log($msg) { エコー $msg; } });
通常のクラスと同じように、コンストラクターに引数を渡したり、他のクラスを拡張したり、インターフェイスを実装したり、特性を使用したりできます。
class SomeClass {}interface SomeInterface {}trait SomeTrait {}var_dump(new class(10) extends SomeClassimplements SomeInterface { private $num; public function __construct($num) { $this->num = $num; SomeTrait を使用します。 });/** 出力:object(class@anonymous)#1 (1) { ["コマンドライン code0x104c5b612":"class@anonymous":private]=> int(10)}*/
匿名クラスを別のクラス内にネストしても、その外部クラスのプライベートまたは保護されたメソッドやプロパティにはアクセスできません。外部クラスの保護されたプロパティまたはメソッドを使用するために、匿名クラスは外部クラスを拡張できます。外部クラスのプライベート プロパティまたは保護されたプロパティを匿名クラスで使用するには、それらをそのコンストラクターを通じて渡す必要があります。
<?phpclass アウター { プライベート $prop = 1; 保護された $prop2 = 2; 保護された関数 func1() { 3 を返す; パブリック関数 func2() { return new class($this->prop) extends アウター { private $prop3; パブリック関数 __construct($prop) { $this->prop3 = $prop; パブリック関数 func3() { return $this->prop2 + $this->prop3 + $this->func1(); } }; } エコー(新しい外側)->func2()->func3(); // 6
RFC: 匿名クラス
これにより、UTF-8 でエンコードされた Unicode コードポイントを二重引用符で囲まれた文字列またはヒアドキュメントで出力できるようになります。任意の有効なコードポイントが受け入れられますが、先頭の0
はオプションです。
エコー "u{aa}"; // èecho "u{0000aa}"; // è (前と同じですが、オプションで先頭に 0 を付けます)echo "u{9999}"; // 香
RFC: Unicode コードポイントエスケープ構文
クロージャの新しいcall()
メソッドは、オブジェクト スコープをクロージャにバインドしながらクロージャを呼び出す簡単な方法として使用されます。これにより、中間クロージャーを呼び出す前に作成する必要がなくなり、よりパフォーマンスが高くコンパクトなコードが作成されます。
class A {private $x = 1;}// PHP 7 より前の code$getXCB = function() {return $this->x;};$getX = $getXCB->bindTo(new A, 'A'); // 中間クロージャエコー $getX(); // 1// PHP 7+ code$getX = function() {return $this->x;};echo $getX->call(new A); // 1
RFC: クロージャ::コール
unserialize()
この機能は、信頼できないデータ上のオブジェクトをシリアル化解除するときに、より優れたセキュリティを提供することを目的としています。開発者がシリアル化解除できるクラスをホワイトリストに登録できるようにすることで、コード インジェクションの可能性を防ぎます。
// すべてのオブジェクトを __PHP_Incomplete_Class に変換します object$data = unserialize($foo, ["allowed_classes" => false]);// MyClass と MyClass2 のオブジェクトを除くすべてのオブジェクトを __PHP_Incomplete_Class オブジェクトに変換します $data = unserialize($foo, [" allowed_classes" => ["MyClass", "MyClass2"]]);// デフォルトの動作 ( 2 番目の引数) すべてのクラスを受け入れます$data = unserialize($foo, ["allowed_classes" => true]);
RFC: フィルタリングされた unserialize()
IntlChar
クラス新しいIntlChar
クラスは、追加の ICU 機能を公開しようとしています。クラス自体は、Unicode 文字の操作に使用できる多数の静的メソッドと定数を定義します。
printf('%x', IntlChar::CODEPOINT_MAX); // 10ffffecho IntlChar::charName('@'); // 商用 ATvar_dump(IntlChar::ispunct('!')); // bool(true)
このクラスを使用するには、 Intl
拡張機能をインストールする必要があります。
BCブレイク
グローバル名前空間内のクラスをIntlChar
と呼ぶことはできません。
RFC: IntlChar クラス
古いassert()
関数に対する後方互換性の拡張が期待されています。これらにより、運用コードでゼロコストのアサーションが可能になり、エラー時にカスタム例外をスローする機能が提供されます。
assert()
関数のプロトタイプは次のとおりです。
void assert (mixed $expression [, mixed $message]);
古い API と同様、 $expression
が文字列の場合は評価されます。最初の引数が false の場合、アサーションは失敗します。 2 番目の引数は、プレーン文字列 (AssertionError をトリガーする)、またはエラー メッセージを含むカスタム例外オブジェクトのいずれかです。
ini_set('assert.Exception', 1);class CustomError extends AssertionError {}assert(false, new CustomError('何らかのエラー メッセージ'));
この機能には、2 つの PHP.ini 設定 (デフォルト値とともに) が付属しています。
zend.assertions = 1
アサート例外 = 0
zend.assertions には 3 つの値があります。
1 = コードを生成して実行します (開発モード)
0 = コードを生成し、実行時にコードを飛び回ります
-1 = コードを生成しません (コストゼロ、運用モード)
assert.Exception は、アサーションが失敗したときに例外がスローされることを意味します。これは、古いassert()
関数との互換性を保つために、デフォルトではオフになっています。
RFC: 期待
use
宣言これにより、親の名前空間に従って複数のuse
宣言をグループ化できるようになります。これにより、同じ名前空間に属する複数のクラス、関数、または定数をインポートする際のコードの冗長性が排除されます。
// PHP 7 より前のコードuse somenamespaceClassA;use somenamespaceClassB;use somenamespaceClassC を C として使用;use function somenamespacefn_a;use function somenamespacefn_b;use function somenamespace fn_c;use const somenamespaceConstA;use const somenamespaceConstB;use const somenamespaceConstC;// PHP 7+ codeuse somenamespace{ClassA, ClassB, ClassC as C};use function somenamespace{fn_a, fn_b, fn_c};use const somenamespace{ConstA, ConstB, ConstC};
RFC: グループ使用宣言
この機能は、PHP 5.5 に導入されたジェネレーター機能に基づいて構築されています。これにより、ジェネレーター内でreturn
ステートメントを使用して、最終式を返すことができるようになります (参照による戻りは許可されません)。この値は、新しいGenerator::getReturn()
メソッドを使用してフェッチできます。このメソッドは、ジェネレーターが値の生成を終了した後にのみ使用できます。
// IIFE 構文が可能になりました - 「変更点」セクションの「統一変数構文」サブセクションを参照してください$gen = (function() { yield 1; yield 2; return 3; })();foreach ($gen as $val) { echo $val, PHP_EOL; }echo $gen->getReturn(), PHP_EOL;// 出力:// 1// 2// 3
ジェネレーターから最終値を明示的に返すことができると便利な機能です。これは、ジェネレーターを実行するクライアント コードによって特別に処理できる最終値をジェネレーター (おそらく何らかの形式のコルーチン計算から) によって返すことができるためです。これは、最初に最終値が得られたかどうかをクライアント コードに確認させ、その後最終値が得られた場合はその値を具体的に処理することを強制するよりもはるかに簡単です。
RFC: ジェネレーターの戻り式
ジェネレーターの委任は、ジェネレーターから式を返すことができる機能に基づいて構築されています。これは、新しい構文yield from <expr>
を使用して行われます。ここには、任意のTraversable
オブジェクトまたは配列を指定できます。これは有効でなくなるまで進められ、その後、呼び出し元のジェネレーターで実行が続行されます。この機能により、 yield
ステートメントをより小さな操作に分割できるため、より再利用性の高いクリーンなコードが促進されます。
関数 gen() { 収量 1; 収量2; gen2() からの利回りを返します。 }関数gen2() { 収量 3; 4 を返します。 }$gen = gen();foreach ($gen を $val として) { エコー $val、PHP_EOL; }echo $gen->getReturn();// 出力// 1// 2// 3// 4
RFC: ジェネレーターの委任
intdiv()
による整数の除算intdiv()
関数は、整数が返される除算を処理するために導入されました。
var_dump(intdiv(10, 3)); // int(3)
BCブレイク
グローバル名前空間内の関数をintdiv
として呼び出すことはできません。
RFC: intdiv()
session_start()
オプションこの機能により、オプションの配列をsession_start()
関数に渡すことができるようになります。これは、セッションベースの php.ini オプションを設定するために使用されます。
session_start(['cache_limiter' => 'private']); // session.cache_limiter オプションをプライベートに設定します
この機能では、新しい php.ini 設定 ( session.lazy_write
) も導入されています。これはデフォルトで true に設定されており、セッション データが変更された場合にのみ書き換えられることを意味します。
RFC: session_start() オプションの導入
preg_replace_callback_array()
関数この新しい関数により、 preg_replace_callback()
関数を使用するときにコードをよりクリーンに記述することができます。 PHP 7 より前では、正規表現ごとにコールバックを実行する必要がある場合、コールバック関数 ( preg_replace_callback()
の 2 番目のパラメータ) を多くの分岐 (せいぜいハックなメソッド) で汚染する必要がありました。
連想配列を使用して各正規表現にコールバックを登録できるようになりました。キーは正規表現、値はコールバックです。
関数のシグネチャ:
string preg_replace_callback_array(array $regexesAndCallbacks, string $input);
$tokenStream = []; // [tokenName, lexeme] ペア$input = <<<'end'$a = 3; // 変数の初期化end;// PHP 7 以前の codepreg_replace_callback( [ '~$[a-z_][azd_]*~i'、'~=~'、'~[d]+~'、'~;~'、'~//.*~' ]、関数 ($match) use (&$tokenStream) { if (strpos($match[0], '$') === 0) { $tokenStream[] = ['T_VARIABLE', $match[0]] ; elseif (strpos($match[0], '=') === 0) { $tokenStream[] = ['T_ASSIGN', $match[0]]; elseif (ctype_digit($match[0])) { $tokenStream[] = ['T_NUM', $match[0]]; elseif (strpos($match[0], ';') === 0) { $tokenStream[] = ['T_TERMINATE_STMT', $match[0]]; elseif (strpos($match[0], '//') === 0) { $tokenStream[] = ['T_COMMENT', $match[0]]; } }, $input);// PHP 7+ codepreg_replace_callback_array( [ '~$[a-z_][azd_]*~i' => 関数 ($match) use (&$tokenStream) { $tokenStream[] = ['T_VARIABLE', $match[0]]; }, '~=~' => 関数 ($match) use (&$tokenStream) { $tokenStream[] = ['T_ASSIGN', $match[0]]; }, '~[d]+~' => 関数 ($match) use (&$tokenStream) { $tokenStream[] = ['T_NUM', $match[0]]; }, '~;~' => 関数 ($match) use (&$tokenStream) { $tokenStream[] = ['T_TERMINATE_STMT', $match[0]]; }, '~//.*~' => 関数 ($match) use (&$tokenStream) { $tokenStream[] = ['T_COMMENT', $match[0]]; } ]、$input);
BCブレイク
グローバル名前空間内の関数をpreg_replace_callback_array
として呼び出すことはできません。
RFC: preg_replace_callback_array 関数を追加
この機能では、暗号的に安全な整数と文字列を生成するための 2 つの新しい関数が導入されています。これらは単純な API を公開しており、プラットフォームに依存しません。
関数のシグネチャ:
string random_bytes(int length); int random_int(int min, int max);
十分なランダム性のソースが見つからない場合、両方の関数はError
例外を生成します。
BCブレイク
グローバル名前空間内の関数は、 random_int
またはrandom_bytes
として呼び出すことはできません。
RFC: 簡単なユーザーランド CSPRNG
define()
での配列定数のサポートconst
キーワードを使用して配列定数を定義する機能が PHP 5.6 で導入されました。この機能は、 define()
関数にも適用されるようになりました。
定義('ALLOWED_IMAGE_EXTENSIONS', ['jpg', 'jpeg', 'gif', 'png']);
RFC: 利用可能な RFC はありません
PHP 7 では 2 つの新しいリフレクション クラスが導入されました。1 つ目はReflectionGenerator
で、ジェネレーターのイントロスペクションに使用されます。
クラスReflectionGenerator { public __construct(Generator $gen) public array getTrace($options = DEBUG_BACKTRACE_PROVIDE_OBJECT) public int getExecutingLine(void) パブリック文字列 getExecutingFile(void) public ReflectionFunctionAbstract getFunction(void) パブリックオブジェクトgetThis(void) public ジェネレーター getExecutingGenerator(void) }
2 つ目は、スカラーおよび戻り値の型宣言機能をより適切にサポートするためのReflectionType
です。
クラスReflectionType { public bool allowedNull(void) public bool isBuiltin(void) public string __toString(void) }
また、2 つの新しいメソッドがReflectionParameter
に導入されました。
クラスReflectionParameter { // ... public bool hasType(void) public ReflectionType getType(void) }
ReflectionFunctionAbstract
の 2 つの新しいメソッドと同様に:
クラス ReflectionFunctionAbstract { // ... public bool hasReturnType(void) public ReflectionType getReturnType(void) }
BCブレイク
グローバル名前空間内のクラスをReflectionGenerator
またはReflectionType
と呼ぶことはできません。
RFC: 利用可能な RFC はありません
クラス、インターフェイス、特性内のプロパティ名、定数名、メソッド名としてグローバルに予約された単語が許可されるようになりました。これにより、新しいキーワードが導入されたときに BC ブレークの表面が減少し、API の名前制限が回避されます。
これは、流暢なインターフェイスを備えた内部 DSL を作成する場合に特に便利です。
// 'new'、'private'、および 'for' は以前は使用できませんでしたProject::new('プロジェクト名')->private()->for('ここでの目的')->with('ここでのユーザー名');
唯一の制限は、 class
キーワードを定数名として使用できないことです。そうしないと、クラス名解決構文 ( ClassName::class
) と競合します。
RFC: 状況依存レクサー
この変更により、PHP の変数演算子にはるかに優れた直交性がもたらされます。これにより、以前は許可されていなかった演算子の新しい組み合わせが多数可能になり、ターサー コードで古い演算を実現する新しい方法が導入されます。
// ネスト ::$foo::$bar::$baz // $foo::$bar プロパティの $baz プロパティにアクセス // ネスト ()foo()() // foo() の return を呼び出す// ()(function () {})() で囲まれた式の演算子 // JS の IIFE 構文
変数演算子を任意に組み合わせる機能は、間接変数、プロパティ、およびメソッド参照の評価セマンティクスを逆にすることで実現しました。新しい動作はより直感的で、常に左から右の評価順序に従います。
// 古い意味 // 新しい意味$$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']()
BCブレイク
古い評価順序に依存するコードは、中かっこを使用してその評価順序を明示的に使用するように書き直す必要があります (上記の中央の列を参照)。これにより、コードは PHP 7.x との上位互換性と PHP 5.x との後方互換性の両方が得られます。
RFC: 統一変数構文
エンジン内の例外は、多くの致命的エラーと回復可能な致命的エラーを例外に変換します。これにより、カスタム エラー処理手順を通じてアプリケーションを適切に機能低下させることができます。また、 finally
句やオブジェクト デストラクターなどのクリーンアップ主導の機能が実行されるようになることも意味します。さらに、アプリケーション エラーの例外を使用すると、追加のデバッグ情報を得るためにスタック トレースが生成されます。
function sum(float ...$numbers) : float{ return array_sum($numbers); }try { $total = sum(3, 4, null); } catch (TypeError $typeErr) { // ここで型エラーを処理します}
新しい例外階層は次のとおりです。
interface Throwable |- Exception implements Throwable |- ... |- Error implements Throwable |- TypeError extends Error |- ParseError extends Error |- AssertionError extends Error |- ArithmeticError extends Error |- DivisionByZeroError extends ArithmeticError
この新しい例外階層の詳細については、「変更点」セクションの「スロー可能インターフェイス」サブセクションを参照してください。
BCブレイク
回復可能な致命的なエラーを処理する (通常は無視する) ために使用されるカスタム エラー ハンドラーは、例外がスローされるため機能しなくなります。
eval()
で処理されたコードで発生した解析エラーは例外となり、 try...catch
ブロックでラップする必要があります。
RFC: エンジン内の例外
この変更は、エンジンに例外が導入されるため、PHP の例外階層に影響します。致命的エラーと回復可能な致命的エラーを既存のException
クラス階層の下に配置するのではなく、PHP 5.x コードがキャッチオール ( catch (Exception $e)
でこれらの新しい例外をキャッチするのを防ぐために、新しい例外階層を実装することが決定されました。 ) 条項。
新しい例外階層は次のとおりです。
interface Throwable |- Exception implements Throwable |- ... |- Error implements Throwable |- TypeError extends Error |- ParseError extends Error |- AssertionError extends Error |- ArithmeticError extends Error |- DivisionByZeroError extends ArithmeticError
Throwable
インターフェイスは、 Exception
とError
両方の基本クラス階層によって実装され、次のコントラクトを定義します。
interface Throwable { final public string getMessage ( void ) final public mixed getCode ( void ) final public string getFile ( void ) final public int getLine ( void ) final public array getTrace ( void ) final public string getTraceAsString ( void ) public string __toString ( void ) }
Throwable
ユーザー定義クラスでは実装できません。代わりに、カスタム例外クラスは PHP の既存の例外クラスの 1 つを拡張する必要があります。
RFC: スロー可能なインターフェース
一部の整数ベースの動作のセマンティクスは、動作をより直感的でプラットフォームに依存しないようにするために変更されました。これらの変更のリストは次のとおりです。
NAN
とINF
整数にキャストすると、常に 0 が返されます。
負のビット数によるビット単位のシフトは禁止されるようになりました (bool(false) が返され、E_WARNING が発行されます)。
整数のビット幅を超えるビット数による左ビットシフトは常に 0 になります。
整数のビット幅を超えてビット単位で右シフトすると、常に 0 または -1 になります (符号に依存します)。
BCブレイク
上記の古いセマンティクスへの依存は機能しなくなります。
RFC: 整数セマンティクス
古い JSON 拡張機能のライセンスは無料ではないと見なされ、多くの Linux ベースのディストリビューションで問題が発生しました。その後、この拡張機能は JSOND に置き換えられ、パフォーマンスが向上し、下位互換性が失われています。
BCブレイク
数値は小数点で終わってはいけません(つまり、 34.
34.0
または単に34
に変更する必要があります)
e
指数は小数点の直後にあってはなりません(つまり、 3.e3
3.0e3
または3e3
に変更する必要があります)。
RFC: 現在の json 拡張子を jsond に置き換えます
浮動小数点から整数への強制は、整数を期待する内部関数に浮動小数点が渡されるときに発生する可能性があります。 float が大きすぎて整数として表現できない場合、値は暗黙的に切り捨てられます (その結果、大きさと符号が失われる可能性があります)。これにより、見つけにくいバグが発生する可能性があります。したがって、この変更は、浮動小数点から整数への暗黙的な変換が発生し、 null
を返して E_WARNING を発行して失敗した場合に開発者に通知することを目的としています。
BCブレイク
以前は静かに動作していたコードが E_WARNING を発行し、関数呼び出しの結果が別の関数に直接渡されると失敗する可能性があります ( null
渡されるようになるため)。
RFC: オーバーフロー時の ZPP 障害
foreach()
の動作の修正PHP のforeach()
ループには、奇妙なエッジケースが多数ありました。これらはすべて実装主導型であり、配列のコピーと参照の間で反復処理を行うとき、 current()
やreset()
などの反復子マニピュレータを使用するとき、現在反復処理されている配列を変更するときなど、多くの未定義で一貫性のない動作を引き起こしていました。
この変更により、これらのエッジケースの未定義の動作が排除され、セマンティクスがより予測可能かつ直感的になりました。
配列の値によるforeach()
$array = [1,2,3];$array2 = &$array;foreach($array as $val) { unset($array[1]); // echo で反復される配列を変更します。 echo "{$val} - ", current($array), PHP_EOL; }// PHP 7 以前の結果 1 - 33 -// PHP 7 以降の結果 1 - 12 - 13 - 1
値によるセマンティクスが使用される場合、反復処理される配列はインプレースで変更されなくなりました。 current()
にも動作が定義されており、常に配列の先頭から開始されます。
foreach()
配列およびオブジェクトの参照による、およびオブジェクトの値による
$array = [1,2,3];foreach($array as &$val) { echo "{$val} - ", current($array), PHP_EOL; }// PHP 7 以前の結果 1 - 22 - 33 -// PHP 7 以降の結果 1 - 12 - 13 - 1
current()
関数は、配列に対するforeach()
の反復の影響を受けなくなりました。また、参照によるセマンティクスを使用するネストされたforeach()
は、互いに独立して動作するようになりました。
$array = [1,2,3];foreach($array as &$val) { echo $val, PHP_EOL; foreach ($array as &$val2) { unset($array[1]); エコー $val、PHP_EOL; } }// PHP 7 以前 result111// PHP 7 以降 result111333
BCブレイク
古い (風変わりで文書化されていない) セマンティクスへの依存は機能しなくなります。
RFC: 「foreach」動作を修正
list()
の動作の変更list()
関数は文字列をサポートしていないと文書化されていますが、まれに文字列が使用される可能性があります。
// 配列の逆参照 $str[0] = 'ab';list($a, $b) = $str[0];echo $a; // エコー $b; // b// オブジェクトの参照解除$obj = new StdClass();$obj->prop = 'ab';list($a, $b) = $obj->prop;echo $a; // エコー $b; // b// 関数 returnfunction func() { 'ab' を返します; }list($a, $b) = func();var_dump($a, $b);echo $a; // エコー $b; // b
これは変更され、 list()
での文字列の使用があらゆる場合に禁止されるようになりました。
また、空のlist()
は致命的なエラーになり、変数を割り当てる順序が左から右に変更されました。
$a = [1, 2];list($a, $b) = $a;// 古い: $a = 1, $b = 2// 新しい: $a = 1, $b = null + "未定義Index 1"$b = [1, 2];list($a, $b) = $b;// 古い: $a = null + "未定義のインデックス 0", $b = 2// 新しい: $a = 1、$b = 2
BCブレイク
list()
直接以外の文字列値と等しくすることはできなくなりました。上記の例では、変数$a
と$b
の値がnull
なります。
変数を指定せずにlist()
を呼び出すと致命的なエラーが発生します
古い右から左への割り当て順序に依存することは機能しなくなります
RFC: list() の動作の不一致を修正
RFC: 抽象構文ツリー
PHP 7 より前では、除算 (/) 演算子または剰余演算子 (%) の除数が 0 の場合、E_WARNING が発行され、 false
返されていました。場合によっては算術演算がブール値を返すのは無意味であったため、この動作は PHP 7 で修正されました。
新しい動作により、除算演算子は浮動小数点数を +INF、-INF、または NAN として返します。モジュラス演算子 E_WARNING が削除され、(新しいintdiv()
関数とともに) DivisionByZeroError
例外がスローされます。さらに、 intdiv()
関数は、有効な整数引数が指定された場合にArithmeticError
スローし、(整数のオーバーフローが原因で) 不正な結果を引き起こす可能性があります。
var_dump(3/0); // float(INF) + E_WARNINGvar_dump(0/0); // float(NAN) + E_WARNINGvar_dump(0%0); // DivisionByZeroErrorintdiv(PHP_INT_MIN, -1); // 算術エラー
BCブレイク
除算演算子はfalse
返さなくなりました (算術演算で暗黙的に 0 に強制される可能性がありました)。
モジュラス演算子はfalse
を返すのではなく、除数 0 の例外をスローするようになりました。
RFC: 利用可能な RFC はありません
カスタム セッション ハンドラーを実装する場合、 true
またはfalse
戻り値を期待するSessionHandlerInterface
の述語関数が期待どおりに動作しませんでした。以前の実装のエラーにより、戻り値-1
のみが false とみなされます。つまり、失敗を示すためにブール値false
が使用された場合でも、成功とみなされます。
<?phpclass FileSessionHandler は SessionHandlerInterface を実装します { プライベート $savePath; 関数オープン($savePath, $sessionName) { 偽を返します; // 必ず失敗する } 関数 close(){return true;} 関数 read($id){} 関数 write($id, $data){} 関数 destroy($id){} 関数 gc($maxlifetime){} }session_set_save_handler(new FileSessionHandler());session_start(); // PHP 7 以前のコードではエラーは発生しません
さて、上記は致命的なエラーで失敗します。戻り値が-1
の場合も引き続き失敗しますが、 0
とtrue
引き続き成功を意味します。他の値が返されると失敗が発生し、E_WARNING が発行されます。
BCブレイク
ブール値のfalse
が返された場合、実際には失敗します。
ブール値、 0
、または-1
以外の値が返された場合、失敗し、警告が発行されます。
RFC: カスタム セッション ハンドラーの戻り値の処理を修正
PHP 4 コンストラクターは、新しい__construct()
とともに PHP 5 に保存されました。現在、PHP 4 スタイルのコンストラクターは非推奨になり、オブジェクトの作成時に呼び出されるメソッドは 1 つだけ ( __construct()
) になりました。これは、PHP 4 スタイルのコンストラクターが呼び出されるかどうかの条件により、開発者に追加の認知的オーバーヘッドが発生し、経験の浅い人にとっては混乱を招く可能性があるためです。
たとえば、クラスが名前空間内で定義されている場合、または__construct()
メソッドが存在する場合、PHP 4スタイルのコンストラクターが平易な方法として認識されました。 __construct()
メソッドの上に定義された場合、E_Strict通知は放出されますが、それでも単純な方法として認識されます。
PHP 7では、クラスが名前空間になく、 __construct()
メソッドが存在しない場合、PHP 4スタイルのコンストラクターがコンストラクターとして使用されますが、E_Deprecatedが放出されます。 PHP 8では、PHP 4スタイルのコンストラクターは常に単純な方法として認識され、E_Deprecated通知は消えます。
BCブレーク
カスタムエラーハンドラーは、E_DEPRECATED警告の提起により影響を受ける可能性があります。これを修正するには、クラスコンストラクター名を__construct
に更新するだけです。
RFC:PHP 4コンストラクターを削除します
日付または時刻ベースの関数が呼び出され、デフォルトのタイムゾーンが設定されていない場合、警告が発生しました。修正は、 date.timezone
INI設定を有効なTimezoneに設定するだけでしたが、これによりユーザーはPHP.iniファイルを持ち、事前に構成することが強制されました。これが警告が付いている唯一の設定であり、とにかくUTCにデフォルトであるため、警告は削除されました。
RFC:date.timezone警告を削除します
代替PHPタグ<%
(および<%=
)、 %>
、 <script language="php">
、および</script>
が削除されました。
BCブレーク
これらの代替タグに依存しているコードは、通常または短い開閉タグのいずれかに更新する必要があります。これは、この移植スクリプトで手動で実行するか、自動化できます。
RFC:代替PHPタグを削除します
以前は、スイッチステートメント内で複数のdefault
ブロックステートメントを指定することができました(最後のdefault
ブロックのみが実行された場合)。この(役に立たない)能力が削除され、致命的なエラーが発生しました。
BCブレーク
複数のdefault
ブロックを使用してスイッチステートメントを作成したコード(または生成される可能性が高い)はすべて、致命的なエラーになります。
RFC:スイッチで複数のデフォルトケースを定義する構文エラーを作成する
以前は、関数定義内の複製名を持つパラメーターを指定することができました。この能力は現在削除されており、致命的なエラーを引き起こしています。
functionfoo($ version、$ version) {return $ version; } echo foo(5、7); // pre php 7 result7 // php 7+ resultfatalエラー:パラメーター$バージョンの再定義/redefinition-of-parameters.php
BCブレーク
名前を重複した関数パラメーターは、致命的なエラーになります。
次のSAPIはコアから削除されました(そのほとんどはPECLに移動されました)。
sapi/aolserver
sapi/apache
sapi/apache_hooks
sapi/apache2filter
sapi/caudium
SAPI/連続性
sapi/isapi
sapi/milter
sapi/nsapi
sapi/phttpd
SAPI/PI3WEB
SAPI/ROXEN
sapi/thttpd
SAPI/TUX
SAPI/WebJames
ext/mssql
ext/mysql
ext/sybase_ct
ext/ereg
RFC:死亡またはまだPHP7ポーティングされたSAPIと拡張機能の除去
糸状の16進数は、数値として認識されなくなりました。
var_dump(is_numeric( '0x123')); var_dump( '0x123' == '291'); echo '0x123' + '0x123'; // php 7 resultbool(true)bool(true)582 // php 7 + resultbool(false)bool(false)0
この変更の理由は、言語全体で弦楽器数の処理間のより良い一貫性を促進するためです。たとえば、明示的なキャストは、弦楽器番号を認識しません。
var_dump((int) '0x123'); // int(0)
代わりに、Stringの16進数は、 filter_var()
関数を使用して検証および変換する必要があります。
var_dump(filter_var( '0x123'、filter_validate_int、filter_flag_allow_hex)); // int(291)
BCブレーク
この変更は==
、 +
、 -
、 *
、 /
、 %
、 **
、 ++
を含むis_numeric()
関数とさまざまな演算子に影響します--
RFC:数値文字列でヘックスサポートを削除します
非推奨機能はすべて削除されました。
元のmysql拡張機能(ext/mysql)
EREG拡張機能(ext/ereg)
参照によりnew
割り当て
互換性のない$this
コンテキスト( Foo::bar()
は、 bar()
が静的な方法ではありません)
BCブレーク
PHP 5で非推奨警告で実行されたコードは機能しなくなります(警告されました!)
RFC:PHP 7で非推奨機能を削除します
E_Strictの通知は、常にその意味が少し灰色の領域でした。これにより、このエラーカテゴリが完全に削除され、次のいずれかが削除され、e_strict通知を削除したり、将来機能を削除したり、e_noticeに変更したり、e_warningに促進したりする場合、e_deprecatedに変更します。
BCブレーク
E_Strictは最低の重大度エラーカテゴリにあるため、E_WARNINGへのエラープロモーションはカスタムエラーハンドラーを破る可能性があります
RFC:e_strict通知を再分類します
password_hash()
の塩オプションの廃止オプションPHP 5.5でAPIをハッシュする新しいパスワードの導入により、多くの人がそれを実装し、独自の塩の生成を開始しました。残念ながら、これらの塩の多くは、MT_RAND()のような暗号化的に不安定な機能から生成され、デフォルトで生成されたものよりもはるかに弱く塩を生成しました。 (はい、この新しいAPIでパスワードをハッシュするときは常に塩が使用されます!)したがって、塩を生成するオプションは、開発者が不安定な塩を生成するのを防ぐために廃止されました。
RFC:RFCは利用できません
無効なオクタルリテラルは、切り捨てられて静かに無視されるのではなく、解析エラーを引き起こします。
エコー0678; //解析エラー:無効な数値リテラル...
BCブレーク
コード内の無効なオクタルリテラルが解析エラーを引き起こすようになります
RFC:RFCは利用できません
substr()
戻り値の変更substr()
切り捨ての開始位置が文字列の長さに等しい場合、 false
の代わりに空の文字列を返します。
var_dump(substr( 'a'、1)); // pre php 7 resultbool(false)// php 7+ resultString(0) ""
ただし、 substr()
、他のケースではまだfalse
を返す場合があります。
BCブレーク
bool(false)
の返品値を厳密にチェックしたコードは、意味的に無効になる可能性があります
RFC:RFCは利用できません
PHP 6は、明らかになったことのない主要なPHPバージョンでした。コアのUnicodeの完全なサポートを備えているはずでしたが、この努力はあまりにも多くの合併症が発生するため、あまりにも野心的でした。この新しいメジャーバージョンのバージョン6がスキップされた主な理由は次のとおりです。
混乱を防ぐため。多くのリソースがPHP 6について書かれており、コミュニティの多くはその中で何が紹介されているかを知っていました。 PHP 7は、まったく異なる焦点(特にパフォーマンスに)とまったく異なる機能セットを持つまったく異なる獣です。したがって、PHP 7が何であるかを取り巻く混乱や誤解を防ぐために、バージョンがスキップされています。
眠っている犬を嘘をつくように。 PHP 6は障害と見なされ、PHPリポジトリには大量のPHP 6コードがまだ残っています。したがって、過去のバージョン6を移動し、次のメジャーバージョン、バージョンで新たに開始するのが最善と見なされていました。
RFC:PHPの次のリリースの名前