5

フレームワーク(OpenCart)コントローラークラス(カタログ/コントローラー/製品/製品.phpなど)があり、コードは次のようになります。

class ControllerProductProduct extends Controller {
    public function index() {
      //some code
      $this->response->setOutput($this->render());
      //some more code
    }
}

のような表現があり$this->response->setOutput($this->render());ます。この表現が何に使われるかは知っていますが、どのように機能するかについてはかなり混乱しています。

$this現在のクラスを参照します。つまりControllerProductProduct$this->responseオブジェクトがいずれかControllerProductProductまたはその親クラスに存在する必要があることを意味しますController。しかし、そうではありません。このオブジェクトは、実際には親クラスの保護されたプロパティにControllerとして存在しController::registry->data['response']->setOutput()ます。したがって、次のように言うべきではありません。

$this->registry->data['response']->setOutput();

$this->response->setOutput(); の代わりに

Controllerクラスのスニペットも提供しているので、アイデアを得ることができます。

abstract class Controller {
    protected $registry;    
    //Other Properties
    public function __construct($registry) {
        $this->registry = $registry;
    }
    public function __get($key) {
        //get() returns registry->data[$key];
        return $this->registry->get($key);
    }
    public function __set($key, $value) {
        $this->registry->set($key, $value);
    }
    //Other methods
}

この表現がどのように機能しているのかわかりませんか?これがどのように可能か考えていますか?

ありがとう。

4

2 に答える 2

1

これは、魔法のメソッド __get()とを使用して非常に簡単に機能し__set()ます。

アクセスできないクラス変数 (宣言されていないなど) を取得しようとすると、魔法の__get('property_name')メソッドが呼び出されます。

したがって、取得しようとする$responseと、魔法のメソッド__get()が呼び出され、$this->registry->get('response')代わりに返されます ($responseプロパティが宣言されていないため)。

はい、$this->registry->get('response')->setOutput($this->render());代わりに書くこともできますが、これはあまり役に立たず、より多くの書き込みになります。PHP に__get()メソッドを使用して変数を取得させることは問題ありませんが、それほどクリーンではありません。

とにかく、解決策に問題はありません。

編集:少しクリーンなソリューションは次のようになります:

class Controller {
    //...
    function getResponse() {
        return $this->registry->get('response');
    }
    //...
}

次に、コードで具象メソッドを呼び出すことができ、それは十分に明確です。

class ControllerProductProduct extends Controller {
    public function index()
        //...
        $this->getResponse()->setOutput($this->render());
    }
}

getXYZただし、これは、可能なプロパティごとにメソッドが必要になることを意味しますが、それ以上の作業を必要とせず__get()に を拡張できます(別のプロパティを追加する場合は、別のメソッドを追加する必要がありますが、それでもこれはより明確でクリーンなソリューションになります)。$registry$registergetProperty()

于 2013-04-16T08:26:16.390 に答える
0

この「オーバーロード」という魔法。
ここに小さなデモがあります:

<?php

class PropsDemo 
{
    private $registry = array();

    public function __set($key, $value) {
        $this->registry[$key] = $value;
    }

    public function __get($key) {
        return $this->registry[$key];
    }
}

$pd = new PropsDemo;
$pd->a = 1;
echo $pd->a;

http://php.net/manual/en/language.oop5.overloading.phpを見てください。それは十分に明確に説明されています。

于 2013-04-16T08:17:13.110 に答える