【问题标题】:Call to a member function fetch_assoc() on array [duplicate]调用数组上的成员函数 fetch_assoc() [重复]
【发布时间】:2020-02-22 01:15:40
【问题描述】:

我正在开发一个测验应用程序,我是这个错误:

致命错误:未捕获的错误:调用 C:\wamp64\ 中数组上的成员函数 fetch_assoc()

怎么了?

/**
* Get the Question
*/
$query = "SELECT * FROM questions
WHERE question_number = $number";

//Get result
$result = mysqli_query ($conn,$query);

$question = $result->fetch_assoc();


/*
* Get choices
*/
$query = "SELECT * FROM choices
WHERE question_number = $number";

//Get result
$result = mysqli_query ($conn,$query);

$choices = $result->fetch_assoc();
?>

<html>
<body>
    <main>
<div class="container" >
<div class="current">Question 1 of 5</div>
<p class="question">
 <?php echo $question ['text']; ?>
</p>

  <?php while ($row = $choices->fetch_assoc()) : ?>
  <li><input name="choice" type="radio value="<?php echo $row ['id'];?> " /><?php echo $row ['text']; ?></li>
      <input type="submit" value="Sumbit your answer"/>
  </ul>


 </main>

    </body>
</html>

<?php endwhile; 

【问题讨论】:

  • 请使用准备好的语句。

标签: php mysqli


【解决方案1】:

该错误表明您正在尝试从数组中获取,而不是从数据库结果集中获取。
在您的代码中:

$choices = $result->fetch_assoc();

这个fetch_assoc返回“一个代表结果集中提取行的字符串的关联数组”,所以$choices将是第一行的数组。

while ($row = $choices->fetch_assoc()) ...

这个fetch_assoc 需要一个“mysqli_query 返回的结果集标识符”,但是$choices 是一个已经被获取的数组,所以while 循环失败了:

调用数组上的成员函数 fetch_assoc()


考虑循环遍历结果集$result 以逐一获取行,如下所示:

$result = mysqli_query($conn,$query);
while ($row = $result->fetch_assoc()) ...

或者,使用fetch_all 一次获取所有行并使用for 循环遍历生成的$choices 数组:

$result = mysqli_query($conn,$query);
$choices = $result->fetch_all();
foreach ($choices as $choice) ....

正如 Dharman 所说,mysqli_result is traversable。您可以直接使用foreach 循环进行迭代:

$choices = mysqli_query($conn,$query);
foreach ($choices as $choice) {
    echo $choice['text'];
}

话虽如此,请考虑observation from Your Common Sense

但它实际上只是一个while循环的语法糖——你不能直接访问这个“数组”值的值,这使得这个特性实际上有点用处。

【讨论】:

  • 你不需要while循环来循环。 mysqli_result 是可遍历的。
  • 不错的补充,但恐怕你误解了 YCS 的说明。你知道这意味着什么吗?
  • 是的。对我来说,在这种情况下,迭代方法在某种程度上是一种风格选择,而且对 OP 的问题似乎并不那么重要。但如果您愿意,我鼓励您在回答中阐明您的想法。
  • 非常感谢您的帮助,非常感谢。到目前为止,我已经让我的项目再次工作。谢谢。
【解决方案2】:

您正在使用这一行将单行提取到 PHP 数组中:

$choices = $result->fetch_assoc();

然后在 while 循环中使用该数组:

while ($row = $choices->fetch_assoc())

你不能在数组上调用fetch_assoc()

您应该做的是将所有行提取到一个多维数组中,然后在该数组上获取foreach

$result = mysqli_query($conn, $query);
$choices = $result->fetch_all(MYSQLI_ASSOC);

// and then loop:

foreach($choices as $row) :

$result 是 mysqli_object 类的对象。直接使用此对象可能很困难。建议使用fetch_all() 将所有记录提取到一个数组中。然后,您可以更改数组、过滤器、循环、访问特定行等。您不能使用 mysqli_result 对象来执行此操作,并且逐行读取的方法可能会令人困惑。

你可以直接循环mysqli_result,这比while ($row = $choices-&gt;fetch_assoc())好很多。最大的好处是它总是从头到尾循环,所以你可以循环很多次而不用倒带。例如:

$result = $conn->query('SELECT * FROM users LIMIT 3'); // 3 rows returned

var_dump($result->fetch_all(MYSQLI_ASSOC)); // <-- this works
var_dump($result->fetch_all(MYSQLI_ASSOC)); // <-- this will not work without rewiding

// both of the loops will work
foreach ($result as $row) {
    var_dump($row);
}
foreach ($result as $row) {
    var_dump($row);
}

foreach 循环也更简洁、更易于理解。你运行一个查询,然后你循环结果。

当然,mysqli_result 对象不是数组。你可以循环它,但你不能通过数组索引访问特定的行。这不会让您获得第一行:

mysqli_query($conn, '...')[0]; // <-- Uncaught Error: Cannot use object of type mysqli_result as array

如果您的 SQL 中有变量输入,您应该使用准备好的语句。您修复的查询应如下所示:

$stmt = $conn->prepare("SELECT * FROM choices WHERE question_number = ?");
$stmt->bind_param('i', $number);
$stmt->execute();
$result = $stmt->get_result();

foreach ($result as $row) {
    // echo HTML
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-07-04
    • 1970-01-01
    • 1970-01-01
    • 2016-08-30
    • 2012-09-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多