【问题标题】:mySQLi prepared statement unable to get_result()mySQLi 准备好的语句无法 get_result()
【发布时间】:2012-05-15 01:01:51
【问题描述】:

我完全被 mySQLi 搞糊涂了。尽管我多年来一直在使用过程 mysql 调用,但我想习惯于为它提供的 db security/mySQL 注入保护制作准备好的语句。我正在尝试编写一个简单的选择语句(是的,我知道为此进行程序调用可以提高性能)。运行时,我得到所有回声,直到我点击 $result = $stmt->get_result(); 组件。这一切对我来说似乎都相当简单,但是在阅读了几个小时的 mySQLi 手册后,我不知所措。任何想法为什么这会失败?

*注意:这是一个测试环境,虽然没有对字符进行清理/转义,但我只是将有效内容传递给变量 $username 和 $email。而且,我已经查看了所有内容以找到我的问题的解决方案。

function checkUsernameEmailAvailability($username, $email) {
    //Instantiate mysqli connection
    @$mysqli = new mysqli(C_HOST,C_USER,C_PASS,C_BASE) or die("Failed to connect to MySQL database...");
    if (!$mysqli)
    {
        echo 'Error: Could not connect to database.  Please try again later...';
        exit;
    } else {
        echo 'mysqli created';
    }

    /* Create a prepared statement */   
    if($stmt = $mysqli -> prepare("SELECT username,email FROM tb_users WHERE username=? OR email=?")) {
        echo '<br />MYSQLi: ';

        /* Bind parameters s - string, b - boolean, i - int, etc */
        $stmt -> bind_param("ss", $username, $email);
        echo '<br />paramsBound...';

        /* Execute it */
        $stmt -> execute();     
        echo '<br />Executed';

        $result = $stmt->get_result();
        echo '<br />Result acquired';

        /* now you can fetch the results into an array - NICE */
        $myrow = $result->fetch_assoc();
        echo '<br />Fetched';


        /* Close statement */
        /$stmt -> close();
        echo '<br />Done mysqli';
    }
}    

另外,我每次调用函数时都必须实例化一个 mysqli 吗?我假设它们不是像程序 mysql 中那样持久的数据库连接。是的,我知道这是一个范围问题,不,我无法理解此类变量的范围。当我在函数外声明它时,当我进入函数时它是不可用的。

更新 如果我将第 12 行更改为:

if($stmt = $mysqli -> prepare("SELECT username,email FROM tb_users WHERE username=? OR email=?")) {

到:

    $stmt = $mysqli->stmt_init();
    if($stmt = $mysqli -> prepare("SELECT username,email FROM tb_users WHERE username=? OR email=?")) {
        if(!stmt) echo 'Statement prepared'; else echo 'Statement NOT prepared';

我收到未准备好的声明。现在我更加困惑了......

更新: 我联系了我的托管服务提供商,显然支持 mySQLi,并且存在 mysqlnd 驱动程序。也许有一种方法可以简单地测试这个?虽然他们过去通常给我非常有见识的答案。

更新...再次:我自己检查了我的服务器功能并发现,虽然 mysqli 和 PDO 存在,但 mysqlnd 不存在。因此,我明白为什么 get_result() 不起作用(我认为需要 mysqlnd),我仍然不明白为什么准备好的语句本身不起作用。

【问题讨论】:

  • 我自己使用带有异常的 PDO(并且绝对可以推荐它......)所以我对 mysqli 不太了解,但您似乎可以使用 $stmt-&gt;error 来描述您的错误,见php.net/manual/en/mysqli.error.php。这给了你什么?
  • 我完全不熟悉 PDO,它是否提供与 mysqli 准备好的语句相同的好处?我将立即检查 $stmt->error 函数。此外,即使我的提供者声明 mysqlnd 存在,运行 phpinfo() 根本没有显示对它的引用......
  • 启用错误报告、显示/记录并告诉我们您收到的错误消息。有了这些信息,就很容易告诉你这里发生了什么。其他一切都只是在黑暗中刺伤并做出假设。这会耗费你的精力和时间。
  • 就像我说的,我对mysqli一无所知。事实上,在尝试这条路线之前,我可能会更好地研究 mysqli。检查了 PDO(甚至不知道它可以与 mysqli 相媲美),它有很多好处。性能受到轻微影响,但一切都一样,命名参数和直接到对象结果令人难以置信!更不用说数据库抽象了。对此进行更多研究,将很快更新...
  • PDO 没有问题!最终代码如下,无法回答我自己的问题,因为声誉还不够高。 function checkUsernameEmailAvailability($username, $email) { $dsn = 'mysql:dbname='.C_BASE.';host='.C_HOST; $user = C_USER; $password = C_PASS; new PDO($dsn, $user, $password); $params = array(':username' =&gt; $username, ':email' =&gt; $email); $sth = $dbh-&gt;prepare('SELECT username,email FROM tb_users WHERE username = :username OR email = :email '); $sth-&gt;execute($params); $result = $sth-&gt;fetch(PDO::FETCH_ASSOC); print_r($result); }

标签: php mysqli prepared-statement


【解决方案1】:

mysqli_stmt :: get_result 仅适用于 mysqlnd 包。删除 php5-mysql 包并安装 php5-mysqlnd 代替

【讨论】:

  • 你怎么能这样做?
【解决方案2】:

通过一些检查,即使我的主机上安装了 mysqli,但显然 mysqlnd 驱动程序不存在。因此,不能使用 get_result()(php 手册将 get_result 定义为依赖于 mysqlnd),而是需要进行额外的编码来按照我想要的方式处理我的结果。

因此,我决定尝试了解 PDO 的工作原理,并在几分钟内,瞧!!!

将上面的代码替换为:

function checkUsernameEmailAvailability($username, $email) {

echo 'pdo about to be created';

$dsn = 'mysql:dbname='.C_BASE.';host='.C_HOST;
$user = C_USER;
$password = C_PASS;

try {
    $dbh = new PDO($dsn, $user, $password);
} catch (PDOException $e) {
    echo 'Connection failed: ' . $e->getMessage();
}

$params = array(':username' => $username, ':email' => $email);

try{
$sth = $dbh->prepare('SELECT username,email FROM tb_users WHERE username = :username OR email = :email ');
} catch(PDOException $e) {
    echo 'Prepare failed: ' . $e->getMessage();
}

try{
$sth->execute($params);
} catch(PDOException $e) {
    echo 'Execute failed: ' . $e->getMessage();
}
$result = $sth->fetch(PDO::FETCH_ASSOC);
print_r($result);
}

我能想到的尽可能多的错误检查,而且完全没有问题首先破解它!

最终代码

function checkUsernameEmailAvailability($username, $email) {
    $dsn = 'mysql:dbname='.C_BASE.';host='.C_HOST;
    $user = C_USER;
    $password = C_PASS;
    new PDO($dsn, $user, $password);

    $params = array(':username' => $username, ':email' => $email);

    $sth = $dbh->prepare('SELECT username,email FROM tb_users WHERE username = :username OR email = :email ');
    $sth->execute($params);
    $result = $sth->fetch(PDO::FETCH_ASSOC);

    print_r($result);
}

【讨论】:

    猜你喜欢
    • 2012-12-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-18
    • 2011-03-07
    • 2014-06-11
    • 2011-06-20
    相关资源
    最近更新 更多