PHP实例化类时,如何访问创建者类的公共属性?
嘿,这个问题挺有意思的——你想让Brochure类自动感知创建它的Car子类的$terrain属性,不用显式传参对吧?直接说结论:默认情况下做不到,因为Brochure实例和它的创建者Car实例是完全独立的两个对象,彼此没有天然的引用关系。不过我们可以通过一些技巧来实现类似的效果,下面给你几种可行的方案:
方案1:依赖注入(最推荐)
给Brochure添加一个属性存储创建它的Car实例,在Car的getBrochure方法里把当前对象传进去。这种方式符合面向对象的设计原则,清晰且低耦合:
class Car { public $brochure; public function getBrochure() { // 将当前Car实例传入Brochure的构造方法 $this->brochure = new Brochure($this); } } class Jeep extends Car { public $terrain = 'dirt'; } class SportsCar extends Car { public $terrain = 'racing tracks'; } class Brochure { public $advertisement_text; private $creator; // 保存创建当前Brochure的Car实例 public function __construct(Car $creator) { $this->creator = $creator; $str = ""; // 现在可以直接访问创建者的terrain属性了 if (isset($this->creator->terrain)) { $str .= "This car is best driven on {$this->creator->terrain}!\r\n"; } $this->advertisement_text = $str; } }
方案2:静态上下文存储(不推荐,耦合性高)
通过静态变量临时存储当前Car实例,让Brochure在构造时读取这个静态值。这种方式不用显式传参,但存在全局状态污染的风险,并发场景下容易出问题:
class Car { public $brochure; public function getBrochure() { // 先把当前Car实例存入静态上下文 Brochure::setCurrentCar($this); $this->brochure = new Brochure(); } } class Brochure { public $advertisement_text; private static $currentCar; // 静态变量存储当前创建者 // 静态方法设置当前Car实例 public static function setCurrentCar(Car $car) { self::$currentCar = $car; } public function __construct() { $str = ""; if (isset(self::$currentCar->terrain)) { $str .= "This car is best driven on ".self::$currentCar->terrain."!\r\n"; } $this->advertisement_text = $str; // 用完清空静态变量,避免后续实例被污染 self::$currentCar = null; } }
方案3:让Car子类负责生成宣传文本
把生成advertisement_text的逻辑放到具体的Car子类里,Brochure只负责存储内容。这种方式把职责拆分得更明确,但如果宣传文本逻辑复杂,会让Car子类的代码变臃肿:
class Car { public $brochure; public function getBrochure() { $this->brochure = new Brochure(); } } class Jeep extends Car { public $terrain = 'dirt'; public function getBrochure() { $this->brochure = new Brochure(); $this->brochure->advertisement_text = "This car is best driven on {$this->terrain}!\r\n"; } } class SportsCar extends Car { public $terrain = 'racing tracks'; public function getBrochure() { $this->brochure = new Brochure(); $this->brochure->advertisement_text = "This car is best driven on {$this->terrain}!\r\n"; } } class Brochure { public $advertisement_text; }
总结
如果要兼顾代码的可读性和低耦合,方案1的依赖注入是最优选择——它本质上还是传递了参数,但这个传递过程被封装在Car的方法里,对你来说相当于“不用手动传参”就能实现需求。后面两种方案虽然能达到“无参访问”的效果,但都有明显的局限性,除非特殊场景,不建议使用。
内容的提问来源于stack exchange,提问作者Dwarf Vader
相关产品推荐
相关产品推荐

