簡體   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