PythonとGoを積極的に使用しているにもかかわらず、サーバーコードの大部分はPHPで記述されています。 そのため、私たちは言語のすべての革新を注意深く追っています。 前のマイナーバージョンのリリースから1年足らずで、8月17日に最後のベータリリースが予定されています。 実稼働環境での使用はまだ推奨されていませんが、既にdocker imageをダウンロードできます。 言語の新しいバージョンで何が変わったのかを理解する時が来ました。

内容
- 最適化
- 新機能
- 拡張機能を名前でダウンロードする機能を追加しました
- 抽象関数をオーバーロードする機能を追加
- -0を返すことを禁止されたnumber_format()
- オブジェクト/配列タイプをキャストするときに番号付きキーを変換する機能を追加しました
- get_class()のパラメータとしてnullを渡すことは禁止されています
- カウントできないパラメーターを持つ呼び出しカウント
- パラメータタイプを展開するオプション
- グループ化された名前空間の末尾にカンマを指定する機能が追加されました
- socket_getaddrinfoファミリーの関数を実装しました
- TLS定数の改善
- オブジェクト型のヒント
- LDAP EXOP
- PHPコアに追加されたLibsodium
- パスワードハッシュ用のArgon2アルゴリズムを追加
- オブジェクトとしてのHashContext
- PDO Prepared Statementデバッガーを追加
- PDO Prepared Statements v2デバッガーを追加
- PDOの拡張文字列タイプ
- オプションJSON_INVALID_UTF8_IGNOREおよびJSON_INVALID_UTF8_SUBSTITUTEが追加されました
- PHP 7.2から削除
- PHP 7.2で非推奨
最適化
Opcacheは、静的な単一割り当てフォーム(SPA)を使用したデータフローの分析に基づくグローバルな最適化を追加しました。スパース条件付き定数伝搬(SCCP)、デッドコード除去(DCE)、および未使用のローカル変数の削除です。
in_array()
組み込み関数は、逆配列のハッシュを検索することによりin_array()
れています。
新機能
名前で拡張機能をダウンロードする機能を追加しました( RFC )
以前は、php.iniファイルのextension=
およびzend_extension=
には、拡張ファイルへのパスが含まれていました。
しかし、残念ながら、ファイル名はプラットフォームに依存していました。 たとえば、unixライクなシステムでは、 <extension-name>.<suffix>
として構築され、 HP-UXを除くすべてのシステムで、 .so
である場合、 suffix
が.so
です。 Windowsでは、ファイル名はphp_<extension-name>.dll
として形成されphp_<extension-name>.dll
。 これはすべて多くの間違いを引き起こしました。
今、あなたは書くことができます:
extension=bz2 zend_extension=xdebug
また、OSに応じて必要な拡張機能がロードされます。
このメカニズムは、iniファイルでextensionおよびzend_extensionを設定するときに機能し、 dl()
関数の引数としても機能します。
ただし、絶対パスを指定する場合と同様に、CLIモードで-z
フラグを使用して絶対パスを指定する必要があります。 次の例は機能しません。
extension=/path/to/extensions/bz2
抽象関数( RFC )をオーバーロードする機能を追加
これで、通常の関数と同じ方法で抽象関数をオーバーロードできます。
abstract class A { abstract function bar(stdClass $x); } abstract class B extends A { abstract function bar($x): stdClass; } class C extends B { function bar($x): stdClass{} }
PHP 7.2より前の形式のエラー:
Fatal error: Can't inherit abstract function A::bar() (previously declared abstract in B)
-0( RFC )を返すことを禁止されたnumber_format()
number_format(-0.00)
への呼び出しはstring(1) “0”
をnumber_format(-0.01)
、 number_format(-0.01)
はstring(2) “-0”
返しました。 これで0が符号なしで返されます。
オブジェクト/配列( RFC )をキャストするときに番号付きキーを変換する機能を追加
背景:
PHPには、キー/値を含む2種類のデータがあります。 1つ目は配列で、文字列または数字の形式でキーを含めることができます。 また、文字列がルール/^(0|(-?[1-9][0-9]*))$/
をPHP_INT_MIN ≤ n ≤ PHP_INT_MAX
、非常に小さいPHP_INT_MIN ≤ n ≤ PHP_INT_MAX
、数値キーに変換されます。
2番目のタイプは、数値キーが許可されておらず、キーが文字列に変換されるオブジェクトです。
同時に、Zend Engineでは単一のHashTable
構造として表示されます。
これは現在修正されています。
いくつかの例を見てみましょう。
$obj = new stdClass; $obj->{'0'} = 1; $obj->{'1'} = 2; $obj->{'2'} = 3; $arr = (array) $obj; var_dump($arr); // , / var_dump($arr[1]); // . PHP 7.2 .
$arr = [0 => 1, 1 => 2, 2 => 3]; $obj = (object)$arr; var_dump($obj); // , / var_dump($obj->{'0'}); // . PHP 7.2 .
get_class()( RFC )にパラメータとしてnullを渡すことは禁止されています
クラスコンテキスト内のget_class()
パラメーターとしてnullが渡されると、関数の動作は非常に予期しないものになる可能性があります。
class Foo { function bar($repository) { $result = $repository->find(100); return get_class($result); } }
$result
にリポジトリから返された有効なオブジェクトが含まれる場合、関数の結果はこのオブジェクトのクラス名になります。
$result
にnull
が含まれる場合、出力にはget_class()
が呼び出されるクラスコンテキストget_class()
この場合はFoo
get_class()
が含まれnull
。
この機能は、「必要な関数のサプライズ係数が高い場合、この関数の再設計が必要になる可能性があります」という最小限の驚きの原則に違反しています。
これで警告が発行されます:
Warning: get_class() expects parameter 1 to be object, null given in %s on line %d
古い動作を維持する場合は、コードを書き直す必要があります。
// : $x = get_class($some_value_that_may_be_null); // : if ($some_value_that_may_be_null === null) { $x = get_class(); } else { $x = get_class($some_value_that_may_be_null); }
カウントできないパラメーターを使用した呼び出しカウント( RFC )
現在、スカラー、null、またはCountableインターフェイスを実装していないオブジェクトのパラメーターを指定してcount()
を呼び出すと、 Warning
が生成されます。
パラメータタイプの拡張性( RFC )
最もホットに議論された変更の1つは、後継でパラメーターのタイプを指定しない機能です。 したがって、相続人はあらゆるタイプのパラメータを受け入れることができます。
class ArrayClass { public function foo(array $foo) { /* ... */ } } class EverythingClass extends ArrayClass { public function foo($foo) { /* ... */ } }
PHP 7.2より前では、エラーが返されました。
Warning: Declaration of EverythingClass::foo($foo) should be compatible with ArrayClass::foo(array $foo) in %s on line 18
「もちろん、SOLIDを地獄に送りましょう。バーバラリスコフとは誰ですか?ある種の狂った女性ですか?もちろん!原則とアイデアを打ち破りましょう。」
他の人は信じています:
「単一責任(単一責任)の原則のような制限は、言語レベルではなく、アプリケーションコードで実装する必要があります。SOLIDの文字Lは、開発者の裁量になります。」
グループ化された名前空間の末尾にカンマを指定する機能が追加されました( RFC )
// $array = [1, 2, 3,]; // use Foo\Bar\{ Foo, Bar, Baz, };
この機能を他のリストに追加することも計画されていましたが、投票段階でキャンセルされ、引き続きParse error
が返されParse error
。
// fooCall($arg1, $arg2, $arg3,); // class Foo implements FooInterface, BarInterface, BazInterface, { // use FooTrait, BarTrait, BazTrait, ; // const A = 1010, B = 1021, C = 1032, D = 1043, ; protected $a = 'foo', $b = 'bar', $c = 'baz', ; private $blah, ; // function something(FooBarBazInterface $in, FooBarBazInterface $out,) : bool { } } // $foo = function ($bar) use ( $a, $b, $c, ) { // . . . };
socket_getaddrinfo( RFC )ファミリーの関数を実装しました
これで、Cで実装されたgetaddrinfo()
からの情報がPHPから利用可能になりますが、これは現在のソケットライブラリにない機能です。 さまざまなネットワークを操作する場合、 libc
にヒントのセットが与えられると、どの接続/リスニングメソッドが最適かを教えてくれると便利です。
4つの機能が承認されました。
socket_addrinfo_lookup(string node[, mixed service, array hints]) : array socket_addrinfo_connect(resource $addrinfo) : resource socket_addrinfo_bind(resource $addrinfo) : resource socket_addrinfo_explain(resource $addrinfo) : array
TLS定数( RFC )の改善
今:
-
tls://
デフォルト値はTLSv1.0 + TLSv1.1 + TLSv1.2
-
ssl://
これはtls://
エイリアスtls://
- 定数
STREAM_CRYPTO_METHOD_TLS_*
のデフォルト値は、TLSv1.0 + TLSv1.1 + TLSv1.2
ではなくTLSv1.0 + TLSv1.1 + TLSv1.2
ですTLSv1.0
- 定数
STREAM_CRYPTO_METHOD_SSLv23_CLIENT
は非推奨と見なされ、後で削除されます。
オブジェクトのタイプヒント( RFC )
ヒントの新しいタイプを追加しました: object
function acceptsObject(object $obj) { // ... } acceptsObject(json_decode('{}')); acceptsObject(new \MyObject()); acceptsObject(" "); function correctFunction() : object { $obj = json_decode('{}'); return $obj; } // function errorFunction() : object { return []; }
LDAP EXOP( RFC )
php-ldapで高度なLDAP操作を使用するために追加された関数。
// EXOP whoami $identity if (ldap_exop($link, LDAP_EXOP_WHO_AM_I, NULL, $identity)) { echo "Connected as $identity\n"; } else { echo "Operation failed\n"; } // , : $r = ldap_exop($link, LDAP_EXOP_WHO_AM_I); if (($r !== FALSE) && ldap_parse_exop($link, $r, $retdata)) { echo "Connected as $retdata\n"; } else { echo "Operation failed\n"; } // : if (ldap_exop_whoami($link, $identity)) { echo "Connected as $identity\n"; } else { echo "Operation failed\n"; } // : if (ldap_exop_passwd($link, 'uid=johndoe,dc=example,dc=com', '', 'newpassword')) { echo "Password changed\n"; } else { echo "Operation failed\n"; }
PHPコアに追加されたLibsodium( RFC )
Libsodiumは、認証された暗号化、楕円曲線を使用した高速暗号化などを提供する最新の暗号化ライブラリです。 他の暗号化標準(WebCryptoなどの暗号化プリミティブのセット)とは異なり、libsodiumには、セキュリティの専門家によって実装された慎重に選択されたアルゴリズムが含まれています。 これにより、サードパーティのチャネルの脆弱性を回避できます。
Argon2パスワードハッシュアルゴリズムが追加されました( RFC )
Argon2は、メモリの高速充填と複数のコンピューティングユニットの効率的な使用を目的とした最新のシンプルなアルゴリズムです。
オブジェクトとしてのHashContext( RFC )
PHP5以降、オブジェクトは内部データを保存するための好ましい構造でした。 何らかの理由で、Hash拡張機能はこれにリソースを使用しました。 このRFCは、ハッシュ拡張機能を翻訳して内部データをオブジェクトとして保存することにより、誤解を修正しようとしています。
内部表現としてリソースを使用する例:
resource hash_copy ( resource $context ) resource hash_init ( string $algo [, int $options = 0 [, string $key = NULL ]] )
内部表現は、リソースからオブジェクトに変換されます。 明示的なis_resource()チェックを使用しない場合、既存のコードは引き続き動作します。これらのチェックはis_resource |に簡単に置き換えることができます。 is_object。
PDO Prepared Statement( RFC )デバッガーを追加
$db = new PDO(...); $stmt = $db->query('SELECT 1'); var_dump($stmt->activeQueryString()); // => string(8) "SELECT 1" $stmt = $db->prepare('SELECT :string'); $stmt->bindValue(':string', 'foo'); // var_dump($stmt->activeQueryString()); // => string(14) "SELECT :string" // $stmt->execute(); var_dump($stmt->activeQueryString()); // => string(11) "SELECT 'foo'"
PDO Prepared Statements v2( RFC )デバッガーを追加
$calories = 150; $colour = 'red'; $sth = $dbh->prepare('SELECT name, colour, calories FROM fruit WHERE calories < ? AND colour = ?'); $sth->bindParam(1, $calories, PDO::PARAM_INT); $sth->bindValue(2, $colour, PDO::PARAM_STR); $sth->execute(); $sth->debugDumpParams(); /* : SQL: [82] SELECT name, colour, calories FROM fruit WHERE calories < ? AND colour = ? Sent SQL: [88] SELECT name, colour, calories FROM fruit WHERE calories < 150 AND colour = 'red' Params: 2 Key: Position #0: paramno=0 name=[0] "" is_param=1 param_type=1 Key: Position #1: paramno=1 name=[0] "" is_param=1 param_type=2 */
PDO( RFC )の高度な文字列型
$db->quote('über', PDO::PARAM_STR | PDO::PARAM_STR_NATL); // N'über' $db->quote('A'); // 'A' $db->setAttribute(PDO::ATTR_DEFAULT_STR_PARAM, PDO::PARAM_STR_NATL); $db->quote('über'); // N'über' $db->quote('A', PDO::PARAM_STR | PDO::PARAM_STR_CHAR); // 'A'
オプションJSON_INVALID_UTF8_IGNOREおよびJSON_INVALID_UTF8_SUBSTITUTE( Request )が追加されました
json_encode
/ json_decode
、無効なUTF-8バイトシーケンスを無視または置換するために、新しいオプションJSON_INVALID_UTF8_IGNORE
およびJSON_INVALID_UTF8_SUBSTITUTE
た。
PHP 7.2から削除
次の機能は廃止され、削除されました。
引用符のないバー(むき出しの単語)( RFC )は削除されました
引用符のない行はE_WARNING
呼び出すようになりました。 PHP2では、このような行によりSyntax error
がSyntax error
しましたが、PHP3ではベータ版の動作が変更されました。
例:
$foo = flase; // , E_NOTICE, . // ... if ( $foo ) { var_dump($foo); // string(5) "flase" }
mcryptをPECLに移植する
PHP 7.1で非推奨になったmcrypt拡張機能は、PECLに移動しました。
PHP 7.2で非推奨( RFC )
次の機能は廃止され、推奨されなくなりました。
この機能はバージョン8.0で削除されます。
非推奨の__autoload
spl_autoload_register
関数は、バージョン5.1でspl_autoload_register
に置き換えられました。
spl_autoload_register
の主な利点は、複数のオートローダーを使用できることです。 これで、コンパイルの段階で非Deprecation notice
がスローされます。
非推奨のpng2wbmp()およびjpeg2wbmp()
Png2wbmp()
およびjpeg2wbmp()
は、直接呼び出すことができるイメージの形式を変更する唯一の関数であり、 ext / gd
で使用できます。libgdはそのような関数を提供しないため、非常に孤立します。 さらに、 WBMP
はWAP
をサポートするために発明されましたが、現在は古くなっています。 これで、 Deprecation notice
がスローされます。
非推奨の$ php_errormsg
track_errors
パラメーターtrack_errors
有効(デフォルトでは無効)で、エラーハンドラーがエラーをインターセプトしなかった場合、致命的でないエラーが発生すると、 $php_errormsg
がローカルエリアに作成されます。
動作がiniファイルの設定に依存するという事実に加えて、それも魔法のようでした。 error_get_last
関数は、最新のエラーを取得するよりクリーンな方法を提供します。 PHP 7以降、 error_clear_last
関数がerror_clear_last
になりました。したがって、スコープを操作することなく、 $php_errormsg
考えられるすべての使用をカバーしています。
非推奨のcreate_function()
create_function()
は、 eval()
言語構成体を囲む薄いシェルであり、生成された名前、引数のリスト、および文字列引数としての本体を使用して関数を作成できます。 PHP 5.3でクロージャーを導入する前は、ラムダ関数に似たものを作成する方法を提供していました。
作業の性質により、潜在的なセキュリティ問題の原因に加えて、 create_function()
パフォーマンスとメモリ使用量の特性は非常に劣っています。 あらゆる方法で実際のクロージャーを使用することが望ましいです。
非推奨のmbstring.func_overload
iniファイルのmbstring.func_overload
パラメーターを使用すると、文字列関数の特定のサブセットを、mbstring拡張機能を持つ類似物に置き換えることができます。 たとえば、 strlen()
は文字列の長さをバイト単位で返さなくなり、代わりに、現在選択されている内部エンコーディングに従って文字単位の長さを返します。
これは、 mbstring.func_overload
を使用するコードmbstring.func_overload
、基本的な文字列操作が正常に機能するという仮定の下で記述されたコードと互換性mbstring.func_overload
ないことを意味します。 一部のライブラリはfunc_overload
(Symfonyなど)を明示的に禁止していますが、他のライブラリは動作を停止します。 func_overloadをサポートするコードは、通常の文字列関数と8ビットエンコーディングのmbstring関数を条件付きで切り替える必要があります(通常、暗号化ライブラリのみがこれを試みます)。
mbstring.func_overload
にゼロ以外の値が含まれている場合、非Deprecation notice
がスローされるようになりました。
非推奨(未設定)キャスト
キャスト(unset)
は、値をNULLにします。 これは、 (unset) expr
は常にnullを返すだけの式であり、他の副作用がないことを意味します。
無駄に加えて、この動作は紛らわしいだけです。なぜなら、多くの人は(unset) $a
を(unset) $a
がunset($a)
と同様に振る舞うと合理的に仮定しているからです。
これで、コンパイルの段階で非Deprecation notice
がスローされます。
2番目の引数のない非推奨のparse_str()関数
parse_str()
関数は、URL文字列を解析し、現在のコンテキストの変数に値を割り当てます(または、結果パラメーターが指定されている場合は配列に値を入れます)。
関数のスコープ内で変数を動的に作成するとregister_globalsとまったく同じ問題が発生するため、結果パラメーターなしでこの関数を使用することは非常に推奨されません。 結果パラメーターが渡されない場合、非Deprecation notice
スローされるようになりました。
非推奨のgmp_random()関数
gmp_random()
関数は、乱数を生成します。 数値は、数値リミッターの積に四肢(リム)のビット数が乗算されるまで、ゼロの範囲になります。 リミッター番号が負の場合、負の結果が返されます。
リムは内部GMPメカニズムです。 技術的には、これは1つの機械語に適合する数の一部です。 その中のビット数はシステムによって異なる場合があります。 基本的には16または32ですが、これは保証されません。 これは、GMP / MPIRの実装をユーザーが利用できないためです。 したがって、この関数を使用するには、四肢のサイズを推測する必要があり、プラットフォームによって異なる場合があります。
これを修正するために、PHP 5.6は関数gmp_random_bits()
およびgmp_random_range()
追加しました。これにより、使用する乱数の範囲を正確に制御できます。 これらの関数は、常にgmp_random()
よりも優先されるべきです。
gmp_random()
がDeprecation notice
スローされます。
廃止された関数each()
each()
関数を使用して、 foreach
などの配列を反復処理できます。 各呼び出しで、現在のキーと値を含む配列を返し、内部配列のポインターを次の位置に進めます。 マニュアルに記載されている一般的な使用法は次のとおりです。
reset($array); while (list($key, $val) = each($array)) { echo "$key => $val\n"; }
each
関数はforeach
ほとんどすべてでforeach
劣り、とりわけ10倍遅くなります。
この機能のサポートにより、一部の言語の変更で問題が発生します。 たとえば、無効な配列コンテナ( RFC )に関する警告では、 list()
を除外する必要がありました。 each
の一般的な使用はeach
警告なしで配列オフセットにfalse
アクセスできるという事実に依存しているためです。
現在、ほとんどの場合ループで使用されるため、 each
の最初の呼び出しで非Deprecation warning
スローされます。
非推奨の文字列引数を使用した()関数のアサート
assert()
関数には2つの操作モードがあります。文字列以外が渡された場合、値がtrueであることを確認します。 文字列が渡された場合、 eval()
を介して起動され、assertはeval()
結果の有効性をチェックします。
この動作の理由は、PHP 7より前では、これが式の評価を防ぐ唯一の方法であったためです。 PHP 7以降、iniファイルのzend.assertions
オプションを使用して、式の評価を回避できます。 したがって、文字列引数の暗黙的な計算をサポートする必要はなくなりました。
assert($value)
を使用assert($value)
を検証すると、 $value
文字列である可能性$value
高い場合にリモートコード実行の脆弱性が発生します。
assert()
文字列引数とともに使用された場合、非Deprecation notice
スローされるようになりました。
エラーハンドラの非推奨の$ errcontext引数
set_error_handler()
を使用して設定されたエラーハンドラは、 $errcontext
最後の引数として渡されます。 この引数は、エラーが生成された場所のすべてのローカル変数を含む配列です。
この関数は、 $errcontext
を使用して現在のスコープ内のすべての参照とオブジェクトを変更できるため、最適化が困難です。 この機能は実際には使用されません。 エラーの場所で状態変数を確認する場合は、デバッガーを使用する必要があります。
エラーコンテキストにはローカル変数のみが含まれていることに注意してください。 $this
および関数の引数を含むバックトレースエラーは、 debug_backtrace()
介して引き続き利用可能です。
この場合、 Deprecation warning
をスローすることは不可能であるため、この機能は単にドキュメントで非推奨としてマークされます。
非推奨の定数INTL_IDNA_VARIANT_2003
PHP 7.2では、定数INTL_IDNA_VARIANT_2003は非推奨です。
PHP 7.4では、 idn_to_ascii()
およびidn_to_utf8()
が変更され、デフォルトの$variant
パラメーターはINTL_IDNA_VARIANT_UTS46になります。
PHP 8.0では、INTL_IDNA_VARIANT_2003のサポートが削除されます。
キャスト(バイナリ)およびb ""リテラル( RFC )は非推奨です
型(binary)
およびb
プレフィックスのサポートは、 PHP 6
との互換性のためにPHP 5.2.1
追加されましたが、このバージョンはまだ登場しておらず、バイナリ文字列を実装しようとする試みがこれ以上ないかは不明です。 ただし、これらは無視されますが、まだ言語スキャナーで受け入れられます。
これらのカーストを使用すると、 Deprecation notice
スローされるようになりました。
バージョン7.2専用に、5から始まるPHPバージョンの変更点を説明する「 PHPの新機能 」というリポジトリを用意しました。
あなたはソースで英語のリストを見つけることができます:
https://github.com/php/php-src/blob/PHP-7.2/UPGRADING
https://wiki.php.net/rfc#php_next_72
新しいバージョンをオンラインで試してください:
https://3v4l.org/
ご覧のとおり、グローバルな変更はほとんどありません。
PHPの変更についてどう思いますか? 最も気に入った機能はどれですか?