我看过一些问题与标题非常相似,但它们与我的具体问题无关。
基本上,我想从扩展核心的类中访问核心类中的变量,但与其他示例相比,事情似乎相当复杂。我正在使用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,则打印正常。
如何访问此变量?
答案 0 :(得分:6)
你做错了 tm
您应该使用自动加载器,而不是手动包含每个类的文件。您应该了解spl_autoload_register()
和namespaces,以及如何利用这两者。
不要在__construct()
方法中生成输出。这是一个非常糟糕的做法
变量仍然存在。那不是问题。在PHP中,当您扩展类时,不会继承构造函数。
您不了解继承的工作原理。在扩展类的实例上调用方法时,在调用扩展类的方法之前,它不会执行父类的方法。它们被覆盖,而不是堆叠。
不应公开对象变量。你打破了封装。而是将它们定义为public
,您应该使用protected
。
你应该扩展他们不同类型的类一般的东西。 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);
}
}