PHP从父类CLOSED访问变量

时间:2012-06-20 11:22:23

标签: php oop class

我看过一些问题与标题非常相似,但它们与我的具体问题无关。

基本上,我想从扩展核心的类中访问核心类中的变量,但与其他示例相比,事情似乎相当复杂。我正在使用MVC框架。我已经简化了下面的代码,删除了任何不相关的内容。

的index.php

// Load the core
include_once('core.php');
$core = new Core($uri, $curpath);
$core->loadController('property');

core.php中

class Core
{
    public $uri;
    public $curpath;

    function __construct($uri, $curpath)
    {       
        $this->uri = $uri;
        $this->curpath = $curpath;
    }


    // Load the controller based on the URL
    function loadController($name)
    {       
        //Instantiate the controller
        require_once('controller/'.$name.'.php');
        $controller = new $name();
    }


}

property.php

class Property extends Core
{
    function __construct()
    {
        print $this->curpath;
    }   
}

打印$ this-> curpath只返回任何内容。变量已设置但为空。 如果我在core.php中打印$ this-> curpath,则打印正常。

如何访问此变量?

3 个答案:

答案 0 :(得分:6)

你做错了 tm

  1. 您应该使用自动加载器,而不是手动包含每个类的文件。您应该了解spl_autoload_register()namespaces,以及如何利用这两者。

  2. 不要在__construct()方法中生成输出。这是一个非常糟糕的做法

  3. 变量仍然存在。那不是问题。在PHP中,当您扩展时,不会继承构造函数

  4. 您不了解继承的工作原理。在扩展类的实例上调用方法时,在调用扩展类的方法之前,它不会执行父类的方法。它们被覆盖,而不是堆叠。

  5. 不应公开对象变量。你打破了封装。而是将它们定义为public,您应该使用protected

  6. 你应该扩展他们不同类型的类一般的东西。 PHP中的extends表示是-a 。这意味着,当你写class Oak extends Tree时,你的意思是所有的橡树都是树。同样的规则意味着,在您的理解中,所有Property个实例只是Core实例的特例。他们显然不是。

    在OOP中,我们有原则。其中一个是Liskov substitution principle(较短explanation)。这是你的课程违反的事情。

答案 1 :(得分:0)

我认为问题在于:

如果你考虑像这样的简单继承:

class Dog{
    public $color;

    public function __construct($color){
        $this->color = $color;
    }
}

class TrainedDog extends Dog{
    public $tricks;

    public function __construct($color, $tricks){
        $this->tricks = $tricks;

        parent::__construct($color);
    }
}

//Create Dog:
$alfred = new Dog('brown');

//Create TrainedDog
$lassie = new TrainedDog('golden',array('fetch'));

在这个例子中,$ alfred是一只棕色的狗,$ lassie是一只金狗。这两个实例是彼此分开的,它们唯一的共同点是它们都有一个名为$ color的属性。

如果你想要一个可用于所有Dogs的变量,你需要一个类变量:

class Dog{
    public $color;

    public static $numberOfLegs; //Class variable available in every instance of Dog.

    public function __construct($color, $numberOfLegs){
        $this->color = $color;
        self::$numberOfLegs = $numberOfLegs;
    }
}

class TrainedDog extends Dog{
    public $tricks;

    public function __construct($color, $tricks){
        $this->tricks = $tricks;

        parent::__construct($color);

        echo parent::$numberOfLegs;
    }
}

在许多情况下这没有多大意义,因为如果你有两个父类的实例(在你的案例中是Core),它们也会共享类变量。

除非您可以确保Core仅实例化一次,否则此方法将无效。如果它只存在一次,你也可以使用常量变量来存储2个属性。

如果Core存在多个实例/对象,我建议使用合成(如Alvin Wong所建议的那样)。

class Core{
      //Just as you programmed it.
}

class Property{
      private $core;

      public function __construct($core){
          $this->core = $core;

          echo $core->curPath;
      }
}

答案 2 :(得分:-1)

试试这个

include_once('core.php');
$core = new Core('test', 'path');
$core->loadController('property');

class Property extends Core
{
 function __construct($date)
{
    print $date->curpath;
}   
}



class Core
{
public $uri;
public $curpath;

function __construct($uri, $curpath)
{       
    $this->uri = $uri;
    $this->curpath = $curpath;
}


// Load the controller based on the URL
function loadController($name)
{       
    //Instantiate the controller
    require_once($name.'.php');
    $controller = new $name($this);
}


}