1

ここに投稿している質問の正確な複製が見つからなかったので、ここにあります:

class CBaseEntity
{
    public function __construct()
    {

    }

    public function __get($property)
    {
        $property = "m_".$property;
        echo $property;
        if(property_exists($this, $property))
        {           
            $result = $this->$property;
            return $result;
        }
        else 
        {
            throw new Exception("Property not found $property");
        }
    }
}

class CCategoryEntity extends CBaseEntity
{
    private $m_id;
    private $m_name;
    private $m_description;

    public function __construct()
    {

    }

    public static function CreateFromParams($id,$name, $description)
    {
        $instance = new CCategoryEntity();
        $instance->m_id=$id;
        $instance->m_name=$name;
        $instance->m_description=$description;
        return $instance;
    }

    public static function CreateFromArray(array $catData)
    {
        $instance = new CCategoryEntity();
        $instance->m_id = $catData["id"];
        $instance->m_name = $catData["name"];
        $instance->m_description = $catData["description"];
        return $instance;
    }
}

    $categoryEntity = CCategoryEntity::CreateFromParams(3, "EntityA", "Entity");
    echo $categoryEntity->name;

Fatal error: Uncaught exception 'Exception' with message 'Property not found m_m_name'
 Exception: Property not found m_m_name in ***\models\BaseModel.php on line 33

nameプロパティはマジック メソッドによって解決されているように見えますが、この getter の本体での戻り値は、文字列が検索された属性の名前と一致するためget、どういうわけかインテリジェントに停止するのではなく、再び自身への呼び出しを発行します。$property文字列を比較して、プロパティが で始まるかどうかを確認することもできますがm_、この場合、2 番目の呼び出しが既に発行されることは望ましくありません。

不要な再帰を生成しない同様のコードを含む他の SO の質問があります。PHPで何か変更がありましたか、それともこれがデフォルトの動作ですか? このデザインが意図する目標をエレガントな方法で達成するにはどうすればよいでしょうか?

4

2 に答える 2

2

現在のスコープからアクセスできるかどうかではなく、プロパティが存在するかどうかのみをチェックしているため、再帰が表示されます。プライベートとして宣言されているため、親クラスまたは子クラスからはアクセスできません。宣言されたクラスでのみアクセスできます。そのため、__get2回目と呼ばれます(最初は存在しないプロパティ用でしたが、現在はアクセスできないプロパティ用です)。get_object_varsを試して、アクセス可能なプロパティを取得してください。

保護するか、プライベートプロパティのパブリックゲッターメソッドを定義することをお勧めします。

于 2012-12-29T12:42:13.180 に答える
2

どういう意味かわかりませんが、2 回目の電話はありません。クラス外のプロパティにアクセスすると、__get()一度だけ呼び出されます。$this->$propertyメソッド内で__get()別の呼び出しをトリガーしません。

PHPドキュメントから:

オーバーロード メソッドは、宣言されていない、または現在のスコープに表示されていないプロパティまたはメソッドと対話するときに呼び出されます。

これは、__get()その呼び出しに使用できるプロパティがない場合にのみメソッドが呼び出されることを意味します。

于 2012-12-29T12:06:15.330 に答える