php - SELECT LAST_INSERT_ID() 间歇性返回 0

标签 php mysql pdo

我搜索了很多类似的问题,但找不到任何间歇性返回0的问题

**** 编辑 *****

此后,我尝试使用只有两列的新表进行测试,将问题减少到大约五十分之一返回零。

我刚刚也能够在付费托管服务器上进行测试,但无法复制我的问题

我认为该问题特定于该网络主机。

问题:

当尝试在每个连接的基础上检索最后插入的 ID 时,大约十分之四的情况是我得到返回的 0。

本地主机,一切正常,没有问题。仅当我的网站托管在服务器上时才会出现此问题。

SELECT LAST_INSERT_ID() intermittently returns 0

$PDOconnection->lastInsertId(); Always returns correct ID

我需要在每个连接的基础上可靠地获取最后插入的 ID,因为在数据库中创建采购订单时,这对于我的网站的结帐流程至关重要。

注释:

  • ID 自动递增
  • sql 插入始终工作正常,并且数据库显示一个新条目。
  • 切换 PHP 版本无法解决问题
  • 我使用的网络主机是我用于直播的免费托管服务 测试目的
  • 页面加载时间始终相似(下面的代码为 500 - 750 毫秒)

我剥离了整个代码(如下所示)以简单地进行测试。问题仍然存在

我似乎无法弄清楚我的问题出在哪里。

include_once "php/config.php";

$cookie_id = 0;

// Time of checkout
$time = gmdate("d/m/Y h:i:s");

// Create new purchase order
$sql_insert = "INSERT INTO user_purchases (cart_id, timestamp) VALUES (:cookie_id, :time)";

$stmt_insert = $PDOconnection->prepare($sql_insert);
$stmt_insert->bindParam(':cookie_id', $cookie_id, PDO::PARAM_STR);
$stmt_insert->bindParam(':time', $time, PDO::PARAM_STR);
$stmt_insert->execute();

$checkout_id_0 = $PDOconnection->lastInsertId();

// Get the primary key id of the last inserted item on per-connection basis
$sql_last_id = "SELECT LAST_INSERT_ID()";
$stmt_last_id = $PDOconnection->prepare($sql_last_id);
$stmt_last_id->execute();
$r_last_id = $stmt_last_id->fetch(PDO::FETCH_ASSOC);

$checkout_id_1 = $r_last_id['LAST_INSERT_ID()'];

echo $checkout_id_0 . " " . $checkout_id_1;  // I echoed out to observe results

连续 10 个查询的结果的真实示例(只需刷新页面即可)。我并排呼应了结果。

checkout_id_0      $checkout_id_1  <---SELECT LAST_INSERT_ID()

      16                16
      17                17
      18                0        // Returned 0
      19                19
      20                0        // Returned 0
      21                0        // Returned 0
      22                22
      23                23
      24                23       // Returned previous ID (happens 1/30 tries)
      25                25

连接配置:

$PDOconnection = new PDO("mysql:host=$servername;dbname=$dbname;charset=utf8", $sql_username, $sql_password);

// Set PDO error mode to exception
$PDOconnection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

// Set PDO Attribute to force native prepared statements
$PDOconnection->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);

最佳答案

您是否尝试过激活持久连接?请参阅Connections and Connection managementPersistent Database Connections 。也许远程服务器的 MySQL 设置太短 - wait_timeoutinteractive_timeout ...

Persistent connections are not closed at the end of the script, but are cached and re-used when another script requests a connection using the same credentials. The persistent connection cache allows you to avoid the overhead of establishing a new connection every time a script needs to talk to a database, resulting in a faster web application.

另请注意:

If you wish to use persistent connections, you must set PDO::ATTR_PERSISTENT in the array of driver options passed to the PDO constructor. If setting this attribute with PDO::setAttribute() after instantiation of the object, the driver will not use persistent connections.

所以:

$PDOconnection = new PDO(
    "mysql:host=$servername;dbname=$dbname;charset=utf8"
    , $sql_username
    , $sql_password
    , array(
        PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
        PDO::ATTR_EMULATE_PREPARES => false,
        PDO::ATTR_PERSISTENT => true,
    )
);

关于php - SELECT LAST_INSERT_ID() 间歇性返回 0,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46743899/

相关文章:

php - 在php中跨类共享对象数组

Mysql选择最大值与阈值

php - 存储过程返回空结果

php - preg_split()—管道字符问题

php - 选择计数 (`id` )FROM `table` WHERE merk LIKE '%$searchq%'

mysql - MySQL 上的更新触发器不起作用

php - 截断文本并添加省略号 PHP SQL

PHP MYSQL 相同的数字,相同的类型,不同的结果

php - 变量 users_ids 与 user_ids 的正确名称

mysql - 将 MySQL 迁移到 SQL Server - 外键给出了一个不清楚的错误(对我来说)