PHP MySQLi准备好的语句似乎不会绑定或传递变量 - 但是可以与PDO一起使用

时间:2018-05-21 07:17:27

标签: php mysqli pdo prepared-statement mariadb

我对最近停止工作的应用程序遇到了一些麻烦,但我无法弄清楚问题可能是什么。

从数据库中读取效果很好,但是当我尝试插入或更新现有记录时,它无法正常工作。有时,记录字段值设置为null而不是变量值。

此应用程序当前正在共享主机上运行,​​并且在一个星期前一直工作好几个月。我让UAT实例与另一个提供商坐在另一个主机上,它似乎没有问题。

在我的调查过程中,我注意到如果我通过标准的PHP MYSQLi程序声明更新或插入正确更新/插入记录,但是当我尝试通过准备好的声明绑定它时它没有&#t; t工作。

PHP / MySQL没有抛出任何错误。

我尝试通过创建一个用值更新一条记录的简单测试脚本来尝试简化。

这有效:

<?php
    // Connection file
    require 'connection.php';

    // Create connection
    $conn = new mysqli($servername, $username, $password, $dbname);

    // Check connection
    if ($conn->connect_error) {
        die("Connection failed: " . $conn->connect_error);
    }

    // set parameters and execute
    $firstname = htmlspecialchars($_GET["firstname"]);

    $sql = "UPDATE users SET first_name='$firstname' WHERE uid=1";

    if ($conn->query($sql) === TRUE) {
        echo "Updated record successfully";
    } else {
        echo "Error updating record: " . $conn->error;
    }

    $conn->close();
    ?>

虽然不是这样:

<?php
    // Connection file
    require 'connection.php';

    // Create connection
    $conn = new mysqli($servername, $username, $password, $dbname);

    // Check connection
    if ($conn->connect_error) {
        die("Connection failed: " . $conn->connect_error);
    }

    // set parameters and execute
    $firstname = htmlspecialchars($_GET["firstname"]);

    // prepare and bind
    $stmt = $conn->prepare("UPDATE users SET first_name=? WHERE uid =1");
    $stmt->bind_param("s", $firstname);


    $stmt->execute();

    echo "Updated record successfully";

    $stmt->close();
    $conn->close();
    ?>

我正在运行PHP v7.0.30,Apache v2.4.33和MySQL v10.2.15(MariaDB)

任何想法。这让我发疯了......

我刚刚尝试返回第二个示例的受影响行数。

printf("Affected rows (UPDATE): %d\n", $stmt ->affected_rows);

如果数据库表中的first_name有值,并且我运行输出行数的脚本,则返回&#39;受影响的行1&#39; 。当我检查数据库时,我可以看到该值现在为空。

是什么导致这个?也许是某种编码问题?

更新1

刚刚添加了var_dump($ stmt,$ firstname);绑定后的第二个例子。

object(mysqli_stmt)#3 (10) { ["affected_rows"]=> int(-1) ["insert_id"]=> int(0) ["num_rows"]=> int(0) ["param_count"]=> int(1) ["field_count"]=> int(0) ["errno"]=> int(0) ["error"]=> string(0) "" ["error_list"]=> array(0) { } ["sqlstate"]=> string(5) "00000" ["id"]=> int(0) } string(3) "Bob" 

受影响的行:1

object(mysqli_stmt)#3 (10) { ["affected_rows"]=> int(-1) ["insert_id"]=> int(0) ["num_rows"]=> int(0) ["param_count"]=> int(1) ["field_count"]=> int(0) ["errno"]=> int(0) ["error"]=> string(0) "" ["error_list"]=> array(0) { } ["sqlstate"]=> string(5) "00000" ["id"]=> int(0) } string(4) "Jack" 

受影响的行:0`

更新2

我开始认为这是一个服务器问题。 我刚刚测试过使用PDO准备更新记录并且它正在工作。

<?php
    // Connection file
    require 'connection.php';

    // set parameters
    $firstname = $_GET["firstname"];
    $id = 1;

    try {
        $conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password);
        // set the PDO error mode to exception
        $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

        // prepare sql and bind parameters
        $stmt = $conn->prepare("UPDATE users SET first_name=? WHERE uid=?");
        $stmt->execute([$firstname,$id]);

        }
    catch(PDOException $e)
        {
        echo "Error: " . $e->getMessage();
        }
    $conn = null;

?>

当我尝试为SELECT执行准备好的语句时,我得到的服务不可用&#39;。在当地工作正常。

<?php
    // Connection file
    require 'connection.php';

    // Create connection
    $conn = new mysqli($servername, $username, $password, $dbname);

    // Check connection
    if ($conn->connect_error) {
        die("Connection failed: " . $conn->connect_error);
    }

    // set parameters and execute
    $id = 1;

    //create a prepared statement
    $query = "SELECT first_name FROM users WHERE uid=?";
    $stmt  = $conn->prepare($query);

    $stmt ->bind_param('i', $id);

    //execute query
    $stmt ->execute();

    //bind result variables
    $stmt ->bind_result($first_name);

    //fetch records
    while($stmt ->fetch()) {
        print $first_name;
    }   

    //close connection
    $stmt ->close();

    mysqli_close($conn);
?>

最终更新 - 问题已解决

我的托管服务提供商能够解决此问题。似乎nd_mysqli PHP扩展已被禁用。启用它后,上面的示例工作,我的应用程序现在正在运行。

1 个答案:

答案 0 :(得分:1)

最终更新 - 解决问题

我的托管服务提供商能够解决此问题。似乎nd_mysqli PHP扩展已被禁用。启用它后,上面的示例工作,我的应用程序现在正在运行。