gpt4 book ai didi

PHP print_r 清除 mysqli 连接对象的状态?

转载 作者:行者123 更新时间:2023-11-29 04:20:43 25 4
gpt4 key购买 nike

我有一个 MySQL 表,其中我需要三列,每列在表中都是唯一的,userName、userEmail 和 userUID。该表为这些列中的每一列设置了 UNIQUE。为了防止竞争条件,我尝试单次插入新用户,然后发现“重复输入”错误,解析错误消息以确定哪一列出现问题,然后向用户询问新信息。我试图调试此代码并放置 print_r($dbConn, true) 以在对重复的列名进行任何测试之前捕获 INSERT 语句的结果。这破坏了很多事情,因为它似乎消除了 mysqli 连接对象中的 errnoerror 值。这是一个说明问题的缩减示例:

<?php
error_reporting(E_ALL);
echo 'PHP Version: ' . phpversion() . PHP_EOL;
$dbConn = @new mysqli('127.0.0.1', 'userX', 'passwordX', 'databaseX');
$dbConn->query('CREATE TABLE IF NOT EXISTS print_r_test (' .
'username VARCHAR(64), UNIQUE (username)');
echo 'Created print_r_test table.' . PHP_EOL;
$dbConn->query('TRUNCATE TABLE print_r_test');
echo 'Truncated print_r_test table.' . PHP_EOL;
$dbConn->query('INSERT INTO print_r_test (username) VALUES (\'testuser\')');
echo '' . 'INSERT#1: ' . $dbConn->errno . ': ' . $dbConn->error . PHP_EOL;
// This next one fails with duplicate entry 'testuser' for 'username'
$dbConn->query('INSERT INTO print_r_test (username) VALUES (\'testuser\')');
// echo '$dbConn: ' . print_r($dbConn, true) . PHP_EOL;
echo '' . 'INSERT#2: ' . $dbConn->errno . ': ' . $dbConn->error . PHP_EOL;
?>

请注意,第 14 行已被注释掉。

如果你按原样运行它(在更改 userX、passwordX 和 databaseX 之后)它会按预期工作:

H:>php print_r_test2.php
PHP Version: 5.4.10
Created print_r_test table.
Truncated print_r_test table.
INSERT#1: 0:
INSERT#2: 1062: Duplicate entry 'testuser' for key 'username'

第 10 行的第一个 INSERT 起作用并报告 errno=0。第二次插入失败,errno=1-62 和一条指示重复用户名的消息。

现在,删除第 14 行的//,以便将 $dbConn 内容打印到输出中,我得到:

H:>php print_r_test2.php
PHP Version: 5.4.10
Created print_r_test table.
Truncated print_r_test table.
INSERT#1: 0:
$dbConn: mysqli Object
(
[affected_rows] => -1
[client_info] => mysqlnd 5.0.10 - 20111026 - $Id: b0b3b15c693b7f6aeb3aa66b646fee339f175e39 $
[client_version] => 50010
[connect_errno] => 0
[connect_error] =>
[errno] => 1062
[error] => Duplicate entry 'testuser' for key 'username'
[error_list] => Array
(
[0] => Array
(
[errno] => 1062
[sqlstate] => 23000
[error] => Duplicate entry 'testuser' for key 'username'
)

)

[field_count] => 0
[host_info] => 127.0.0.1 via TCP/IP
[info] =>
[insert_id] => 0
[server_info] => 5.6.19
[server_version] => 50619
[stat] => Uptime: 26920 Threads: 2 Questions: 97 Slow queries: 0 Opens: 85 Flush tables: 1 Open tables: 61 Queries per second avg: 0.003
[sqlstate] => 00000
[protocol_version] => 10
[thread_id] => 20
[warning_count] => 0
)

INSERT#2: 0:

第二个 INSERT 报告 0 表示正常,但显然失败了。

这里似乎发生的是 print_r($dbConn, true) 导致了 errnoerror 属性>$dbConn 连接对象被设置为零。这导致我的代码无法找到 1062 错误。

如果我将 print_r 行注释掉并复制 INSERT#2 行,那么它会打印两次 1062 错误消息。

如果我复制 print_r 行,我会看到第二行打印出 errno -> 0 并且 error 为空。我注意到第二个显示连接 stat 中的 Questions 计数增加了 1。所以我的想法是 $dbConnprint_r 导致对 MySQL 的额外查询,该查询成功并返回 0 表示 OK,并清除其中以前的值。

这似乎不是很有帮助,或者我在这里遗漏了一些非常明显的东西?

谢谢。

在下面@Phil 的评论之后,我的问题是我做错了什么(如果有的话)破坏了 $dbConn< 中的 errnoerror 返回 对象?

print_r无关。将最后一行替换为:

echo '' . 'INSERT#2: ' . $dbConn->errno . ': ' . $dbConn->error . PHP_EOL . $dbConn->stat . PHP_EOL;
echo '' . 'INSERT#2: ' . $dbConn->errno . ': ' . $dbConn->error . PHP_EOL . $dbConn->stat . PHP_EOL;

导致输出为:

INSERT#2: 1062: Duplicate entry 'testuser' for key 'username'
Uptime: 29364 Threads: 2 Questions: 136 Slow queries: 0 Opens: 91 Flush tables: 1 Open tables: 61 Queries per second avg: 0.004
INSERT#2: 0:
Uptime: 29364 Threads: 2 Questions: 137 Slow queries: 0 Opens: 91 Flush tables: 1 Open tables: 61 Queries per second avg: 0.004

这样做:

echo '' . 'INSERT#2: ' . $dbConn->errno . ': ' . $dbConn->error . PHP_EOL;
echo '' . 'INSERT#2: ' . $dbConn->errno . ': ' . $dbConn->error . PHP_EOL;

结果:

INSERT#2: 1062: Duplicate entry 'testuser' for key 'username'
INSERT#2: 1062: Duplicate entry 'testuser' for key 'username'

如果读取连接对象不是幂等操作,那么这对我来说就像是一个陷阱,也是问题和挫折的根源。所以我的问题是,还是我做错了什么或遗漏了什么,或者这是 mysqli 的一些奇怪功能吗?

最佳答案

如果您查看 documentation for mysqli->stat() ,它是一个在服务器上执行命令“mysqladmin status”并返回服务器为此返回的任何内容的函数。如果你看the documentation for mysqli->errno您会看到它“返回最近函数调用的错误代码”。

那么会发生什么?

您执行查询,然后读取错误代码。然后执行另一个没有失败的命令,并读取该命令的错误代码。这正是您应该期望发生的事情。


如果在调用 stat() 后需要 errno 或 error 的值,没有什么可以阻止您在调用 stat() 之前将这些值存储在变量中:

$a = $dbConn->errno;
$b = $dbConn->error;
$c = $dbConn->stat();

echo $a . $b . $c;

关于PHP print_r 清除 mysqli 连接对象的状态?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25152653/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com