![](/img/trans.png)
[英]PHP Warning: print_r and debug_backtrace when passing a mysqli connection
[英]PHP print_r clears status from a mysqli connection object?
我有一個MySQL表,其中需要三列,每個列在表中是唯一的,分別是userName,userEmail和userUID。 對於這些列中的每列,都使用UNIQUE設置了該表。 為了防止出現競爭情況,我嘗試插入一個新用戶,然后選擇“重復輸入”錯誤,分析錯誤消息以確定哪一列出了問題,然后向用戶詢問新信息。 我正在嘗試調試此代碼,並在對重復的列名稱進行任何測試之前,放置了print_r($dbConn, true)
以捕獲INSERT語句的結果。 這使事情變得很errno
,因為它似乎消除了mysqli連接對象中的errno
和error
值。 以下是說明問題的樣本:
<?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
對象的errno
和error
屬性設置為零。 這導致我的代碼無法找到1062錯誤。
如果我將print_r
行注釋掉並復制INSERT#2
行,那么它將兩次打印出1062錯誤消息。
如果我復制了print_r
行,那么我看到第二個打印出errno -> 0
, error
為空。 我注意到的是,第二個顯示連接stat
中的“ Questions
計數增加了一個。 所以我的想法是$dbConn
的print_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.