PHP如何遍历并修改对象的所有字符串属性?
为testClass对象的字符串属性追加"abc"的实现方法
先补充完整原测试代码(添加getter方法方便验证结果):
class testClass { protected $name; protected $jobTitle; protected $age; public $otherStr; public function setName($name) { $this->name = $name; } public function setJobTitle($title) { $this->jobTitle = $title; } public function setAge($age) { $this->age = $age; } public function setOtherStr($str) { $this->otherStr = $str; } // 补充getter方法用于获取属性值 public function getName() { return $this->name; } public function getJobTitle() { return $this->jobTitle; } public function getAge() { return $this->age; } public function getOtherStr() { return $this->otherStr; } } $test = new testClass(); // 先给属性赋初始值,方便后续测试效果 $test->setName("Alice"); $test->setJobTitle("Developer"); $test->setAge(30); $test->setOtherStr("Hello");
方法一:通过反射直接遍历修改属性
由于类中存在protected属性,普通foreach无法直接访问,可借助PHP的ReflectionClass来获取所有属性(包括受保护的),判断属性值为字符串后直接追加内容:
$reflection = new ReflectionClass($test); $properties = $reflection->getProperties(); foreach ($properties as $property) { // 开启对protected/private属性的访问权限 $property->setAccessible(true); $currentValue = $property->getValue($test); // 仅对字符串类型属性追加"abc" if (is_string($currentValue)) { $property->setValue($test, $currentValue . "abc"); } } // 验证修改结果 echo $test->getName(); // 输出 Aliceabc echo $test->getJobTitle(); // 输出 Developerabc echo $test->getAge(); // 输出 30(数值类型不修改) echo $test->getOtherStr(); // 输出 Helloabc
方法二:遍历setter方法间接修改属性
遵循面向对象封装原则,通过类提供的setter方法修改属性,需要对应存在getter方法来获取当前属性值:
$reflection = new ReflectionClass($test); $methods = $reflection->getMethods(); foreach ($methods as $method) { $methodName = $method->getName(); // 筛选出符合规范的setter方法:以set开头、仅接受1个参数 if (str_starts_with($methodName, 'set') && $method->getNumberOfParameters() === 1) { // 拼接对应的getter方法名 $getterName = 'get' . substr($methodName, 3); // 确认类中存在对应getter方法 if ($reflection->hasMethod($getterName)) { $currentValue = $test->$getterName(); if (is_string($currentValue)) { // 调用setter方法追加内容 $test->$methodName($currentValue . "abc"); } } } } // 验证修改结果 echo $test->getName(); // 输出 Aliceabc echo $test->getJobTitle(); // 输出 Developerabc echo $test->getAge(); // 输出 30 echo $test->getOtherStr(); // 输出 Helloabc
两种方法的区别:
- 方法一更直接,无需依赖getter方法,但直接操作属性本身,会打破类的封装性。
- 方法二更符合面向对象设计原则,通过类对外暴露的方法修改属性,安全性更高,但需要类提供对应的getter方法。
内容的提问来源于stack exchange,提问作者program359315
相关产品推荐
相关产品推荐

