【问题标题】:MySQLi foreach bind_param()MySQLi foreach 绑定参数()
【发布时间】:2015-10-01 01:27:07
【问题描述】:

我正在从表单发送一组值。我想循环查找这些 ID 的数据库表。当我收到这条消息时,我明白出了点问题......

致命错误:在第 56 行的 /home/d15155/tool/pdf.php 中的非对象上调用成员函数 bind_param()

if (count($_POST['q']) == 0){
}
else {
  foreach($_POST['q'] as $quality){
    # Prepare statement
    $stmt = $mysqli->prepare("SELECT the_question, the_sub_questions, the_quality, the_time FROM my_questions WHERE the_category='2' AND the_headline='5' AND quality_id = ? ORDER BY the_sort_order ASC");
    $stmt->bind_param('i', $quality);
    $stmt->execute(); 
    $stmt->store_result();
    $stmt->bind_result($the_question, $the_sub_questions, $the_quality, $the_time); 
    $stmt->fetch();
    $konkretaexempel .= utf8_encode($the_question) . " <br />";
  }
}

我想将结果添加到一个长字符串中(然后在 PDF 中使用)。

编辑

删除了 foreach 和数组,但仍然收到相同的错误消息。我检查了,数据库连接正常。

    if (count($_POST['q']) == 0){

    }
    else {

$stmt = $mysqli->prepare("SELECT the_question, the_sub_questions, the_quality, the_time FROM my_questions WHERE the_category='2' AND the_headline='5' AND quality_id = ? ORDER BY the_sort_order ASC");

        $stmt->bind_param('i', '27');
        $stmt->execute(); 
        $stmt->bind_result($the_question, $the_sub_questions, $the_quality, $the_time); 
        $stmt->fetch();
        $konkretaexempel .= utf8_encode($the_question) . " <br />";

        }

【问题讨论】:

  • 您似乎截断了错误消息;您可能需要编辑您的问题以包含完整的消息。
  • 这意味着prepare 不起作用。尝试在语句中添加 ` 周围的列名
  • 旁注:-&gt;prepare() 的目的是让您无需在每次循环迭代时调用它。通过将其放在您的 foreach() 中,您正在浪费它的最佳功能/特性之一。

标签: php arrays mysqli


【解决方案1】:

Sean 在 cmets 中的提示在这里可能不仅仅是一个旁注;它会解决这个问题:每个连接只能有一个活动查询/语句,并且在单个 ->fetch() 之后,该语句仍然处于活动状态(while-loop 可以解决这个问题,但这里不需要)。当您按照建议重新使用 $stmt 实例时,任何旧的结果集都将被丢弃。

你的脚本目前是这样的

<?php
$mysqli = setup();

if (count($_POST['q']) == 0){
    myErrorHandling();
}
else {
    foreach($_POST['q'] as $quality){       
        $stmt = $mysqli->prepare("SELECT x, y FROM soFoo WHERE id = ?");
        if ( !$stmt ) { die('prepare failed'); }
        $stmt->bind_param('i', $quality);
        $stmt->execute(); 
        $stmt->bind_result($x, $y); 
        $stmt->fetch();
        printf("x=%d,y=%s\r\n", $x, $y);
    }
}


function setup() {
    // for demonstration purposes only
    $_POST = [ 'q'=> [
        1,3,5
    ]];

    mysqli_report(MYSQLI_REPORT_STRICT);
    $mysqli = new mysqli('localhost', 'localonly', 'localonly', 'test');


    $mysqli->query('
        CREATE TEMPORARY TABLE soFoo (
            id int auto_increment,
            x int,
            y varchar(32),
            primary key(id)
        )
    ');

    $stmt = $mysqli->prepare('INSERT INTO soFoo (x,y) VALUES (?,?)');
    $stmt->bind_param('ss', $x, $y);
    foreach( range('a','z') as $x=>$y ) {
        $stmt->execute();
    }
    return $mysqli;
}

输出是

x=0,y=a
prepare failed

现在,当我将调用 prepare/bind_param 移到循环之前

<?php
$mysqli = setup();

if (count($_POST['q']) == 0){
    myErrorHandling();
}
else {
    $stmt = $mysqli->prepare("SELECT x, y FROM soFoo WHERE id = ?");
    if ( !$stmt ) { die('prepare failed'); }
    $stmt->bind_param('i', $quality);
    foreach($_POST['q'] as $quality){       
        $stmt->execute(); 
        $stmt->bind_result($x, $y); 
        $stmt->fetch();
        printf("x=%d,y=%s\r\n", $x, $y);
    }
}


function setup() {
  ... same as before...
}

输出是

x=0,y=a
x=2,y=c
x=4,y=e

正如预期的那样。

【讨论】:

  • 感谢您的回复 VolkerK,我尝试了您的建议,但仍然收到相同的错误消息。我尝试创建一个新数组只是为了测试目的,但仍然是同样的错误。
  • 我已经用 php 5.6.10/win32 和 mysql 5.6.something 测试了这些脚本
  • 嗯.. 我现在在没有 foreach 和数组的情况下进行了测试,但仍然出现相同的错误...请参阅原始帖子。
猜你喜欢
  • 1970-01-01
  • 2010-12-03
  • 2012-08-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-27
  • 2016-08-31
相关资源
最近更新 更多