PHP MySQLi 编程风格解析:从面向对象到过程化及最佳实践


PHP MySQLi 编程风格解析:从面向对象到过程化及最佳实践

本文深入探讨了 php mysqli 扩展的两种编程风格:面向对象(oo)和过程化。我们将对比这两种风格的语法差异,演示如何正确地在它们之间进行转换,并强调在现代 php 开发中,面向对象风格是更推荐的选择,因为它提供了更清晰、更易维护的代码结构。同时,文章也介绍了优化 mysqli 使用的技巧,并推荐了更强大的数据库抽象层 pdo。

MySQLi 编程风格概述

PHP 的 MySQLi 扩展提供了两种主要的方式来与 MySQL 数据库进行交互:面向对象(Object-Oriented, OO)风格和过程化(Procedural)风格。虽然面向对象风格的名称中包含“面向对象”,但它并不要求开发者完全掌握面向对象编程(OOP)范式,它更多地是提供了一种更现代、更直观的 API 接口。过程化风格则更接近于传统的 PHP MySQL 函数,通常需要将连接对象作为第一个参数传递给函数。

对于新的项目和代码库,强烈建议使用面向对象风格。过程化风格最初设计的主要目的是帮助开发者从旧的 mysql_* 函数迁移到 MySQLi,而不是作为新代码的首选。

理解面向对象与过程化风格的差异

两种风格的核心功能是相同的,主要区别在于函数调用的语法和参数传递方式。在面向对象风格中,方法通过对象实例调用;而在过程化风格中,函数直接调用,并将连接或语句对象作为第一个参数。

以下是两种风格中等效操作的对比:

功能 面向对象风格 过程化风格
准备语句 $stmt = $mysqli->prepare($query); $stmt = mysqli_prepare($mysqli, $query);
绑定参数 $stmt->bind_param($types, ...$params); mysqli_stmt_bind_param($stmt, $types, ...$params);
执行语句 $stmt->execute(); mysqli_stmt_execute($stmt);
获取结果集 $result = $stmt->get_result(); $result = mysqli_stmt_get_result($stmt);
获取行数 $result->num_rows; mysqli_num_rows($result);
获取关联数组 $row = $result->fetch_assoc(); $row = mysqli_fetch_assoc($result);
关闭语句 $stmt->close(); mysqli_stmt_close($stmt);

从上面的对比可以看出,过程化风格的函数名通常以 mysqli_ 开头,并且需要显式地传递 MySQLi 对象(如 $mysqli 或 $stmt)作为其第一个参数。

将面向对象代码转换为过程化风格

假设我们有一个使用面向对象风格编写的函数,用于从数据库中获取预订日期:

function build_calendar_oo($month, $year){
    $mysqli = new mysqli('localhost', 'root', '', 'ems');
    $stmt = $mysqli->prepare("SELECT * FROM bookings WHERE MONTH(event_date) = ? AND YEAR(event_date)=?");
    $stmt->bind_param('ss', $month, $year);
    $bookings = array();
    if($stmt->execute()){
        $result = $stmt->get_result();
        if($result->num_rows > 0){
            while($row = $result->fetch_assoc()){
                $bookings[] = $row['event_date'];
            }
            $stmt->close();
        }
    }
    return $bookings;
}

要将其转换为过程化风格,我们需要将所有对象方法调用替换为相应的过程化函数,并确保传递正确的对象作为第一个参数:

function build_calendar_procedural($month, $year)
{
    // 建立数据库连接
    $mysqli = mysqli_connect('localhost', 'root', '', 'ems');
    if (mysqli_connect_errno()) {
        die("数据库连接失败: " . mysqli_connect_error());
    }

    // 准备语句
    $stmt = mysqli_prepare($mysqli, "SELECT * FROM bookings WHERE MONTH(event_date) = ? AND YEAR(event_date)=?");
    if (!$stmt) {
        die("语句准备失败: " . mysqli_error($mysqli));
    }

    // 绑定参数
    mysqli_stmt_bind_param($stmt, 'ss', $month, $year);

    $bookings = array();
    // 执行语句
    if (mysqli_stmt_execute($stmt)) {
        // 获取结果集
        $result = mysqli_stmt_get_result($stmt);
        if ($result && mysqli_num_rows($result) > 0) {
            // 遍历结果
            while ($row = mysqli_fetch_assoc($result)) {
                $bookings[] = $row['event_date'];
            }
            // 释放结果集
            mysqli_free_result($result);
        }
    } else {
        die("语句执行失败: " . mysqli_stmt_error($stmt));
    }

    // 关闭语句和连接
    mysqli_stmt_close($stmt);
    mysqli_close($mysqli);

    return $bookings;
}

错误解析:

用户在尝试转换时遇到了 Fatal error: Uncaught TypeError: mysqli_fetch_assoc(): Argument #1 ($result) must be of type mysqli_result 错误。这是因为用户尝试将 mysqli_query 与占位符(?)一起使用,这是不正确的。mysqli_query 不支持预处理语句中的占位符。它用于执行简单的 SQL 查询,或者已经完全构建好的 SQL 字符串。当使用预处理语句时,必须通过 mysqli_prepare、mysqli_stmt_bind_param 和 mysqli_stmt_execute 等函数来处理。mysqli_fetch_assoc 期望的是一个 mysqli_result 对象,而直接使用 mysqli_query 配合占位符并不会返回一个有效的 mysqli_result 对象供预处理语句使用。

Beautiful.ai Beautiful.ai

AI在线创建幻灯片

Beautiful.ai 108 查看详情 Beautiful.ai

推荐的 MySQLi 实践与简化

无论选择哪种风格,都应遵循一些最佳实践来提高代码的健壮性和可维护性。

1. 错误报告

为了更好地调试和处理错误,建议在脚本开始时启用 MySQLi 的错误报告:

mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);

这会在发生 MySQLi 错误时抛出 mysqli_sql_exception 异常,而不是默默失败或只返回 false,从而更容易捕获和处理错误。

2. 简化面向对象风格的代码

使用面向对象风格时,可以通过一些方法进一步简化代码,例如使用 fetch_all 来一次性获取所有结果:

// 启用错误报告
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);

// 建立数据库连接
$mysqli = new mysqli('localhost', 'root', '', 'ems');

/**
 * 构建日历预订日期数组
 *
 * @param mysqli $mysqli 数据库连接对象
 * @param int $month 月份
 * @param int $year 年份
 * @return array 预订日期数组
 */
function build_calendar_simplified(mysqli $mysqli, int $month, int $year): array
{
    $stmt = $mysqli->prepare("SELECT event_date FROM bookings WHERE MONTH(event_date) = ? AND YEAR(event_date)=?");
    $stmt->bind_param('ii', $month, $year); // 注意:如果月份和年份是整数,应使用 'ii'
    $stmt->execute();

    // 获取所有结果并以关联数组形式返回
    $result = $stmt->get_result();
    return $result->fetch_all(MYSQLI_ASSOC);
}

// 示例调用
$bookings = build_calendar_simplified($mysqli, 1, 2025);
print_r($bookings);

// 关闭连接
$mysqli->close();

在这个简化版本中:

  • 我们将 $mysqli 连接对象作为参数传递给函数,这是一种更好的实践,避免了在函数内部重复创建连接。
  • 使用 fetch_all(MYSQLI_ASSOC) 一次性获取所有结果行,并以关联数组的形式返回,大大简化了结果集的处理。
  • 参数类型 bind_param 从 ss 改为 ii,因为月份和年份通常是整数类型。

推荐:使用 PDO 扩展

尽管 MySQLi 的面向对象风格是一个不错的选择,但更推荐的 PHP 数据库抽象层是 PDO (PHP Data Objects)。PDO 提供了一个轻量级、一致的接口来访问多种数据库,而不仅仅是 MySQL。它的主要优势包括:

  • 数据库无关性: 相同的 API 可以用于 MySQL, PostgreSQL, SQLite 等多种数据库。
  • 更好的错误处理: 通过异常机制提供更健壮的错误报告。
  • 更简洁的 API: 通常比 MySQLi 提供更直观和简洁的代码。
  • 命名参数支持: 除了位置参数,还支持命名参数,使查询更具可读性。

如果您正在开始一个新的项目,或者有机会重构现有代码,学习和使用 PDO 将是一个非常有益的投资。

总结

在 PHP 中进行数据库操作时,理解 MySQLi 的面向对象和过程化风格至关重要。尽管过程化风格可以实现相同的功能,但面向对象风格因其更清晰的语法、更好的可读性和维护性而成为现代 PHP 开发的首选。始终使用预处理语句来防止 SQL 注入,并考虑启用 MySQLi 的错误报告。对于追求更高灵活性和一致性的开发者,PDO 是一个更强大、更推荐的数据库抽象层。

以上就是PHP MySQLi 编程风格解析:从面向对象到过程化及最佳实践的详细内容,更多请关注php中文网其它相关文章!


# 并以  # 免费网站推广公司地址  # 天津网站推广﹣weisuzhou佳v新  # 优化对网站的作用  # 网站建设教程 下载  # 西安市关键词排名供应商  # 网站设计与优化服务商  # 商丘网站建设的要求  # 潜江精准推广网站在哪里  # 三明seo优化哪家好  # 邯郸seo推广推荐公司  # 转换为  # mysql  # 重构  # 是一个  # 错误报告  # 两种  # 已有  # 管理系统  # 第一个  # 面向对象  # 区别  # 面向对象编程  # php 


相关栏目: 【 Google疑问12 】 【 Facebook疑问10 】 【 优化推广96088 】 【 技术知识133117 】 【 IDC资讯59369 】 【 网络运营7196 】 【 IT资讯61894


相关推荐: 微信如何设置字体大小_微信字体设置的阅读舒适  MySQL多重关联查询:利用别名高效获取同一表的多个关联字段  在VS Code中利用AI辅助进行代码迁移  从J*a应用程序中导出MySQL表数据的技术指南  J*aScript大数运算_BigInt使用指南  猫眼电影app如何设置电影上映提醒_猫眼电影上映提醒设置教程  《领英》查看屏蔽名单方法  PointNet++语义分割模型中类别变更引发的断言错误及标签处理策略  《腾讯相册管家》注销账号方法  LINUX怎么查看显卡信息_LINUX查看GPU状态  高德地图导航路线偏差报警频繁怎么办 高德地图路线偏差修复与优化方法  鲁班大师乓乓皮肤获取方法  汽车之家网页版免费登录_汽车之家官网首页直接进入  Yandex世界探索 最新官方免登录入口全知道  抖音号显示企业机构号是什么意思?企业机构号申请条件是什么?  《海豚家》注销账号方法  火狐浏览器如何刷新修复浏览器 火狐浏览器“重置Firefox”功能详解  第五人格PC版怎么避免被封号_第五人格PC版防封号注意事项  韩小圈网页版PC端入口 韩小圈网页版官方网站入口  如何查找哪个composer包引入了特定的依赖?  解决 Vue 3 组件未定义错误:理解 createApp 与根组件的正确使用  mysql归档数据怎么导出为csv_mysql归档数据导出为csv文件的方法  mysql如何管理数据库账户_mysql数据库账户管理技巧  邦丰播放器频道搜索设置  如何在Golang中处理表单文件上传_Golang 表单文件上传示例  谷歌浏览器如何查找和删除恶意软件 谷歌浏览器内置安全清理工具使用教程  51漫画网实时入口 51漫画网页版官方免费漫画入口  12306夜间购票失败? | 查看官方公布的暂停服务公告与应对方案  Go Goroutine调度与并发执行深度解析  全球各国上班时间表外贸邮件时间  cad怎么隐藏指定的图层_cad隐藏或冻结图层方法  NumPy 高性能技巧:基于多列条件查找最近邻行索引的向量化实现  diskgenius分区工具如何设置Bios启动项  CSS绝对定位与溢出控制:实现背景元素局部显示不触发滚动条  mysql中如何配置字符集和排序规则_mysql字符集排序配置  国际经济与贸易就业方向解析  漫蛙漫画官方网站使用_漫蛙manwa网页版在线入口教程  抖音小程序怎么开通?小程序开通条件是什么?  晓晓优选app支付宝绑定方法  申通快递物流信息查询 申通快递包裹状态追踪  AO3中文版手机快速通道_AO3最新稳定链接更新  谷歌学术论文搜索引擎 谷歌学术官网入口论坛永久链接  《金山词霸》语音翻译方法  精通VS Code多光标编辑以实现闪电般快速的修改  Composer reinstall命令重装损坏的包  咸鱼怎么设置仅粉丝可见的动态_咸鱼动态粉丝可见设置方法  青橙手机语音助手怎么唤醒_青橙手机语音助手设置与唤醒方法  德邦快递会员怎么开通  批改网网页版登录 批改网电脑版学生登录入口  《友玩*》创建群聊方法 

 2025-11-08

了解您产品搜索量及市场趋势,制定营销计划

同行竞争及网站分析保障您的广告效果

点击免费数据支持

提交您的需求,1小时内享受我们的专业解答。

运城市盐湖区信雨科技有限公司


运城市盐湖区信雨科技有限公司

运城市盐湖区信雨科技有限公司是一家深耕海外推广领域十年的专业服务商,作为谷歌推广与Facebook广告全球合作伙伴,聚焦外贸企业出海痛点,以数字化营销为核心,提供一站式海外营销解决方案。公司凭借十年行业沉淀与平台官方资源加持,打破传统外贸获客壁垒,助力企业高效开拓全球市场,成为中小企业出海的可靠合作伙伴。

 8156699

 13765294890

 8156699@qq.com

Notice

We and selected third parties use cookies or similar technologies for technical purposes and, with your consent, for other purposes as specified in the cookie policy.
You can consent to the use of such technologies by closing this notice, by interacting with any link or button outside of this notice or by continuing to browse otherwise.