繁体   English   中英

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

[英]PHP print_r clears status from a mysqli connection object?

我有一个MySQL表,其中需要三列,每个列在表中是唯一的,分别是userName,userEmail和userUID。 对于这些列中的每列,都使用UNIQUE设置了该表。 为了防止出现竞争情况,我尝试插入一个新用户,然后选择“重复输入”错误,分析错误消息以确定哪一列出了问题,然后向用户询问新信息。 我正在尝试调试此代码,并在对重复的列名称进行任何测试之前,放置了print_r($dbConn, true)以捕获INSERT语句的结果。 这使事情变得很errno ,因为它似乎消除了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报告OK表示0,但显然失败。

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

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

如果我复制了print_r行,那么我看到第二个打印出errno -> 0error为空。 我注意到的是,第二个显示连接stat中的“ Questions计数增加了一个。 所以我的想法是$dbConnprint_r导致对MySQL的附加查询,该查询成功并为OK返回0,并删除那里的先前值。

这似乎不是很有帮助,还是我在这里想念的东西明显地令人眼花obvious乱?

谢谢。

在下面$dbConn的评论之后,我的问题是我在做错什么(如果有的话),从而打破了errno并在$dbConn对象中返回了error

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的某些奇怪功能?

如果查看mysqli->stat()文档 ,则此函数可在服务器上执行命令“ mysqladmin status”并返回服务器为此返回的内容。 如果查看mysqli->errno的文档,您会看到它“返回最近函数调用的错误代码”。

那会怎样呢?

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


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

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

echo $a . $b . $c;

这是一个有趣的问题,在浏览了文档后,我找到了答案: http : //php.net/manual/en/class.mysqli.php

这些是对象属性:errno,错误。 因此访问它们不会影响对象的状态。

另一方面,stat()是对对象的方法调用。 这意味着errno和error将被更新以反映该调用是成功还是失败。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM