5

以下の行が何を意味するのか、誰にもわかりますか?

以下の行は、 PHP マニュアルからコピーされたものです。

ノート:

isset() 以外の言語構造では、オーバーロードされたプロパティを使用することはできません。つまり、オーバーロードされたプロパティで empty() が呼び出された場合、オーバーロードされたメソッドは呼び出されません。

この制限を回避するには、オーバーロードされたプロパティをスコープ内のローカル変数にコピーしてから、empty() に渡す必要があります。

しかし、これは、オーバーロードされたプロパティで empty() を呼び出すことができないという事実ではありません。 empty() を呼び出すと、__isset() がトリガーされました

4

3 に答える 3

5

これはドキュメントのバグです:

<?php
class PropNameReturn {
    function __isset($propname){
          return true;

    }
    function __get($propname){
          echo 'Yes, it IS called!'.PHP_EOL;
          return $propname;
    }
}
$o = new PropNameReturn();
var_dump(empty($o->this_prop_name));
//Yes, it IS called!
//bool(false)
$b = new stdClass();
var_dump(empty($b->this_prop_name));
//bool(true)
于 2012-06-16T13:17:16.127 に答える
4

マニュアルが間違っているようです。これは PHP 5.2 でも機能します。

ちなみに で__get()使用すると が呼び出されるようですempty()が、結果も に依存し__isset()ます。

empty()__isset()true __get()返し、空の値を返す場合にのみtrue を返します。

このコード例を参照してください。

class Foo {
    function __get($name) {
        if ($name == "bar")
            return '';
    }
    function __isset($name) {
        if ($name == "bar")
            return true;
    }
}
$foo = new Foo();
echo $foo->bar . PHP_EOL;  // outputs "" - correct
echo var_export(isset($foo->bar)) . PHP_EOL; // outputs "true" - correct

$bar = $foo->bar;

// outputs both "true" -- so the manual is wrong here
echo var_export(empty($foo->bar)) . PHP_EOL;
echo var_export(empty($bar)) . PHP_EOL;

このバグレポートも参照してください

于 2012-06-16T13:15:36.750 に答える
0

どうやら、あなたが自分の質問に含めたリンクに気付かなかったようです。そのため、オーバーロードの基本的な内訳を次に示します。

PHP でのオーバーロードは、メソッドとパラメーターを動的に作成するという概念です。基本的なシナリオを考えてみましょう:

class MyClass {
  public $foo = 'bar';
}

$Instance = new MyClass();
echo $Instance->foo;

私たちは皆、それが「バー」を出力することを期待していますが、そうです。オーバーロードを使用した同じ例を次に示します。

class MyOverloadedClass {
  public function __get($variable) {
    return $variable == 'foo' ? 'bar' : '';
  }
}

 $Instance = new MyOverloadedClass();
 echo $Instance->foo;

この 2 番目の例では、MyOverloadedClass::$foo が存在しないため、__ge メソッドが実行され、ユーザーが要求した変数 (この場合は "foo") が渡されます。__get メソッド内の私のコードは、ユーザーが foo を探していると判断し、"bar" を返します。

言語構造は PHP 言語の一部です。言い換えれば、パーサーはそれらを解釈し、関数参照を検索することなく何をすべきかを知っています。いくつかの例は、exit、die、print、echo、isset、empty です。

isset() は、オーバーロードを処理する唯一の言語構造です。マニュアルページには、クラスに追加できるオーバーロードされたメソッド __isset が記述されており、誰かがそのクラスのプロパティで isset を呼び出すたびに実行されます。ただし、オーバーロードされたプロパティで empty() を呼び出すと、常に true が返され、E_NOTICE がスローされる可能性があります。理由は次のとおりです。

免責事項: オーバーロードされたプロパティで empty() を呼び出すと、渡された変数名に対して true を返す __isset() メソッドがある場合のみ、__get() が実行されるように見えます:

empty() はオーバーロードされた __get() メソッドを呼び出しません。クラス定義を調べて、そのパラメーターが存在するかどうかを確認します。存在する場合は、空かどうかを評価します。ただし、未定義のクラス パラメーターにアクセスすると、エラーがスローされます。最初の例では、$Instance->bar が存在しないため、要求するとエラーがスローされます。これは、次のように要求した場合と同じエラーです。

empty( $Instance->foo );

2番目の例では。これが役立つことを願っています。

これを関数に適用する方法、または変数を設定する方法の詳細については、言及したページを参照してください。

于 2012-06-16T13:09:28.937 に答える