You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:24:20