2013-04-16 58 views
5

方法調用我有一個框架(Opencart的)控制器類(如:目錄/控制器/產品/ product.php)的代碼如下所示:混淆類,並在Opencart的

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(); 

,而不是 $這個 - >響應 - > 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 
} 

我不知道這個表達式是如何工作的?任何想法如何這是可能的?

謝謝。

+0

我有類似的麻煩,除了沒有__get方法聲明,它也可以使用,請參閱:http://stackoverflow.com/questions/23183327/dynamically-adding-new-properties-in- PHP – user3505400

回答

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而不需要進一步的工作(在我描述的情況下,如果您要將其他財產添加到$register您將不得不添加另一個getProperty()方法 - 但這仍然是更清晰/清晰的解決方案)。

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。這足夠清楚地解釋了。