Php 使用$this访问子对象中的父属性

Php 使用$this访问子对象中的父属性,php,oop,Php,Oop,我正在尝试创建一个简单的MVC,我个人使用,我真的可以用这个简单问题的答案 class theParent extends grandParent{ protected $hello = "Hello World"; public function __construct() { parent::__construct(); } public function route_to($where) { call_user_func

我正在尝试创建一个简单的MVC,我个人使用,我真的可以用这个简单问题的答案

class theParent extends grandParent{

    protected $hello = "Hello World";

    public function __construct() {
        parent::__construct();
    }

    public function route_to($where) {
        call_user_func(array("Child", $where), $this);
    }
}

class Child extends theParent {

    public function  __construct() {
        parent::__construct();
    }

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

}

$x = new theParent();
$x->route_to('index');
现在
Child::index()
这抛出了一个致命错误:
在不在对象上下文中时使用$this
,但是如果我使用echo
$var->hello
,它工作得很好


我知道我可以使用
$var
来访问父对象中的所有属性,但我更愿意通过编写
调用用户函数(数组(“Child”,$where),$this)
来使用
$this

。但由于您的方法不是静态的,因此需要某种对象实例:

call_user_func(array(new Child, $where), $this);

.

在执行
$x->route_to('index')时,您没有可调用非静态方法的
Child
实例在没有先创建实例的情况下调用方法的方式是静态的

有两种方法可以纠正它。或者将
子类的方法设置为静态:

class Child extends theParent {

    public function  __construct() {
        parent::__construct();
    }

    static public function index($var) {
        echo self::$hello;
    }

}
…或创建子类的实例供父类使用:

   class theParent extends grandParent{

        protected $hello = "Hello World";
        private $child = false

        public function __construct() {
            parent::__construct();
        }

        public function route_to($where) {
            if ($this->child == false)
              $this->child = new Child();
            call_user_func(array($this->child, $where), $this);
        }
    }

当然,这两个示例都是非常通用且无用的,但是您可以看到这个概念。

$this
允许您访问当前对象中可见/可访问的所有内容。可以在类本身(this)中,也可以在它的任何父级公共或受保护的成员/函数中

如果当前类重写父类的某些内容,则可以使用
parent
关键字/标签显式访问父方法,而不管它是否为静态方法,都可以向其添加
::

受保护的变量只存在一次,因此不能使用
parent
访问它们


这个信息有用吗?

抛出错误的
Child::index()
在哪里?我不能从你发布的代码中看到它。谢谢,我喜欢这个。我可以使用变量创建这个类的新实例吗?使$var=“Child”;然后调用_user_func(数组(new${$var},$where),$this);还是像这样?上次我尝试时,您无法将对象分配给string您的语法几乎正确,但您只需要使用
new$var
而不是
new${$var}
。(后者有不同的含义,它将使用变量实例化类。)