PHP从父类CLOSED访问变量

I've seen a few questions with really similar titles but they where irrelevant to my specific problem.

Basically, I want to access the variables from my core class in a class which extends core, but things seem to be quite complicated compared to other examples. I am using a MVC framework. I've simplified the code below to remove anything that was irrelevant.

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;
    }   
}

Printing $this->curpath just returns nothing. The variable has been set but it is empty. If I print $this->curpath inside core.php it prints fine.

How can I access this variable?

Try this

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


}

The problem, I think, lies here:

If you consider a simple inheritance like this one:

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

In this example $alfred is a brown dog and $lassie is a golden dog. The two instances are separate from each other, the only thing they have in common is that they both have a property called $color.

If you want a variable that is available in all Dogs for example, you need a class variable:

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;
    }
}

This does not make much sense in many cases though, because if you have two instances of the parent class (in you're case Core), they also share the class variable.

Unless you can ensure that Core is instanciated only once, this approach will not work. If it does only exist once, you can just as well use constant variables to store the 2 properties.

If there exist multiple instances/objects of Core, I'd recommend using a composition (as suggested by Alvin Wong).

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

class Property{
      private $core;

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

          echo $core->curPath;
      }
}

You are doing it wrong tm

  1. You should be utilizing an autoloader, instead of including files with each class manually. You should learn about spl_autoload_register() and and namespaces, and how to utilize both of them.

  2. Do not generate output in the __construct() methods. That's an extremely bad practice

  3. The variables are still there. That is not the problem. In PHP, when you extend a class, it does not inherit the constructor.

  4. You do not understand how inheritance works. When you call method on instance of extended class it will not execute parent class's method , before calling extended class's methods. They get overwritten , not stacked.

  5. Object variables should not be exposed. You are breaking the encapsulation. Instead og defining them as public you should use protected.

  6. You should extend classes of they are different type same general thing. The extends in PHP means is-a. Which means that, when you write class Oak extends Tree, you mean that all the oaks are trees. The same rule would mean, that in your understanding all Property instances are just a special case of Core instances. Which they clearly ain't.

    In OOP, we have principle. One of which is Liskov substitution principle (shorter explanation). And this is the thing your classes are violating.