ホームページ  >  記事  >  バックエンド開発  >  PHP7での設定

PHP7での設定

Guanhui
Guanhui転載
2020-05-09 11:09:092835ブラウズ

php7 のアップグレード後に isset が正しくありません

php7 のアップグレード後に会社に問題が発生しました

これと同様の isset($post->user-> ; name) は常に falseです

以前の PHP 5.6 では正常でした

laravel のバージョンは 5.1.35 (長い間アップグレードされていません)

最初に isset# を見てください

##isset は変数が設定されているかどうかを検出するために使用されます

まずは公式の例を見てみましょう

大まかに次のことを意味します

<?php
class Post
{
    protected $attributes = [&#39;content&#39; => &#39;foobar&#39;];
    public function __get($key)
    {
        if (isset($this->attributes[$key])) {
            return $this->attributes[$key];
        }
    }
}
$post = new Post();
echo isset($post->content);  // false

上記の例では、常に false が返されます。foo は Post のプロパティではなく、__get

Magic メソッド__isset# によって取得されるプロパティであるためです。 ##それでは、上記の問題を解決するにはどうすればよいでしょうか?マジックメソッドの使用

<?PHP
class Post
{
    protected $attributes = [&#39;content&#39; => &#39;foobar&#39;];
    public function __get($key)
    {
        if (isset($this->attributes[$key])) {
            return $this->attributes[$key];
        }
    }
    public function __isset($key)
    {
        if (isset($this->attributes[$key])) {
            return true;
        }
        return false;
    }
}
$post = new Post();
echo isset($post->content);   //true

Eloquentに似た例

laravel 5.1.35のコードを見て、自分たちで簡単な例を書きます

最初のAモデル、簡単な実装。 __get、__set、__isset

class Model
{
    // 存放属性
    protected $attributes = [];
    // 存放关系
    protected $relations = [];
    public function __get($key)
    {
        if( isset($this->attributes[$key]) ) {
            return $this->attributes[$key];
        }
          // 找到关联的对象,放在关系里面
        if (method_exists($this, $key)) {
              $relation = $this->$method();   
              return $this->relations[$method] = $relation;
        }
    }
    public function __set($k, $v)
    {
        $this->attributes[$k] = $v;
    }
    public function __isset($key)
    {
        if (isset($this->attributes[$key]) || isset($this->relations[$key])) {
            return true;
        }
        return false;
    }
}

次に、Post Moel と User Moel を定義します

class Post extends Model
{
    protected function user()
    {
        $user = new User();
        $user->name = &#39;user name&#39;;
        return $user;
    }
}
class User extends Model
{
}

わかりました、issetを確認しましょう

$post = new Post();
echo &#39;isset 发帖用户:&#39;;
echo isset($post->user) ? &#39;true&#39; : &#39;false&#39;;  // false
echo PHP_EOL;
echo &#39;isset 发帖用户的名字:&#39;;
echo isset($post->user->name) ? &#39;true&#39; : &#39;false&#39;;  // false
echo PHP_EOL;
echo &#39;发帖用户的名字:&#39;;
echo $post->user->name;    // user name
echo PHP_EOL;
echo &#39;再次判断 isset 发帖用户的名字:&#39;;
echo isset($post->user->name) ? &#39;true&#39; : &#39;false&#39;;   // true
echo PHP_EOL;

Answer

上記の結果を分析すると、PHP 7 の isset メソッドのオブジェクトの判定が変わったような気がします 一度実行すると、$post->user->name、つまり user がリレーションに入れられますしたがって、 isset ($post->user) が true になり、次に isset ($post->user->name) が true になります。

ついに Eloquent モデルの git ログで答えが見つかりました。

PHP 7 は、

ネイティブ isset メソッドと空のメソッドの両方に影響する __isset のバグを修正しました。これにより、Eloquent のリレーションの isset または empty をチェックする際に特定の問題が発生します。

PHP 7 では、アンロードされたリレーションにプロパティが存在するかどうかをチェックします。

たとえば isset( $this->relation->id) は常に

を返します。これは、PHP 5.6 とは異なり、PHP 7 では

## にチェーンする前に各属性のオフセットを

チェックするためです。 #次の 1 つです。PHP 5.6 では、オフセットをチェックせずにリレーション

を積極的にロードしていました。この変更により、コア Eloquent モデル __isset メソッド

## の意図した動作が戻ります。 #PHP 7 では、PHP 5.6 と同じように動作します。

参考までに、次のリンクを確認してください。

具体的には、Nikita Popov のコメント (コア PHP 開発者) -

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

php7 issetで判断すると、おおよそ、順番に判断されます。 php5.6 ではリレーションシップがプリロードされます。実はlaravelでも5月の時点で関連する処理を行っていたので、laravelをバージョンアップすれば自然とこの問題は解消されるでしょう。

推奨チュートリアル: 「

PHP7 チュートリアル

」 「

PHP チュートリアル

」 「
Laravel チュートリアル

以上がPHP7での設定の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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