[英]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.