【问题标题】:How do I convert this PDO code to MySQLi?如何将此 PDO 代码转换为 MySQLi?
【发布时间】:2019-12-09 07:39:20
【问题描述】:

我对 PHP 和 MySQL 还很陌生,我尝试学习如何将代码从 PDO 更改为 MySQLi。它与我在网络上找到的登录系统的安全令牌和标识符有关的记住我功能。 我想了解并了解如何将代码从 PDO 更改为 MySQLi。我知道在 MySQLi 中有一条语句创建和准备,我还必须绑定参数并执行。但是在这种情况下,我不知道如何开始。

$pdo = new PDO('mysql:host=localhost;dbname=dbname', 'root', '');
if (!isset($_SESSION['id']) && isset($_COOKIE['identifier']) &&
isset($_COOKIE['securitytoken'])) {
    $identifier = $_COOKIE['identifier'];
    $securitytoken = $_COOKIE['securitytoken'];

    $statement = $pdo->prepare("SELECT * FROM securitytokens WHERE identifier = ?");
    $result = $statement->execute(array($identifier));
    $securitytoken_row = $statement->fetch();

    if (sha1($securitytoken) !== $securitytoken_row['securitytoken']) {
        die('Maybe a stolen securitytoken.');
    } else {
        //Token was correct
        //Set an new token
        $neuer_securitytoken = random_string();
        $insert = $pdo->prepare("UPDATE securitytokens SET securitytoken = :securitytoken WHERE identifier = :identifier");
        $insert->execute(array('securitytoken' => sha1($neuer_securitytoken), 'identifier' => $identifier));
        setcookie("identifier", $identifier, time() + (3600 * 24 * 365)); //1 Year valid
        setcookie("securitytoken", $neuer_securitytoken, time() + (3600 * 24 * 365)); //1 Year valid

        //Loggin the user
        $_SESSION['id'] = $securitytoken_row['id'];
    }
}

【问题讨论】:

  • 我不明白为什么需要从 PDO 切换到 MySQLi,但这是个人喜好。无论如何,请查看prepared statementsbind_param 的文档。 MySQLi 不使用命名参数。
  • 老实说,我认为没有人愿意从 PDO 切换到 MySQLi。 PDO 更简单,功能更多。
  • 是的,这个问题确实很有趣,人们通常会从 MySQLi 切换到限制较少的选项 PDO
  • 是的,我知道 - 用于学习目的。感谢您的链接和提示。我想我现在已经完成了准备语句和 bind_param。但是这一行我不知道如何处理: $result = $statement->execute(array($identifier));我不能把东西放进 $statement->execute();这是如何工作的?
  • 不,你必须使用 bind_param。 OOP 风格中使用的execute 不带任何参数。在程序样式中,它只需要链接php.net/manual/en/mysqli-stmt.execute.php

标签: php mysqli pdo


【解决方案1】:

别这样! PDO 更简单并提供更多功能。

如果您只想学习 MySQLi,那么您应该牢记以下几点:

  1. 这是您正确打开连接的方式:

    mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
    $mysqli = new mysqli($host, $user, $pass, $db);
    $mysqli->set_charset($charset);
    
  2. MySQLi 中没有执行中的绑定。实际上根本没有按值绑定!您只能通过引用绑定,并且必须指定值的类型。

    $statement = $mysqli->prepare("SELECT * FROM securitytokens WHERE identifier = ?");
    $statement->bind_param('i', $identifier); // i for integer; s for string. 
    $statement->execute();
    
  3. MySQLi 没有命名占位符,因此您只需要使用位置占位符。

    $insert = $mysqli->prepare("UPDATE securitytokens SET securitytoken = ? WHERE identifier = ?");
    $sha1ResultDueToPassByRef = sha1($neuer_securitytoken);
    $insert->bind_param('si', $sha1ResultDueToPassByRef, $identifier);
    $insert->execute();
    
  4. MySQLi 中的fetch 方法的工作方式完全不同,它返回布尔值。要获得与PDO's fetch() 相同的结果,您需要先使用get_result(),然后使用fetch_array()fetch_assoc()

    $securitytoken_row = $statement->get_result()->fetch_array();
    

【讨论】:

  • 只有在您拥有 MYSQLND 驱动程序的情况下,才能将 fetch_arrayfetch_assoc 与准备好的语句一起使用。
  • 哇 - 这真的很快。我会努力学习这个,非常感谢!我也会尝试找出为什么不应该这样做
  • @Barmar 很好,但是任何使用 PHP 5.4 的人都应该默认拥有这个驱动程序,并且 PHP 5.4 以下的所有版本已经被弃用多年了。
  • 我完全同意。将 PDO 代码转换为 mysqli 的每一步都揭示了不这样做的更多理由。
猜你喜欢
  • 2021-01-03
  • 1970-01-01
  • 2019-09-04
  • 2015-01-25
  • 2017-09-27
  • 2019-12-19
  • 1970-01-01
  • 1970-01-01
  • 2015-04-05
相关资源
最近更新 更多