PHP 7の概要:新機能と廃止点

公開: 2022-03-11

PHPの世界で2015年に最もエキサイティングなイベントの1つは、最後のメジャーバージョンであるPHP5のリリースから10年後のPHP7のリリースでした。大きな前進とともに、PHP7は多くの新機能とパフォーマンスのアップグレードを導入します。 。

ただし、古い非推奨の機能も削除されるため、互換性が失われ、古いアプリケーションを新しいバージョンに移行するのが難しくなります。 このガイドは、PHP 7に加えて、既存のアプリケーションを移動したり、新しいアプリケーションを構築したりする場合に何が期待できるかについてのクイックツアーとして役立つはずです。

しかし、待ってください、PHP 6はどこに行きましたか?

最近PHPを使用していない場合は、PHP 6に何が起こったのか、なぜPHP5からPHP7にスキップするのか疑問に思われるかもしれません。 簡単に言えば、PHP6は失敗でした。 バージョン6の主な機能はUnicode文字のネイティブサポートでした。PHPは主にWeb開発で使用され、WebにはUnicodeが必要であるため、UnicodeをPHPに導入する動きは理にかなっています。

アイデアは、Unicodeの完全なサポートをコア自体にもたらすことでした。 それは、変数名や関数名として愚かな絵文字を使用する機能から、強力な国際文字列機能まで、言語に拡張機能をもたらしたでしょう。 たとえば、別の言語で英語とは異なる大文字と小文字が使用されている場合や、漢字の名前を英語に変換する必要がある場合です。

残念ながら、この野心的な計画は予想よりも大きな問題であることが判明しました。 コードベースの多くは、コア拡張機能と重要な拡張機能の両方でUnicodeをサポートするように移植する必要がありましたが、これは面倒で注意が必要でした。 これにより、言語の他の機能の開発が遅くなり、その過程で多くのPHP開発者を苛立たせました。 追加のハードルが現れ、ネイティブUnicodeサポートの開発への関心が低下し、最終的にプロジェクトが放棄されることになりました。

本や記事などのリソースはPHP6とそのUnicodeサポート用に作成されていたため、混乱を避けるために、新しいバージョンの名前はPHP7に変更されます。

とにかく、悲しい過去に十分住んでいたので、PHP7がパーティーに何をもたらすか見てみましょう。

パフォーマンスバトル、PHP7とPHP5

事実上すべてのアップデートで、マイナーなパフォーマンスのアップグレードが期待されます。 ただし、今回のPHPは、以前のバージョンに比べて大幅な改善をもたらし、PHP7の最も魅力的な機能の1つに優れたパフォーマンスをもたらします。 これは、ZendEngine自体の内部に取り組む「PHPNG」プロジェクトの一部として提供されます。

内部データ構造をリファクタリングし、抽象構文ツリー(AST)の形式でコードコンパイルに中間ステップを追加することにより、優れたパフォーマンスとより効率的なメモリ割り当てが実現します。 数字自体は非常に有望に見えます。 実際のアプリで行われたベンチマークによると、PHP7は平均してPHP5.6の2倍の速度であり、リクエスト中のメモリ消費量が50%少なくなり、PHP7はFacebookのHHVMJITコンパイラーの強力なライバルになります。 いくつかの一般的なCMSとフレームワークのパフォーマンスを描いたZendのこのインフォグラフィックをご覧ください。

画像:PHP7とPHP5のパフォーマンスの図。

メモリ消費量の減少により、PHPを中心にマイクロサービスを構築する機会とともに、より小さなマシンがリクエストをより適切に処理できるようになります。 内部の変更、特にASTの実装は、パフォーマンスをさらに向上させる可能性のある将来の最適化の可能性も開きます。 JITコンパイラの新しい社内実装は、将来のバージョンで検討されています。

PHP7シンタックスシュガー

PHP 7には、新しい構文機能が付属しています。 言語自体の機能を拡張することはありませんが、コードをより楽しく、見た目に心地よいものにするための、より優れた、またはより簡単な方法を提供します。

グループ輸入宣言

これで、同じ名前空間から発生したクラスのインポート宣言を1つのuse行にグループ化できます。 これは、意味のある方法で宣言を整列させるのに役立つか、単にファイルにいくつかのバイトを保存するのに役立ちます。

 use Framework\Module\Foo; use Framework\Module\Bar; use Framework\Module\Baz;

PHP 7では、次のものを使用できます。

 use Framework\Module\{Foo, Bar, Baz};

または、複数行のスタイルを好む場合:

 use Framework\Module{ Foo, Bar, Baz };

ヌル合体演算子

これにより、PHPプログラミングの一般的な問題が解決されます。この問題では、別の変数が実際に設定されている場合は別の変数から変数に値を割り当てたり、別の変数に別の値を指定したりします。 これは、ユーザー提供の入力を処理するときに一般的に使用されます。

PHP 7より前:

 if (isset($foo)) { $bar = $foo; } else { $bar = 'default'; // we would give $bar the value 'default' if $foo is NULL }

PHP 7以降:

 $bar = $foo ?? 'default';

これは、いくつかの変数と連鎖させることもできます。

 $bar = $foo ?? $baz ?? 'default';

宇宙船オペレーター

宇宙船演算子<=>を使用すると、2つの値を3方向に比較できます。これらの値が等しいかどうかだけでなく、1,0または-1を返すことで、不等式でどちらが大きいかを示します。

ここでは、値の違いに応じてさまざまなアクションを実行できます。

 switch ($bar <=> $foo) { case 0: echo '$bar and $foo are equal'; case -1: echo '$foo is bigger'; case 1: echo '$bar is bigger'; }

比較される値は、整数、浮動小数点数、文字列、または配列ですらあります。 ドキュメントを確認して、さまざまな値が互いにどのように比較されているかを確認してください。 [https://wiki.php.net/rfc/combined-comparison-operator]

PHP7の新機能

しかしもちろん、PHP7には新しくエキサイティングな機能もあります。

スカラーパラメータタイプとリターンタイプのヒント

PHP 7は、4つのスカラー型を追加することにより、メソッド(クラス、インターフェイス、および配列)のパラメーターの以前の型宣言を拡張します。 可能なパラメータタイプとして、整数( int )、float( float )、booleans( bool )、strings( string )。

さらに、オプションで、メソッドと関数が返すタイプを指定できます。 サポートされているタイプは、 boolintfloatstringarraycallableクラスまたはインターフェイスの名前、 selfおよびparent (クラスメソッドの場合)です。

 class Calculator { // We declare that the parameters provided are of type integer public function addTwoInts(int $x, int $y): int { return $x + $y; // We also explicitly say that this method will return an integer } }

型宣言により、より堅牢なアプリケーションを構築し、関数から誤った値を渡したり返したりすることを回避できます。 その他の利点には、静的コードアナライザーとIDEがあり、DocBlockが欠落している場合にコードベースに関するより良い洞察を提供します。

PHPは弱い型の言語であるため、パラメーター型と戻り型の特定の値はコンテキストに基づいてキャストされます。 int型の宣言されたパラメーターを持つ関数に値「3」を渡すと、インタープリターはそれを整数として受け入れ、エラーをスローしません。 これが不要な場合は、 declareディレクティブを追加してstrict modeを有効にできます。

declare(strict_types=1);

これはファイルごとに設定されます。グローバルオプションでは、コードリポジトリがグローバルな厳密性構築されたリポジトリとそうでないリポジトリに分割されるため、両方のコードを組み合わせると予期しない動作が発生します。

エンジンの例外

エンジンの例外を追加すると、スクリプトの終了につながる致命的なエラーを簡単にキャッチして処理できます。

存在しないメソッドを呼び出すなどのエラーはスクリプトを終了しません。代わりに、try catchブロックで処理できる例外をスローします。これにより、アプリケーションのエラー処理が改善されます。 致命的なエラーが発生すると再起動が必要になるため、これは特定の種類のアプリ、サーバー、デーモンにとって重要です。 致命的なエラーによってテストスイート全体が削除されるため、PHPUnitでのテストもより使いやすくなるはずです。 エラーではなく例外は、テストケースごとに処理されます。

PHP 7は、発生する可能性のあるエラーのタイプに基づいて、いくつかの新しい例外クラスを追加します。 バージョン間の互換性を維持するために、エンジン例外とユーザー例外の両方から実装できる新しいThrowableインターフェースが追加されました。 これは、エンジン例外を回避して基本例外クラスを拡張するために必要であり、以前は存在しなかった古いコードキャッチ例外が発生していました。

PHP 7より前では、これは致命的なエラーでスクリプトを終了していました。

 try { thisFunctionDoesNotEvenExist(); } catch (\EngineException $e) { // Clean things up and log error echo $e->getMessage(); }

匿名クラス

匿名クラスは、単純な短期インスタンスで使用できる匿名関数のいとこです。 匿名クラスは、通常のオブジェクトと同じように簡単に作成して使用できます。 これがドキュメントの例です。

PHP7以前

class MyLogger { public function log($msg) { print_r($msg . "\n"); } } $pusher->setLogger( new MyLogger() );

匿名クラスの場合:

 $pusher->setLogger(new class { public function log($msg) { print_r($msg . "\n"); } });

匿名クラスは、単体テスト、特にテストオブジェクトとサービスのモック作成に役立ちます。 これは、モックしたいインターフェースを提供する単純なオブジェクトを作成することにより、重いモックライブラリとフレームワークを回避するのに役立ちます。

CSPRNG関数

暗号的に安全な文字列と整数を生成するための2つの新しい関数が追加されました。

 random_bytes(int $len);

長さが$lenのランダムな文字列を返します。

 random_int(int $min, int $max);

$minから$maxまでの数値を返します。

Unicodeコードポイントエスケープ構文

他の多くの言語とは異なり、PHP 7より前のPHPには、文字列リテラルでUnicodeコードポイントをエスケープする方法がありませんでした。 この機能は、エスケープ\uシーケンスを追加して、UTF-8コードポイントを使用してそのような文字を生成します。 これは、文字を直接挿入するよりも優れており、非表示の文字や、同じグラフィック表現で意味が異なる文字をより適切に処理できます。

echo "\u{1F602}"; // outputs ‚

これは動作を変更するため、 \uシーケンスで既存のコードを壊すことに注意してください。

発電機がアップグレードされる

PHPのジェネレーターには、いくつかの優れた追加機能もあります。 現在、ジェネレーターには、反復後に最終値を出力できるようにするために使用できるreturnステートメントがあります。 これは、ジェネレーターがエラーなしで実行されたことを確認するために使用でき、ジェネレーターを呼び出したコードがさまざまなシナリオを適切に処理できるようにします。

さらに、ジェネレーターは他のジェネレーターから式を返し、生成することができます。 これにより、複雑な操作をより単純なモジュール式のユニットに分割できます。

 function genA() { yield 2; yield 3; yield 4; } function genB() { yield 1; yield from genA(); // 'genA' gets called here and iterated over yield 5; return 'success'; // This is a final result we can check later } foreach (genB() as $val) { echo "\n $val"; // This will output values 1 to 5 in order } $genB()->getReturn(); // This should return 'success' when there are no errors.

期待

期待値は、下位互換性を維持しながら、 assert()関数を拡張したものです。 これらは、本番コードでゼロコストのアサーションを可能にし、アサーションが失敗したときにカスタム例外をスローする機能を提供します。これは、開発中に役立ちます。

assert()は、PHP 7の言語構造になります。アサーションは、開発環境とテスト環境でのみデバッグ目的で使用する必要があります。 その動作を構成するために、2つの新しいディレクティブが提供されます。

  • zend.assertions
    • 1 :コードの生成と実行(開発モード)(デフォルト値)
    • 0 :コードを生成しますが、実行時にジャンプします
    • -1 :コードを生成せず、コストをゼロにします(本番モード)
  • assert.exception
    • 1 :例外として提供されたオブジェクトをスローするか、例外が提供されなかった場合は新しいAssertionErrorオブジェクトをスローすることにより、アサーションが失敗したときにスローします。
    • 0 :上記のようにThrowableを使用または生成しますが、オブジェクトをスローするのではなく、そのオブジェクトに基づいて警告を生成するだけです(PHP 5の動作と互換性があります)

PHP5からPHP7への移行の準備

メジャーリリースの導入により、古い機能を変更/更新したり、古すぎると見なされたり、しばらくの間廃止された場合は削除したりする機会がもたらされます。 このような変更により、古いアプリケーションの互換性が損なわれる可能性があります。

このようなバージョンの飛躍から生じるもう1つの問題は、依存している重要なライブラリとフレームワークが、最新バージョンをサポートするようにまだ更新されていない可能性があることです。 PHPチームは、新しい変更を可能な限り下位互換性を持たせ、新しいバージョンへの移行を可能な限り簡単に行えるように努めました。 新しい、より最新のアプリは、新しいバージョンへの移行が容易であることがわかるはずですが、古いアプリは、メリットがコストを上回るかどうかを判断しなければならない場合があり、更新しないことを選択する可能性があります。

ほとんどの休憩は軽微であり、簡単に軽減できますが、他の休憩はより多くの労力と時間を必要とする場合があります。 基本的に、PHP 7をインストールする前にアプリケーションで非推奨の警告があった場合、修正されるまでアプリケーションを壊すエラーが発生する可能性があります。 警告されましたよね?

古いSAPIと拡張機能

最も重要なことは、古くて廃止されたSAPIがmysql拡張機能のように削除されたことです(ただし、そもそもこれを使用するべきではありませんよね?)。 拡張機能と削除された機能の完全なリストについては、このRFCをこことここで確認できます。

さらに、他のSAPIがPHP7に移植されています。

古いSAPIと拡張機能のロードはPHP7から削除されました。これらを見逃すことはないと推測しています。

一様変数構文

この更新により、変数-変数構造の一貫性を優先するためにいくつかの変更が行われました。 これにより、変数を使用したより高度な式が可能になりますが、以下に示すように、他の場合には動作に変更が加えられます。

 // old meaning // new meaning $$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']()

これにより、このような値にアクセスするアプリケーションの動作が損なわれます。 一方、あなたはこのようないくつかのきちんとしたことをすることができます:。

 // Nested () foo()(); // Calls the return of foo() $foo->bar()(); // IIFE syntax like JavaScript (function() { // Function body })(); // Nested :: $foo::$bar::$baz

古いスタイルのタグが削除されました

開始/終了タグ<% ... %><%= ... %><script language="php"> ... </script>は削除され、無効になりました。 それらを有効なものと交換するのは簡単なはずですが、とにかくそれらを使用して何をしているのですか、Weirdo?

クラス、インターフェイス、および特性の名前が無効です

パラメータやリターンタイプなどの追加の結果、クラス、インターフェイス、およびトレイトに次の名前を付けることはできなくなりました。

  • ブール
  • int
  • 浮く
  • ストリング
  • ヌル
  • true
  • false

これらは、それらを使用する既存のアプリケーションとライブラリに障害を引き起こしますが、簡単に修正できるはずです。 また、エラーは発生せず有効ですが、将来の使用のために予約されているため、以下は使用しないでください。

  • 資源
  • 物体
  • 混合
  • 数値

それらの使用を控えることで、将来それらを変更する作業を省くことができます。

互換性を損なう可能性のある変更の完全なリストについては、このドキュメントを確認してください。

php7ccを使用することもできます。これは、コードをチェックし、PHP 7に移行した場合に発生する可能性のある潜在的な問題を検出できます。ただし、もちろん、PHP7をインストールして自分で確認するよりも良い方法はありません。

PHP7の互換性に関する潜在的な問題

PHP7インフラストラクチャの互換性

多くのホスティングサービスがPHP7のサポートを追加し始めています。これは、パフォーマンスの向上により、ハードウェア上のクライアントWebサイトの数を増やし、運用コストを削減し、マージンを増やすことができるため、共有ホスティングプロバイダーにとって朗報です。 クライアント自身に関しては、これらの条件下であまりブーストを期待するべきではありませんが、公平を期すために、共有ホスティングはとにかくパフォーマンス指向の選択ではありません。

一方、仮想プライベートサーバーまたは専用サーバーを提供するサービスは、このパフォーマンスの向上のメリットを最大限に活用します。 Herokuのような一部のPaaSサービスは早い段階でPHP7をサポートしていましたが、AWSBeanstalkやOracleのOpenShiftなどの他のサービスは遅れをとっています。 PaaSプロバイダーのWebサイトをチェックして、PHP 7がすでにサポートされているかどうか、またはサポートが近い将来に行われるかどうかを確認してください。

もちろん、IaaSプロバイダーを使用すると、ハードウェアを制御してPHP 7をインストールできます(または、好みに応じてコンパイルできます)。 PHP 7パッケージは、主要なIaaS環境ですでに利用可能です。

PHP7ソフトウェアの互換性

インフラストラクチャの互換性に加えて、潜在的なソフトウェアの互換性の問題にも注意する必要があります。 WordPress、Joomla、Drupalなどの人気のあるコンテンツ管理システムは、最新リリースでPHP7のサポートを追加しました。 SymfonyやLaravelなどの主要なフレームワークも完全にサポートされています。

ただし、注意が必要です。 このサポートは、アドオン、プラグイン、パッケージ、またはCMSやフレームワークがそれらを呼び出すものの形式のサードパーティコードには拡張されません。 彼らは互換性の問題に苦しんでいる可能性があり、すべてがPHP7に対応していることを確認するのはあなたの責任です。

アクティブで保守されているリポジトリの場合、これは問題にはなりません。 ただし、PHP 7のサポートがない、古くてメンテナンスされていないリポジトリでは、アプリ全体が使用できなくなる可能性があります。

PHPの未来

PHP 7のリリースにより、古くて時代遅れのコードが削除され、将来の新機能とパフォーマンスのアップグレードへの道が開かれました。 さらに、PHPはまもなく追加のパフォーマンス最適化を取得することが期待されています。 過去のリリースとの互換性が失われていますが、ほとんどの問題は簡単に解決できます。

ライブラリとフレームワークは現在、コードをPHP 7に移行しているため、最新バージョンを利用できるようになっています。 ぜひお試しいただき、結果をご確認ください。 たぶん、あなたのアプリケーションはすでに互換性があり、PHP 7の使用を待っており、その恩恵を受けています。

関連: PHP開発者が犯す最も一般的な10の間違いのリスト