【问题标题】:PHP can't fetch last id inserted correctlyPHP 无法获取正确插入的最后一个 id
【发布时间】:2026-01-28 23:40:01
【问题描述】:

对于我的问题,我有两种可能的解决方案,我想回显插入的最后一个 id,以了解有多少人填写表格,但这会影响下表中的数据。注意:这不会影响数据库本身,只会影响浏览器的输出。

connect.php

@$db = new mysqli('127.0.0.1', 'blop', 'blop', 'blop');

if ($db->connect_errno) {
    die ('Sorry, we are having some problems.');
}

显示结果:

function returnData() {
    global $db;

    echo ('<style> td {border: 1px solid #000; background:#ed8043;} th {border:1px solid #000; background:#fff</style>
                    <table style="width:100%; text-align:center;">
                        <tr>
                        <th>Line</th>
                        <th>id</th>
                        <th>Name</th>
                        <th>Email</th>
                        <th>Visited</th>
                        </tr>');


    $result = $db->query("SELECT * FROM `people` ORDER BY `created` DESC");
    $count = $result->num_rows;
    echo 'Number of visits: ' .$count.'<br><br>';

    /*$visits1 = $result->fetch_assoc();
    echo $visits1['id']. '<br>';
    $visits2 = $db->insert_id;
    echo $visits2. '<br>';*/

    $row_num = 1;
        while ($row = $result->fetch_object()) {

            echo ('
                    <tr>
                    <td>' .$row_num. '</td>
                    <td>' .$row->id. '</td>
                    <td>' .$row->first_name. '</td>
                    <td>' .$row->mail. '</td>
                    <td>' .$row->created.'</td>
                    </tr>'
                );

            $row_num++;
        }
            echo ('</table><br>');
            $result->free();
}

问题是当我这样尝试时:1.

$result = $db->query("SELECT * FROM `people` ORDER BY `created` DESC");
$visits1 = $result->fetch_assoc();
echo $visits1['id']. '<br>';

我实际上比表格上显示的 ID 多一个,如下图所示:

如您所见,我有“756”女巫很好,因为它是插入的最后一个 id,但我不想要相应的行(id 为 756),它从下面的表格中消失了。当我评论上面的代码时,它工作正常,第一行是插入的最后一个 id。

我有一个替代代码来解决这个问题,问题是这也不起作用:2.

$result = $db->query("SELECT * FROM `people` ORDER BY `created` DESC");
$visits2 = $db->insert_id;
echo $visits2. '<br>';

这次表格是正确的,它显示了所有行,但总 id 的数量为 0。

【问题讨论】:

  • 你做网格的代码也可以贴出来
  • 好的,马上更新

标签: php database output


【解决方案1】:

这就是fetch_* 方法正在做的事情,这就是您需要的,以便您可以迭代它们。这是编程循环的简单逻辑。要执行函数n 次,请将其放入循环中,或者手动调用它n 次。您手动调用一次,因此您已经从该结果集中获取了第一项。将其放入while() 循环将从结果集中获取剩余元素。

为避免这种情况,您最好切换到已获取的结果集并对其进行操作。

现在,你打破了单一职责原则,因为returnData 获取数据,制作 HTML 等等。

使用查询创建一个函数getData(),然后将它与foreach一起使用以获取所有结果集。

仅使用一次即可获取最后一个 Id(第一个)。

function getData() {
     global $db;
     $result = $db->query("SELECT .......");
     while ($row = $result->fetch_object()) {
          $rows[] = $row;
     }
     return $rows;
}

现在在returnData()你可以使用

getData()[0]->id

要获取最后一个 id,因为您也可以在不丢失结果集的情况下遍历方法:

foreach (getData() as $data) {
    echo $data->id;
}

你最好为这个应用程序中你需要的每一个东西创建函数。获取最后一个 id、获取整个结果集、获取行数等。从单个查询/方法中获取它很少是好的做法。

老实说,你的代码中有很多问题需要修复,从全局变量开始,到放弃函数式/过程式风格以支持 OOP

【讨论】:

    【解决方案2】:

    尝试使用:

    SELECT `AUTO_INCREMENT`
    FROM  INFORMATION_SCHEMA.TABLES
    WHERE TABLE_SCHEMA = 'blop'
    AND   TABLE_NAME   = 'people';
    

    【讨论】:

    • WHERE TABLE_SCHEMA = 'blop' - blop 这是你的数据库名称,对吗?
    【解决方案3】:

    在第一个示例中,您不应该立即执行第二个 'fetch_...'。那是因为你丢弃了第一行,你已经获取了。

    下面的快速(未经测试,抱歉错别字)修复:

    ...

    $row = $result->fetch_object();
    echo $row->id. '<br>';
    
    $row_num = 1;
        while ($row_num == 1 || $row = $result->fetch_object()) {
    
            echo ('
                    <tr>
                    <td>' .$row_num. '</td>
                    <td>' .$row->id. '</td>
                    <td>' .$row->first_name. '</td>
                    <td>' .$row->mail. '</td>
                    <td>' .$row->created.'</td>
                    </tr>'
                );
    
            $row_num++;
        }
    

    ...

    【讨论】:

      【解决方案4】:

      来自 php 文档:

      mysqli_insert_id() 函数返回由对具有 AUTO_INCREMENT 属性的列的表的查询生成的 ID。如果最后一个查询不是 INSERT 或 UPDATE 语句,或者修改后的表没有具有 AUTO_INCREMENT 属性的列,则此函数将返回零。

      所以SELECT 查询不会返回最后插入的 id。

      一般来说,这个查询应该适用于按列排序的表的最后一行:

      select column_name from table_name order by column_name desc limit 1;
      

      对于 id 你也可以使用:

      select LAST_INSERT_ID() from table;
      

      这不会强制您在此查询之前进行 INSERTUPDATE 查询。

      【讨论】: