如何重构简化PHP发票商品统计函数并拆分为至少两个函数?
问题描述
需要重构一个用于统计发票内商品总数量的PHP方法,将耦合的逻辑拆分为至少两个职责独立的函数,原实现代码如下:
public function getTotalProductsNumber(): int { $dataset = 'supplier_invoice_products inner join supplier_invoices as si using (supplier_invoice_id)'; $dbmSupplier = new Dbm_Supplier($dataset); $whereAndOpt = $this->getConditionsAndOptions(); $where = $whereAndOpt['where']; $opt = $whereAndOpt['opt']; $select = 'sum(product_quantity) as sumTotal'; $invoiceTotalProductsNumber = $dbmSupplier->findFirstSimple($where, $select, $opt); $invoiceTotalProductsNumber['sumTotal'] = (int)$invoiceTotalProductsNumber['sumTotal']; return $invoiceTotalProductsNumber['sumTotal']; }
重构方案
拆分核心是将通用数据库查询逻辑和具体业务统计逻辑解耦,拆分后两个函数职责清晰,且通用逻辑可复用于其他同场景统计需求:
- 通用聚合查询函数:封装关联表初始化、查询条件解析、查询执行、空值兜底、类型转换的通用逻辑,不绑定具体统计字段,支持同表下所有返回整数的聚合查询(比如总金额统计、商品条目数统计)
- 业务统计函数:作为对外暴露的业务入口,仅负责传入商品数量求和的查询规则,调用通用查询方法获取结果后直接返回,不需要关心底层查询实现细节
重构后代码如下:
/** * 供应商发票关联表通用整数聚合查询方法 * @param string $selectSql 聚合查询select语句 * @param string $resultKey 聚合结果对应的字段别名 * @return int 统计结果,无匹配数据时默认返回0 */ protected function getSupplierInvoiceAggregate(string $selectSql, string $resultKey): int { $dataset = 'supplier_invoice_products inner join supplier_invoices as si using (supplier_invoice_id)'; $dbmSupplier = new Dbm_Supplier($dataset); $conditionPack = $this->getConditionsAndOptions(); $queryResult = $dbmSupplier->findFirstSimple( $conditionPack['where'], $selectSql, $conditionPack['opt'] ); return (int)($queryResult[$resultKey] ?? 0); } /** * 统计发票关联商品总数量 * @return int */ public function getTotalProductsNumber(): int { return $this->getSupplierInvoiceAggregate( 'sum(product_quantity) as sumTotal', 'sumTotal' ); }
重构收益
- 重复逻辑收敛:后续新增同表统计需求时,不需要重复编写数据库实例初始化、条件解析的重复代码,直接调用通用聚合方法传入对应查询规则即可
- 职责单一:两个函数各自只负责一类逻辑,排查问题、修改逻辑时不需要通读全量业务代码
- 鲁棒性提升:顺带修复了原实现无匹配查询结果时,访问不存在数组键触发报错的问题,空结果默认返回0符合统计类业务的常规预期
- 可扩展性更强:如果后续需要调整表关联关系、查询条件解析规则,只需要修改通用聚合方法一处即可生效,不需要逐个修改所有业务统计方法
内容的提问来源于stack exchange,提问作者user3848412
相关产品推荐
相关产品推荐

