PHPを7.0.6に更新するとコードが破損する場合がある

注意! PHPをバージョン7.0.6にアップグレードするときは注意してください! このバージョンでは、コードまたはフレームワークコードが暗黙的に依存する可能性のあるいくつかの重要なバグが修正されました。



PHPのバグ







どのバグが修正されましたか?



bugs.php.net/bug.php?id=62059

bugs.php.net/bug.php?id=69659

bugs.php.net/bug.php?id=71359



テストケース:



最も簡潔なものは、最後のバグの説明(オリジナルのwww.pastebucket.com/97499 )から取得できます。



class Test { protected $attributes = [ 'attribute1' => 'value1', ]; public function __get($name) { print "GET\n"; if (array_key_exists($name, $this->attributes)) { return $this->attributes[$name]; } trigger_error("Property $name does not exist"); return null; } public function __isset($name) { print "ISSET\n"; return array_key_exists($name, $this->attributes); } } $obj = new Test(); var_dump($obj->attribute1 ?? 'default'); //GET //string(6) "value1" var_dump($obj->attribute2 ?? 'default'); //GET //PHP Notice: Property attribute2 does not exist in /var/www/html/test.php on line 23 //string(7) "default"
      
      







もっと簡単にできますか?



はい



特定のケースでは、言語構成体isset()およびempty()を使用する場合、マジックメソッド__isset ()はクラスに存在するときには使用さませんでしたが、代わりに__get()がすぐに呼び出され、返される内容に基づいて決定が行われました。



これは現在修正されています。 すべての場合において、isset()またはempty()がArrayAccess配列オブジェクトの「マジック」プロパティまたは「マジック」キーに適用される場合、__ isset()が最初に呼び出されることが望まれます。



これは個人的にどのように脅迫しますか?



クラスに__get()メソッドがあり、__ isset()メソッドがない場合、コードが破損するためです。 今後、このような場合はすべて、isset()は常にfalseを返し、空()=== trueを返します



どうする



7.0.5にロールバックし、コードを慎重にリファクタリングします。 __get()はあるが__isset()はない場所がたくさんあることはまずありません。 その後、コードアナライザーに適切なルールを追加し、そのような有毒なコードのコミットを禁止するとよいでしょう。



All Articles