如何优化PHP中MySQL CRUD代码以避免冗余?
优化PHP中MySQL CRUD的冗余代码
你的思路已经抓对了方向——把重复的prepare()和execute()抽成通用函数是消除冗余的第一步,但确实还有更优雅、更实用的优化方案,下面给你拆解几个不同层级的思路:
1. 先给通用执行函数补全实用功能
你当前的execute_crud太基础了,既没有返回结果也没处理异常,实际开发中很容易踩坑。可以扩展它,让它根据SQL类型自动返回对应的数据,同时加上错误处理:
function execute_crud(string $sql, array $params = []): mixed { global $conn; try { $stmt = $conn->prepare($sql); $stmt->execute($params); // 根据SQL开头判断操作类型,返回对应结果 $sqlType = strtoupper(substr(trim($sql), 0, 6)); switch ($sqlType) { case 'SELECT': return $stmt->fetchAll(PDO::FETCH_ASSOC); // 按需换成fetch()取单条 case 'INSERT': return $conn->lastInsertId(); // 返回新增数据的ID case 'UPDATE': case 'DELETE': return $stmt->rowCount(); // 返回受影响行数 default: return true; } } catch (PDOException $e) { // 这里可以根据需求记录日志或者抛出异常 error_log("CRUD执行错误: " . $e->getMessage()); throw $e; // 也可以返回false,根据项目错误处理逻辑调整 } }
调用的时候就不用再手动处理结果集了,直接拿到需要的数据:
// 查询多条数据 $list = execute_crud("SELECT col1, col2 FROM `table1` WHERE `col1` = :id", ['id' => 'xyz']); // 新增数据并获取ID $newId = execute_crud("INSERT INTO `table1` (col1, col2, col3) VALUES (:v1, :v2, :v3)", ['v1' => 'x', 'v2' => 'y', 'v3' => 'z']); // 更新数据并获取受影响行数 $affectedRows = execute_crud("UPDATE `table1` SET col2 = :val WHERE col1 = :id", ['val' => 'newVal', 'id' => 'xyz']);
2. 封装成数据库操作类(更推荐的工程化方案)
用全局变量$conn其实不是最佳实践,封装成类可以更好地管理数据库连接(比如用单例避免重复创建连接),同时把CRUD操作都收拢起来,代码更清晰也更易维护:
class DB { private static ?PDO $conn = null; // 单例模式初始化数据库连接 private static function getConnection(): PDO { if (self::$conn === null) { $dsn = 'mysql:host=localhost;dbname=your_db;charset=utf8mb4'; $username = 'your_user'; $password = 'your_pass'; self::$conn = new PDO($dsn, $username, $password); self::$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); } return self::$conn; } // 通用执行方法 public static function execute(string $sql, array $params = []): mixed { $conn = self::getConnection(); $stmt = $conn->prepare($sql); $stmt->execute($params); $sqlType = strtoupper(substr(trim($sql), 0, 6)); switch ($sqlType) { case 'SELECT': return $stmt->fetchAll(PDO::FETCH_ASSOC); case 'INSERT': return $conn->lastInsertId(); case 'UPDATE': case 'DELETE': return $stmt->rowCount(); default: return true; } } // 还可以封装更具体的业务方法,进一步简化调用 public static function getById(string $table, string $idCol, mixed $id): ?array { $sql = "SELECT * FROM `$table` WHERE `$idCol` = :id"; $result = self::execute($sql, ['id' => $id]); return $result ? $result[0] : null; } public static function insert(string $table, array $data): string { $columns = implode('`, `', array_keys($data)); $placeholders = ':' . implode(', :', array_keys($data)); $sql = "INSERT INTO `$table` (`$columns`) VALUES ($placeholders)"; return self::execute($sql, $data); } }
调用的时候就非常简洁直观:
// 根据ID查询单条数据 $item = DB::getById('table1', 'col1', 'xyz'); // 一键插入数据 $newId = DB::insert('table1', ['col1' => 'x', 'col2' => 'y', 'col3' => 'z']); // 执行自定义SQL $deletedCount = DB::execute("DELETE FROM `table1` WHERE col1 = :id", ['id' => 'xyz']);
3. 进阶方案:使用ORM框架
如果你的项目规模较大,或者想彻底摆脱手写SQL的冗余,可以考虑使用ORM(对象关系映射)框架,比如Eloquent(Laravel的ORM,也可以单独使用)、Doctrine等。ORM可以直接通过操作对象来完成CRUD,完全不用写重复的执行代码:
比如用Eloquent的话,先定义模型:
use Illuminate\Database\Eloquent\Model; class Table1 extends Model { protected $table = 'table1'; protected $fillable = ['col1', 'col2', 'col3']; // 允许批量赋值的字段 }
然后CRUD操作就变成了非常简洁的对象操作:
// 查询单条数据 $item = Table1::where('col1', 'xyz')->first(); // 新增数据 $newItem = Table1::create(['col1' => 'x', 'col2' => 'y', 'col3' => 'z']); $newId = $newItem->id; // 更新数据 Table1::where('col1', 'xyz')->update(['col2' => 'newVal']); // 删除数据 Table1::where('col1', 'xyz')->delete();
这种方式几乎没有冗余代码,而且可读性极强,适合中大型长期维护的项目。
内容的提问来源于stack exchange,提问作者user5005768-hd
相关产品推荐
相关产品推荐

