ホームページ  >  記事  >  バックエンド開発  >  PHP8.2 にはどのような変更が含まれますか (パフォーマンスの向上、新機能)!

PHP8.2 にはどのような変更が含まれますか (パフォーマンスの向上、新機能)!

青灯夜游
青灯夜游転載
2022-07-04 14:28:214116ブラウズ

PHP8.2のリリース時期は未定ですが、2022年末にリリースされる予定です。この記事では、新バージョンの機能、パフォーマンスの向上、廃止された機能などを紹介します。

関連する推奨事項: PHP8.2 の最新の進歩、新機能は間もなく凍結されます。

#null と false は独立した型として扱われます

PHP は完全な型安全性の方向には陥りませんただし、技術的な観点からは、null と false を独立したデータ型として扱うことには価値があります。通常の状況では、PHP の多くの一般的な関数は false を返してエラーを示します。たとえば、file_get_content の場合:

file_get_contents(/* … */): string|false

以前は false を共用体型で使用できましたが、単独で使用することはできませんでしたが、PHP8.2 では単独で使用できるようになりました:

function alwaysFalse(): false
{
    return false;
}

もちろん、このアプローチに対して、一部の開発者は慎重です。 true は独立した型としてサポートされません。これらの開発者は、false は単なる値であり、型は値ではなくカテゴリを表す必要があると信じています。もちろん、型システムにはユニット型という概念があり、これは値を 1 つだけ許可する型です。しかし、これは本当に効果があるのでしょうか?

しかし、別の RFC では、PHP に true を型として追加することについても議論されています。

独立した null は非常に意味があり、空のオブジェクト パターンを簡単に実装できます。

class Post
{
    public function getAuthor(): ?string { /* … */ }
}

class NullPost extends Post
{
    public function getAuthor(): null { /* … */ }
}

これは、NullPost::getAuthor() に対しても言えることですが、null のみを返します。その場合、null と string を一緒に宣言する必要があります。

動的プロパティの非推奨

これは言語仕様としては優れた設計ですが、多くの用途が制限されます。動的プロパティは PHP 8.2 では非推奨となり、PHP ではエラー例外がスローされます。

動的プロパティとは何ですか?つまり、これらのプロパティをクラスで宣言していませんが、設定および取得は可能です:

class Post
{
    public string $title;
}

// …

$post->name = 'Name';  // 在PHP8.2中不能这样使用,因为并没有在类中声明

ただし、心配しないでください。__set や __get などのマジック メソッドは引き続き期待どおりに動作します:

class Post
{
    private array $properties = [];

    public function __set(string $name, mixed $value): void
    {
        $this->properties[$name] = $value;
    }
}

// …

$post->name = 'Name';

標準オブジェクト 同じこと: stdClass は引き続き動的プロパティをサポートします。

PHP はかつては非常に動的な動的言語でしたが、現在では多くの人がより厳密なプログラミング手法を受け入れています。できる限り厳密にし、可能な限り静的解析に依存することは、開発者がより良いコードを作成できるため、良いことです。

ただし、動的プロパティを重視する一部の開発者は、この変更に非常に満足していない可能性があります。PHP8.2 を使用するときにこれらの警告を表示したくない場合は、次のようにすることができます:

はい

#[AllowDynamicProperties]

#[AllowDynamicProperties]
class Post
{
    public string $title;
}

// …

$post->name = 'Name'; // 一切正常

を使用する別の方法は、アラーム レベルを変更することですが、これはお勧めできません。 PHP9.0 にアップグレードしようとすると、問題が発生します。

error_reporting(E_ALL ^ E_DEPRECATED);

呼び出しトレース時のパラメータの感度の解除

パラメータの感度の解除とは何ですか?開発時やエラーが発生した場合は、トレースを使用してデバッグしますが、現在のスタックには、環境変数、パスワード、ユーザーなどの機密データが記録されます。

PHP8.2 では、一部のパラメーターの感度を下げるなど、パラメーターの一部の編集が許可されています (リダクト、編集と呼びましょう、何らかの変更の意味がありますが、それを直接変更と呼ぶのは適切ではありません)。これらのパラメータの呼び出し値はスタック情報にリストされません:

function test(
    $foo,
    #[\SensitiveParameter] $bar,
    $baz
) {
    throw new Exception('Error');
}

test('foo', 'bar', 'baz');

エラーが報告された場合、2 番目のパラメータ バーに実際の値が記録されていないことがわかります。これにより、感度が低下する可能性があり、パスワードが渡されても記録されません。

Fatal error: Uncaught Exception: Error in test.php:8
Stack trace:
#0 test.php(11): test('foo', Object(SensitiveParameterValue), 'baz')
#1 {main}
  thrown in test.php on line 8

一部のオブジェクトの呼び出しメソッドは非推奨になりました

オブジェクトを呼び出す以前のいくつかのメソッドは非推奨になりました。これらの一部は、$callable() で直接呼び出すのではなく、call_user_func($callable) を通じて呼び出す必要があります。

"self::method"
"parent::method"
"static::method"
["self", "method"]
["parent", "method"]
["static", "method"]
["Foo", "Bar::method"]
[new Foo, "Bar::method"]

なぜこんなことをするのですか? Nikita は RFC ディスカッションでこれについて詳しく説明しました:

これらの非推奨の呼び出しはコンテキスト固有であり、「self::method」によって参照されるメソッドは、呼び出しが実行されるクラスまたは呼び出し可能性チェックによって異なります。 。実際、これは通常、[new Foo, "parent::method"] の形式で使用される場合、最後の 2 つのケースにも当てはまります。

呼び出し可能オブジェクトのコンテキスト依存性を軽減することは、この RFC の 2 番目の目標です。この RFC 以降、残っているスコープの依存関係はメソッドの可視性だけです。「Foo::bar」はあるスコープでは可視であっても、別のスコープでは可視ではない可能性があります。将来、呼び出し可能なオブジェクトがパブリック メソッドに限定される場合、呼び出し可能な型は明確に定義され、プロパティ型として使用できるようになります。ただし、可視性の処理の変更は、この RFC の一部として推奨されません。

#未定義変数の検出メカニズムとレベルを改善します未定義変数とは、読み取られる前に読み取られていない変数です。初期化中の変数。現在、未定義の変数にアクセスすると、E_WARNING「警告: 未定義の変数 $varname」が発行され、変数は null として扱われますが、実行は中断されないため、コードの実行は衰えることなく続行されますが、予期しない状態になる可能性があります。

現在、一部の設定を使用して、PHP が実行時に未定義の変数に対してエラーレベルの例外を生成できるようにすることができますが、これには別の設定が必要です。 PHP はデフォルトでより安全なチェックを提供する必要があります。

一般什么情况下会出现未定义变量的情况呢?

用法1

变量在某个分支中声明,比如在if中设置一个值。

if  ( $user -> admin )  {
   $restricted  =  false ;
}

if  ( $restricted )  {
   die ( '你没有进入这里的权限' ) ;
}

用法2

变量拼写错误:

$name = 'Joe';
echo 'Welcome, ' . $naame;

这种用法在1中也可能会发生:

if ($user->admin) {
   $restricted = false;
} else {
   $restrictedd = true;
}

if ($restricted) {
   die('You do not have permission to be here');
}

用法3

在循环中定义,但这个循环可能并没有执行:

while ($item = $itr->next()) {

   $counter++; // 定义变量
}

  // 这里调用了变量,但是很有可能并没有定义这个变量
echo 'You scanned ' . $counter . ' items';

解决方法

在这些分支之前提前定义好一个默认值。

对于第1种用法:

$restricted = true;
if ($user->admin) {
   $restricted = false;
}

if ($restricted) {
   die('You do not have permission to be here');
}

对于第3种用法:

$counter = 0;
while ($item = $itr->next()) {
   $counter++;
}

echo 'You scanned ' . $counter . ' items';

这样做的好处是消除了整个访问和使用这些未定义变量的后果,以及回退到引擎默认状态的用户态错误。这样我们提供了另一层保护,防止PHP程序发生了这种意外后继续运行。

这种更改也会让PHP引擎和JIT等方面不会那么复杂。

这个版本主要是针对PHP9.0的,在PHP8.2的还是警告,在以后会将这种行为提升到错误级别。

增加只读类

通过给类添加只读修饰符来声明只读类。

readonly class Test {
    public string $prop;
}

这样做会隐式地将类的所有实例属性标记为只读。此外,它将阻止创建动态属性。 

readonly class Foo
{
    public int $bar;

    public function __construct() {
        $this->bar = 1;
    }
}

$foo = new Foo();
$foo->bar = 2;
// 抛出错误,不能修改只读属性 Foo::$bar

$foo->baz = 1;
// 抛出错误:不能动态创建属性 Foo::$baz

可以通过增加#[AllowDynamicProperties]属性,可以不触发错误的情况下创建动态属性。

#[AllowDynamicProperties]
readonly class Foo {
}

一些限制:

由于是只读类,必须对属性声明类型:

readonly class Foo
{
    public $bar;
}
// 以上定义会产生错误。

不能使用静态属性:

readonly class Foo
{
    public static int $bar;
}
// 抛出错误: 只读属性不能声明静态类型

原文地址:https://phpreturn.com/index/a626a74a300dc5.html

原文平台:PHP武器库

版权声明:本文由phpreturn.com(PHP武器库官网)原创和首发,所有权利归phpreturn(PHP武器库)所有,本站允许任何形式的转载/引用文章,但必须同时注明出处。

推荐学习:《PHP视频教程

以上がPHP8.2 にはどのような変更が含まれますか (パフォーマンスの向上、新機能)!の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はphpreturn.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。