簡體   English   中英

PHP如何使用$ this-> classname引用鄰居類?

[英]PHP how to reference neighbor class with $this->classname?

顯然我想念一些東西。 我有以下代碼:

<?php

class module {
    protected $registry;
    public $controller;
    public $model;
    public $view;
    public $var = 'global';

}

class controller extends module {
    public function test_controller() {
        echo 'controller test';
        echo $this->var;
        $this->model->test_model();
        $this->view->test_view();
    }
}

class model extends module {
    public function test_model() {
        echo 'model test';
        echo $this->var;
    }
}

class view extends module {
    public function test_view() {
        echo 'view test';
        echo $this->var;
    }
}

$module = new module();
$module->controller = new controller();
$module->model = new model();
$module->view = new view();

echo "\n\n\n" . print_r($module);

$module->controller->test_controller();

最后,我得到“在null上調用成員函數test_model()”。 我確實知道,每次實例化“擴展器”類時,都會重新初始化“模塊”類的變量。 好的,沒問題,但是在此之后,我立即為“父”類屬性分配了所需的“值”(我的意思是$ module-> controller = new controller();)。

我不明白如何處理此行為。 我想在我在控制器函數中編寫的模塊內實現這種類型的引用:$ this-> model-> some_func(),$ this-> view-> some_other()。 也將有一個帶有其他類的所謂注冊表,擴展類也應該可以使用。

如果這是設計問題-好的,請指點我:)

謝謝。

這些是不同的實例。 如下:

<?php

class Foo
{
    public $bar;
    public $baz;
}

class Baz extends Foo
{
    public function showMeTheBar()
    {
        return $this->bar;
    }
}

$foo      = new Foo;
$foo->bar = 'Hat';
$foo->baz = new Baz;
var_dump($foo->baz->showMeTheBar());

輸出:

NULL

$foo的欄和$foo::baz的欄不相同。

如其他答案所述,控制器具有$this->model$this->view所有權,因此在您的實例中,您必須為控制器分配新實例:

$module = new module();
$module->controller         =   new controller();
# Need to assign to the controller now, not the $module
$module->controller->model  =   new model();
$module->controller->view   =   new view();

這可能是您不打算做的。 如果要執行操作,則必須在$module范圍內執行,然后將單個元素放回module

<?php
class module
{
    public $controller,
           $model,
           $view;

    public $var = 'global';

    protected $registry;
    # Add a new method that basically does what your controller method was doing.
    # Difference is that now these other classes are in the $module scope
    public function get()
    {
        $this->controller->test_controller();
        $this->model->test_model();
        $this->view->test_view();
    }
}

class controller extends module
{
    public function test_controller()
    {
        echo $this->var;
    }
}

class model extends module {
    public function test_model()
    {
        echo $this->var;
    }
}

class view extends module {
    public function test_view()
    {
        echo $this->var;
    }
}

$module = new module();
$module->model = new model();
$module->view = new view();
$module->controller = new controller();
$model->get();

盡管我不確定要分配多少個類,但是您可能要使用注入:

$module = new module(new model(), new view(), new controller());
$module->view->test_view();

如果您要注入並想使用動態注入,則可能需要查看Reflection,以便您的類不需要顯式的參數分配。

您可以進入動態調用的范圍,但是如果您不小心,可能會遇到一些麻煩!

<?php
class module
{
    public $var = 'global';
    protected $registry;
    # Might want to add a getter
    public function __get($prop)
    {
        if(property_exists($this, $prop)) {
            return $this->{$prop};
        }
    }
    # Create a method getter
    public function __call($class, $args = false)
    {
        $class = strtolower(str_replace('get','', $class));
        # Set the dynamic variable
        if(!isset($this->{$class}))
            $this->{$class} = (is_array($args))? new $class(...$args) : new $class($args);
        # Send back new variable
        return $this->{$class};
    }
}

class controller extends module
{
    public function test_controller()
    {
         echo $this->var;
    }
}

class model extends module
{
    public function test_model()
    {
        echo $this->var;
    }
}

class view extends module
{
    public  function __construct()
    {
        print_r(func_get_args());
    }

    public function test_view()
    {
        echo $this->var;
    }
}

# Create instance of module
$module =   new module();
# use getView() to fetch and assign view
print_r($module->getView('arg1', 'arg2')->test_view());
# Since you set this value already, it can be pulled directly or by using
# getView()
print_r($module->view);

你從中得到什么:

Array
(
    [0] => arg1
    [1] => arg2
)

global

view Object
(
    [var] => global
    [registry:protected] => 
)

動態調用具有它的位置,因此,如果您使用它,請謹慎進行。

如前所述,對於持久變量,您可以使用靜態變量,因此,如果在一個類中更改變量,則所有變量都將更改。

以樹的形式調用Controller::test_controller()之前, $module的狀態(我將以駝峰式的方式顯示類名):

$module: Module
Props:
  $controller: Controller
  Props:
    $controller: null
    $model: null
    $view: null
    $var: "global"
  $model: Model
  Props:
    $controller: null
    $model: null
    $view: null
    $var: "global"
  $view: View
  Props:
    $controller: null
    $model: null
    $view: null
    $var: "global"
  $var: "global"

你知道嗎? $module->controller$module->controller->controller 甚至$module->var$module->controller->var也不一樣。 $module$module->controller是不同的。

我不知道您是否做對了,但是解決方案是使用依賴注入。 這意味着您應該將$module (依賴項)作為參數傳遞(注入)到Controller::test_controller()或其他參數中。

感謝您的回答。 這就是這種情況:您必須要求自己找到答案:)

該應用程序的入口點是控制器和API,因此我必須在此處提供可用的東西,但不能在其他地方使用:“視圖”一定不能看到“模型”。

因此,如果有人在尋找這種設計,它可以:

$controller = new Controller($registry);
$model = new Model($registry);
$api = new Api($registry);
$view = new Template($modulename);
//these classes above are already extended by abstract classes to bring $registry classes with __get()

$settings = new Settings($modulename);
$language = new Language($code);

$module = new stdClass();

$module->controller = $controller;
$module->controller->model = $model;
$module->controller->view = $view;
$module->controller->api = $api; //this might be questionable, but sometimes it's easier to do so
$module->controller->settings = $settings;
$module->controller->language = $language;

$module->api = $api;
$module->api->model = $model;
$module->api->view = $view;
$module->api->controller = $controller; //this might also be questionable, but sometimes it's easier to do so
$module->api->settings = $settings;
$module->api->language = $language; 

$model->settings = $settings;

我的目標是進行調用(在控制器和api中),例如$this->model->method(), $this->view->method()等,這些我已經實現了。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM