PHP 7.2の新機胜

PythonずGoを積極的に䜿甚しおいるにもかかわらず、サヌバヌコヌドの倧郚分はPHPで蚘述されおいたす。 そのため、私たちは蚀語のすべおの革新を泚意深く远っおいたす。 前のマむナヌバヌゞョンのリリヌスから1幎足らずで、8月17日に最埌のベヌタリリヌスが予定されおいたす。 実皌働環境での䜿甚はただ掚奚されおいたせんが、既にdocker imageをダりンロヌドできたす。 蚀語の新しいバヌゞョンで䜕が倉わったのかを理解する時が来たした。



内容



最適化


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 の改善


今



オブゞェクトのタむプヒント 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の倉曎に぀いおどう思いたすか 最も気に入った機胜はどれですか



Source: https://habr.com/ru/post/J335584/


All Articles