• PHP MYSQLi OOP式准备好语句


    在本教程中,我们将学习如何使用 PHP 中的 MYSQLI 准备语句执行不同条件的查询,如 SELECT、UPDATE、DELETE 等。在我们开始之前,我将简要介绍您准备好的陈述。

    什么是 MYSQLI 准备好的语句?

    MYSQL是一种流行的关系数据库系统。MYSQLI是一个强大的 PHP 扩展,用于连接 MYSQL。准备好的语句作为先前准备并稍后使用数据执行的查询。

    为什么准备好的陈述很重要?

    简单地说,准备好的语句保护网站免受可用于攻击网站的SQL 注入。此外,根据某些来源,准备好的语句可能比普通查询更快(但是,根据我的经验,它们在执行简单查询时几乎相同。但是,对于重复查询,准备好的语句比普通查询快)。准备好的语句最好的地方是可读性。它们很容易被阅读、理解和管理。

    先决条件

    在开始之前,您将需要这些东西。

    • 安装了 PHP 和 MYSQL 的计算机。
    • 已连接到数据库的 PHP 脚本。我们将把数据库连接保存在$mysqli中。
      1. $mysqli = new mysqli( 'hostname', 'username', 'password', 'database' );

    • 在本教程中,我们的数据库中将有一个这样的“user”表
      idnameemail
      1Teodorteod@gmail.com
      2Christchristoperkhawand@gmail.com
      3Austinaustin@gmail.com
      4Ayushayushagarwal@gmail.com

    如何在 PHP 中使用准备好的语句

    让我们看看如何使用 MYSQLI 在 PHP 中执行准备好的语句。这是基本概念。在各种查询(SELECT、UPDATE 等)中,我们将使用不同的方式(和技巧)。

    • 首先,应该准备一个查询。
      $stmt = $mysqli -> prepare('SELECT * FROM users WHERE id = ?');

      在这里,我们将语句存储在$stmt中。这是一个mysqli_stmt对象。在接下来的步骤中,我们将调用此类的方法来执行操作。

      请注意? 查询中的(问号)用作占位符。我们对 MYSQL 说这是一个空盒子,我们将在未来填充它。

    • 接下来,我们绑定数据。这就像填满盒子。
      1. $userId = 2;
      2. $stmt -> bind_param('i', $userId);

      这里我们将绑定2作为用户的 id。在bind_param()方法中,第一个参数表示每个变量的数据类型。例如,如果您要绑定三个变量(空框),它们分别是整数、整数、字符串、整数,您可以使用'iisi'。

      无缘无故,在 PHP 中,以下内容无效。bind_param函数的参数应该是除第一个之外的变量。
      $stmt -> bind_param('i', 2);
      
    • 接下来,我们执行查询
      $stmt -> execute();
      在此步骤之后,过程会根据您将执行的查询而有所不同。让我们看一些例子。

    1. SELECT - 选择一行

    1. $stmt = $mysqli -> prepare('SELECT name, email FROM users WHERE id = ?');
    2. $userId = 1; // or $_GET['userId'];
    3. $stmt -> bind_param('i', $userId);
    4. $stmt -> execute();
    5. $stmt -> store_result();
    6. $stmt -> bind_result($name, $email);
    7. $stmt -> fetch();
    8. echo $name; // Teodor
    9. echo $email; // teod@gmail.com
    • store_result()存储结果。
    • bind_result()将值绑定到变量。
    • fetch()将结果提取到变量中。

    起初,如果您是初学者,这很棘手。但是,当您执行其他步骤时,您会明白。请记住,fetch()将当前行的结果保存在bind_result()的变量中。默认情况下,当前行是结果集中的第一行。当我们调用一次fetch()时,当前行是结果中的第二行。但是,我们在此查询中只有一行。

    2. SELECT - 选择多行

    1. $stmt = $mysqli -> prepare('SELECT name, email FROM users');
    2. $stmt -> execute();
    3. $stmt -> store_result();
    4. $stmt -> bind_result($name, $email);
    5. while ($stmt -> fetch()) {
    6. echo $name;
    7. echo $email;
    8. }

    当您没有任何要传递的变量时,不需要bind_param()函数。这将选择所有用户并回显所有用户的姓名和电子邮件。

    特别说明:

    • fetch()成功时返回 true,失败时返回 false。如果没有找到行,它将返回 false。所以,我们可以直接用它作为while循环的条件。
    • 在每次调用fetch()时,当前行的结果都保存在$name和$email变量中。并且,光标移动到下一行。(所以,当我们下次调用 fetch 时,它会获取下一行)

    3. SELECT - 获取所选行数

    1. $stmt = $mysqli -> prepare('SELECT name, email FROM users');
    2. $stmt -> execute();
    3. $stmt -> store_result();
    4. // 4
    5. echo $stmt -> num_rows;

    需要记住的一件事是,应该在使用num_rows属性之前调用store_result() 。

    4. 选择 - 获取结果

    1. $stmt = $mysqli -> prepare('SELECT name, email FROM users WHERE id > ?');
    2. $greaterThan = 1;
    3. $stmt -> bind_param('i', $greaterThan);
    4. $stmt -> execute();
    5. $result = $stmt -> get_result();

    现在$result与$mysqli -> query(...)相同。您可以使用以下内容来使用结果。

    1. while ($row = $result -> fetch_assoc()) {
    2. echo $row['name'];
    3. echo $row['email'];
    4. }

    5. SELECT - 带通配符

    通配符用于匹配 MYSQL 中的模式。

    1. $stmt = $mysqli -> prepare('SELECT name, email FROM users WHERE name LIKE ?');
    2. $like = 'a%';
    3. $stmt -> bind_param('s', $like);
    4. $stmt -> execute();
    5. $stmt -> store_result();
    6. $stmt -> bind_result($name, $email);
    7. while ($stmt -> fetch()) {
    8. echo $name;
    9. echo $email;
    10. }

    在此示例中,我们将选择名称以字母a开头的所有用户。(奥斯汀和阿尤什)

    6. SELECT - 带有 ID 数组

    在使用准备好的语句时,这是一件非常困难的事情。我们需要动态地将问号添加到查询中。

    1. // array of user IDs
    2. $userIdArray = [1,2,3,4];
    3. // number of question marks
    4. $questionMarksCount = count($userIdArray);
    5. // create a array with question marks
    6. $questionMarks = array_fill(0, $questionMarksCount, '?');
    7. // join them with ,
    8. $questionMarks = implode(',', $questionMarks);
    9. // data types for bind param
    10. $dataTypes = str_repeat('i', $questionMarksCount);
    11. $stmt = $mysqli -> prepare("SELECT name, email FROM users WHERE id IN ($questionMarks)");
    12. $stmt -> bind_param($dataTypes, ...$userIdArray);
    13. $stmt -> execute();
    14. $stmt -> store_result();
    15. $stmt -> bind_result($name, $email);
    16. while ($stmt -> fetch()) {
    17. echo $name;
    18. echo $email;
    19. }

    7. 选择 - 限制和偏移

    1. $stmt = $mysqli -> prepare("SELECT name, email FROM users LIMIT ? OFFSET ?");
    2. // limit of rows
    3. $limit = 2;
    4. // skip n rows
    5. $offset = 1;
    6. $stmt -> bind_param('ii', $limit, $offset);
    7. $stmt -> execute();
    8. $stmt -> store_result();
    9. $stmt -> bind_result($name, $email);
    10. while ($stmt -> fetch()) {
    11. echo $name;
    12. echo $email;
    13. }

    8. 选择 - 之间

    1. $stmt = $mysqli -> prepare("SELECT name, email FROM users WHERE id BETWEEN ? AND ?");
    2. $betweenStart = 2;
    3. $betweenEnd = 4;
    4. $stmt -> bind_param('ii', $betweenStart, $betweenEnd);
    5. $stmt -> execute();
    6. $stmt -> store_result();
    7. $stmt -> bind_result($name, $email);
    8. while ($stmt -> fetch()) {
    9. echo $name;
    10. echo $email;
    11. }

    9. 插入 - 一行

    1. $stmt = $mysqli -> prepare('INSERT INTO users (name, email) VALUES (?,?)');
    2. $name = 'Akhil';
    3. $email = 'akhilkumar@gmail.com';
    4. $stmt -> bind_param('ss', $name, $email);
    5. $stmt -> execute();

    10. INSERT - 获取插入 ID

    如果您有一个用于保存 ID 的自动增量列,在许多情况下,我们需要知道我们刚刚插入数据库的用户的 ID 是什么。在这种情况下使用$stmt -> insert_id属性。

    1. $stmt = $mysqli -> prepare('INSERT INTO users (name, email) VALUES (?,?)');
    2. $name = 'Akhil';
    3. $email = 'akhilkumar@gmail.com';
    4. $stmt -> bind_param('ss', $name, $email);
    5. $stmt -> execute();
    6. echo 'Your account id is ' . $stmt -> insert_id;

    11. INSERT - 多行(递归)

    使用准备好的语句完成递归插入非常强大。我们准备一个语句并使用它来插入多行。

    1. $newUsers = [
    2. [ 'sulliops', 'sulliops@gmail.com' ],
    3. [ 'infinity', 'infinity@gmail.com' ],
    4. [ 'aivarasco', 'aivarasco@gmail.com' ]
    5. ];
    6. $stmt = $mysqli -> prepare('INSERT INTO users (name, email) VALUES (?,?)');
    7. foreach ($newUsers as $user) {
    8. $name = $user[0];
    9. $email = $user[1];
    10. $stmt -> bind_param('ss', $name, $email);
    11. $stmt -> execute();
    12. echo "{$name}'s account id is {$stmt -> insert_id}";
    13. }

    每次插入新行时,您都会看到$stmt -> insert_id更新。

    12. 更新

    1. $stmt = $mysqli -> prepare('UPDATE users SET email = ? WHERE id = ? LIMIT 1');
    2. $email = 'newemail@hyvor.com';
    3. $id = 2;
    4. $stmt -> bind_param('si', $email, $id);
    5. $stmt -> execute();

    13. 更新 - 获取受影响的行

    有时您需要知道我们的 UPDATE 查询影响了多少行。

    1. $stmt = $mysqli -> prepare('UPDATE users SET email = ? WHERE name = ? LIMIT 1');
    2. $email = 'newemail@hyvor.com';
    3. $name = 'teodor';
    4. $stmt -> bind_param('ss', $email, $name);
    5. $stmt -> execute();
    6. // 1
    7. echo $stmt -> affected_rows;

    14. 删除

    1. $stmt = $mysqli -> prepare('DELETE FROM users WHERE id = ?');
    2. $userId = 4;
    3. $stmt -> bind_param('i', $userId);
    4. $stmt -> execute();
    5. // number of deleted rows
    6. echo $stmt -> affected_rows;

    处理错误

    知道如何调试 MYSQLI 准备好的语句总是很好的。这里有一些提示。

    1. 准备失败时

    有时$mysqli -> prepare()函数会因为查询错误而失败。

    如何检测?

    1. $stmt = $mysqli -> prepare('SELECT * FROM no_table WHERE id = ?');
    2. $id = 1;
    3. $stmt -> bind_param('i', $id);

    如果您在调用$stmt的方法时 看到 PHP 中的错误,例如“在布尔值上调用成员函数 bind_param()”,则说明准备工作失败。当$mysql -> prepare()失败时,它返回false。因此$stmt是一个布尔值,而不是一个对象。现在我们可以使用$mysqli -> error来查找查询中的错误。

    1. $stmt = $mysqli -> prepare('SELECT * FROM no_table WHERE id = ?');
    2. echo $mysqli -> error;

    2. 执行失败时

    执行失败通常不会引发错误。因此,您应该添加一个条件来检查执行是否成功。如果不是,$stmt -> error会告诉你什么是错误。

    1. $stmt = $mysqli -> prepare('INSERT INTO stmt_users (name) VALUES (?)');
    2. $name = 'User';
    3. $stmt -> bind_param('i', $name);
    4. if (! $stmt -> execute()) {
    5. echo $stmt -> error;
    6. }

    对于我们的示例表,错误是"Field 'email' doesn't have a default value"

    结论

    我的目标是涵盖在本教程中执行准备好的语句的所有方法。我们讨论了如何为 SELECT、INSERT、UPDATE 和 DELETE 使用准备好的语句。所以,我希望我涵盖了所有内容。如果您愿意学习执行 MYSQLI 准备好的语句的最佳方法,那么本文适合您。我正在等待在评论部分看到您的反馈。感谢您的阅读!

  • 相关阅读:
    亚商投资顾问 早餐FM/12022023年开展第五次全国经济普查
    矩阵等价和向量组等价的一些问题
    python生成随机数
    为什么win11连接wifi频繁掉线?
    物联网运维-前端设备运维管理设计及解决方案
    学数学,要“直觉”还是要“严谨”?
    leetcode经典面试150题---6.旋转数组
    证券行业超融合架构方案设计
    Prometheus-2:blackbox_exporter黑盒监控
    目标检测-AnyLabeling标注格式转换成YOLO格式
  • 原文地址:https://blog.csdn.net/allway2/article/details/126813273