PHP方法内修改对象数组后外部作用域数组未更新问题
PHP数组修改未生效问题解答
问题根源
你遇到的问题和作用域无关,核心原因是PHP中数组为值类型,Foo::getElements()返回的是类私有属性$elements的副本,你在removeElement()方法中修改的只是本地存储的副本数据,完全没有修改Foo类内部存储的原始数组,所以外部访问时数组不会有任何变化。
解决方案
方案1:为Foo类新增内部操作方法(最推荐,符合面向对象封装原则)
不需要暴露类的内部属性,直接在Foo类中扩展专门的元素删除方法,直接操作内部存储的数组:
class Foo { private array $elements = []; // 原有构造方法、getElements方法保持不变 public function __construct(int $howMany) { for ($i = 0; $i < $howMany; $i++) { $this->elements[] = random_int(1, 100); } } public function getElements(): array { return $this->elements; } // 新增删除指定下标的元素方法 public function removeElementByIndex(int $index): void { // 先校验下标合法性,避免报错 if (array_key_exists($index, $this->elements)) { array_splice($this->elements, $index, 1); } } }
对应修改Demo::removeElement()方法的逻辑:
private function removeElement(): void { // 直接调用Foo类提供的删除方法 $this->foo->removeElementByIndex(2); echo "\nWe have ", count($this->foo->getElements()), " soldiers in \$foo->elements\n"; }
方案2:通过返回引用实现修改(不推荐,破坏封装)
如果不想改动Foo类的基础逻辑,也可以让getElements()返回内部数组的引用,修改后直接同步到原属性:
首先修改Foo类的getElements()方法声明,添加引用标记&:
public function &getElements(): array { return $this->elements; }
接收返回值时也需要添加引用标记:
private function removeElement(): void { // 接收引用,修改会同步到Foo内部的原始数组 $elements = &$this->foo->getElements(); array_splice($elements, 2, 1); echo "\nWe have ", count($elements), " soldiers in local \$elements\n"; }
该方案的缺点是直接暴露了类的私有属性引用,外部可以任意修改内部数据,不符合封装设计原则,仅建议临时调试使用。
方案3:新增set方法回写修改后的数组
你也可以给Foo类新增数组赋值方法,修改完副本后回写到类属性中:
在Foo类中新增setElements方法:
public function setElements(array $elements): void { $this->elements = $elements; }
修改removeElement逻辑:
private function removeElement(): void { $elements = $this->foo->getElements(); array_splice($elements, 2, 1); // 将修改后的数组回写到Foo属性中 $this->foo->setElements($elements); echo "\nWe have ", count($elements), " soldiers in local \$elements\n"; }
内容的提问来源于stack exchange,提问作者Bengall
相关产品推荐
相关产品推荐

