PHP与MySQL中使用带属性对象替代直接列值处理数据(getter与setter)
基于getter/setter处理MySQL数据的OOP实现方案
你原有代码存在两个独立查询嵌套循环的逻辑问题,会导致产品和尺寸数据不匹配产生笛卡尔积,我们先调整查询逻辑,再对接OOP封装方案:
步骤1:创建DVD产品实体类,定义属性和getter/setter
class DvdProduct { // 封装私有属性,禁止外部直接访问 private int $id; private string $sku; private string $name; private float $price; private int $size; // 定义对应getter方法,受控获取属性值 public function getId(): int { return $this->id; } public function getSku(): string { return $this->sku; } public function getName(): string { return $this->name; } public function getPrice(): float { return $this->price; } public function getSize(): int { return $this->size; } // 定义对应setter方法,受控设置属性值,可加校验逻辑 public function setId(int $id): void { $this->id = $id; } public function setSku(string $sku): void { $this->sku = $sku; } public function setName(string $name): void { $this->name = $name; } public function setPrice(float $price): void { $this->price = $price; } public function setSize(int $size): void { $this->size = $size; } }
步骤2:修改查询逻辑,关联表获取完整数据
把两次独立查询改为关联查询,保证产品和尺寸的对应关系正确,同时将查询结果直接映射为实体类对象:
$stmt = $this->db_connect()->prepare(' SELECT pl.id, pl.sku, pl.name, pl.price, d.size FROM product_list pl LEFT JOIN dvd d ON pl.id = d.product_id WHERE pl.type = "dvd" ORDER BY pl.id '); $stmt->execute(); // 配置PDO将查询结果自动映射为DvdProduct类的实例 $stmt->setFetchMode(PDO::FETCH_CLASS, DvdProduct::class); // 循环调用getter方法输出,完全不直接操作数据库列值 while ($product = $stmt->fetch()) { echo '<div class="product">'. '<input type="checkbox" class="delete-checkbox" name="check[]" value ="'. $product->getId() .'">'; echo '<p>'.$product->getSku(). '<br>' .$product->getName(). '<br>'.$product->getPrice().'$'.' <br>'.$product->getSize().'MB'.'</p>'; echo '</div>'; }
方案优势
- 所有属性封装在类内部,外部不会直接操作数据库列名对应的数组键,后续如果字段名修改,只需要调整实体类的setter逻辑或者SQL字段别名,不需要改动输出层代码
- 修复了原代码嵌套循环导致的数据错乱问题,一次关联查询性能更高
- 后续扩展其他产品类型时,只需要新增对应的实体类继承公共的产品父类即可,符合OOP开发规范
内容的提问来源于stack exchange,提问作者User 7014
相关产品推荐
相关产品推荐

