PHP程序的一次重构记录
项目和新需求:
我们有一个PHP写的webmail系统,有一个mail_list.php用于展现用户的邮件列表这个页面支持folderId参数(因为邮件是存在不同的文件夹下的)由于邮件太多所以支持翻页。现在需要在系统里增加标签。细化下来:需要在原有的邮件列表里增加标签列,和支持tagid检索出一个邮件列表(列表里也增加标签列)
代码和新需求
mail_list.php调用GetMailList函数,这个函数传入文件夹ID,页码,页大小,得到HTML TABLE和导航链接
GetMailList用T_Page类得到请求的一页数据再处理为HTML表格
虽然T_Page只支持单表查询,但是在整个系统里还是被广泛使用
因为动T_Page还是有风险的,所以最好继承它,然后让需要多表查询的地方直接实例化子类
重构前
/* 功能:查询指定文件夹下的特定页的邮件列表(HTML Table) */ function GetMailList($folderId, $pageNo, $pageSize) { global $db_obj, $pageLink, $html; // db_obj是从外部导入使用,后两个似乎要导出去 $query = " where folderId = $folderId ..."; //省略很多行 $pageclass = new T_Page; $tableName = "mail"; $condition = $query . "order by tm desc"; $pageclass->BaseSet($tableName, "id,sender,subject,content,...", $pageNo, $pageSize, $db_obj); $pageclass->SetCondition($condition); $record = $pageclass->ReadList(); // 查出来的记录集,被放到二维数组里 $pageLink=$pageclass->Page(); //存放翻页按钮的数组 $html = "<table>"; for($ipage=0;$ipage<$pageSize;$ipage++) { $i=$ipage; $id = $record[$i]["id"]; $sender = $record[$i]["sender"]; $subject = $record[$i]["subject"]; $content = $record[$i]["content"]; $html = $html . "<tr><td><input type=\"checkbox\" value=\"$id\"></td>"; $html = $html . "<td>$subject</td>"; ... } $html = $html . "</table>"; } /* 功能: 查询"一页"记录,且输出导航链接用于翻页 */ class T_Page { var $TableName; ... function BaseSet($TableName, $Fields, $PageNo, $PageSize, $Obj_DB) { $this->TableName = $TableName; ... $this->MaxLine = $this->PageSize; $this->Offset = $this->PageNo * $this->PageSize; } function SetCondition($Condition) { $this->Condition = $Condition; } function ReadList() { $SQL = "select count(*) as recordtotal from $this->tableName $this->Condition"; $result = $this->Obj_DB->simpleQuery($SQL); $row = $this->Obj_DB->fetchRow($result, DB_FETCHMODE_ASSOC); $this->Total = $row["recordtotal"]; if($this->Total > 0) { $SQL = "select $this->Fields fom $this->tableName $this->Condition limit $this->Offset, $this->MaxLine;"; $result = $this->Obj_DB->simpleQuery($SQL); $this->Number = $this->Obj_DB->numRows($result); while($row = $this->Obj_DB->fetchRow($result,DB_FETCHMODE_ASSOC)) { $this->Result[]=$row; } $this->Obj_DB->freeResult($result); } return($this->Result) } function Page() { if($this->PageNo > 0) $this->PageLink[0] = "<a ...>上一页</a>"; else $this->PageLink[0] = "<a>上一页</a>"; ... return $this->PageLink; } // more function }
重构后
class MailPage extends T_Page { function setTotal() { ... $this->Total = $row["recordtotal"]; } function getMailList() { $Fields = $this->Field . " ,'' as taglist "; $SQL.="select $Fields from $this->Table $this->Condition"; $SQL.=" LIMIT $this->Offset , $this->MaxLine"; ... } function addTagList() {
... $tagList = Array(); for($i=0; $i < $this->Number; $i++) { $key = $this->Result[$i]["id"]; $this->Result[$i]["taglist"] = $tagList[$key]; } } //覆盖父类的接口 function ReadList() { $this->setTotal(); $this->getMailList(); $this->addTagList(); return $this->Result; } } class TagPage extends MailPage { function SetCondition($taglist) { ... $this->Condition = sprintf(" where id in (%s) order by tm desc ", $mailList); } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· [AI/GPT/综述] AI Agent的设计模式综述
2013-12-25 测试和恢复性的争论:面向对象vs.函数式编程