我正在尝试准备一个mysqli查询,但它在没有任何错误的情况下无声地失败。
$db_hostname = "test.com";
$db_database = "dbname";
$db_username = "db_user";
$db_password = "password";
$db = new mysqli($db_hostname,$db_username,$db_password,$db_database);
$q = "INSERT INTO Members (`wp_users_ID`,`MemberID`,`Status`,`MiddleName`,`Nickname`,`Prefix`,`Suffix`,`HomeAddress`,`City`,`State`,`Zip`,`ExtendedZip`,`BadAddress`,`SpouseFirstName`,`SpouseMiddleName`,`HomePhone`,`CellPhone`,`WorkPhone`,`WorkPhoneExt`,`OfficePhone`,`OfficePhoneExt`,`Pager`,`Fax`,`Company`,`CompanyType`,`OfficeAddress`,`OfficeAddress2`,`OfficeCity`,`OfficeState`,`OfficeZip`,`OTYPECO`,`OSTAG`,`UPCODE`,`Region`,`Department`,`Classification`,`Retired`,`Industry`,`Comments`,`Officer`,`OfficerType`,`OfficerTitle`,`OUNIT`,`ReceiveEMagazine`,`CD`,`SD`,`AD`,`isOrganization`,`DEL`,`Dues`,`DataSource`) VALUES ((?),(?),(?),(?),(?),(?),(?),(?),(?),(?),(?),(?),(?),(?),(?),(?),(?),(?),(?),(?),(?),(?),(?),(?),(?),(?),(?),(?),(?),(?),(?),(?),(?),(?),(?),(?),(?),(?),(?),(?),(?),(?),(?),(?),(?),(?),(?),(?),(?),(?),(?));";
$stmt = $db->prepare($q);
if ( false === $stmt ) {
echo "<pre>";
print_r( $db );
echo "</pre>";
mysqli_report(MYSQLI_REPORT_ALL);
echo mysqli_error();
}
实际显示任何内容的唯一部分是print_r($ db):
mysqli Object
(
[affected_rows] => -1
[client_info] => 5.1.73
[client_version] => 50173
[connect_errno] => 0
[connect_error] =>
[errno] => 0
[error] =>
[error_list] => Array
(
)
[field_count] => 1
[host_info] => dbhost.com via TCP/IP
[info] =>
[insert_id] => 919910
[server_info] => 5.1.73-log
[server_version] => 50173
[stat] => Uptime: 1924325 Threads: 8 Questions: 642600129 Slow queries: 28158 Opens: 24168750 Flush tables: 1 Open tables: 403 Queries per second avg: 333.935
[sqlstate] => 00000
[protocol_version] => 10
[thread_id] => 9939810
[warning_count] => 0
)
有没有人看到会导致这种情况的任何事情?没有任何错误,很难看出有什么问题......我尝试将生成的查询直接复制并粘贴到phpmyadmin中,并且运行得很好(手动用测试值替换问号后)。
谢谢!
更新
看来,自从将 mysqli_report(MYSQLI_REPORT_ALL); 添加到页面顶部后,插入查询的查询现在失败了,但仍然没有给出错误。这个执行失败:
echo "1";
$idDataSources = "";
echo "2";
$q = "SELECT idDataSources FROM DataSources WHERE `description`=(?);";
echo "3";
$stmt = $db->prepare($q);
echo "4";
$stmt->bind_param('s',$description);
echo "5";
$description = "File - 01/10/2015";
echo "6";
$stmt->execute() or die( mysqli_stmt_error( $stmt ) );
echo "7";
$stmt->bind_result($idDataSources);
echo "8";
$stmt->fetch();
echo "9";
unset($params);
输出:
123456
它到$ stmt-&gt; execute()并失败。我再次尝试输出错误,但没有任何显示。这真是令人费解。我想知道我是否应该恢复旧的mysql(非面向对象)方法......它是不安全的,但至少它工作一致并在出现问题时显示错误。
更新2
好吧,我只是用mysql(非面向对象)而不是mysqli重写了整个脚本...就像一个梦想。我希望我可以切换到更新的标准,但是随机故障和这样的错误报告很差,这肯定很难。我会更好地保持&#34;更好的&#34;版本,直到我能弄清楚它失败的原因。
更新3
我注意到mysqli的一个有趣的行为。在同一代码的其他地方,我有两个查询依次运行STMT。这偶尔会失败。失败并不一致,因为我可以提交50次相同的数据,而且可能会失败20次......数据相同,功能相同。
为了确定脚本错误输出的确切位置,我在两个查询中的每个语句之间放入了echo命令,只是吐出一个数字来查看计数停止的位置 - 结果是使用不相关的命令,它将STMT放慢到足以使其始终如一地工作。这让我想知道STMT连接是否未正确关闭。
$q = "";
$stmt = $this->db->prepare( "SELECT ID FROM Members WHERE MemberID='5' LIMIT 1;" );
$stmt->execute();
$stmt->store_result();
if ( $stmt->num_rows > 0 ) {
$q = "UPDATE Members SET Name='Test' WHERE MemberID=(?) LIMIT 1;";
}
$stmt->close();
// here if we continue, it has a chance of erroring out. However,
// if we run just the following command instead, everything works perfect.
//
// mysql_query( "UPDATE Members SET Name='Test' WHERE MemberID='5' LIMIT 1;" );
if ( $q != "" ) {
$stmt = $this->db->prepare($q);
$stmt->bind_param('i',$params['ID']);
$params['ID'] = 5;
$stmt->execute();
$stmt->close();
unset($params);
}
有人可以解释这种行为吗?它似乎不应该是冲突的,因为我在开始一个新查询之前使用close()命令,并且它在某些时候工作......看起来很奇怪。
答案 0 :(得分:8)
以下是来自php.net的一个稍微改编的示例脚本,其中包含错误处理:
<?php
$mysqli = new mysqli("example.com", "user", "password", "database");
if ($mysqli->connect_errno) {
echo "Failed to connect to MySQL: (" . $mysqli->connect_errno . ") " . $mysqli->connect_error;
}
/* Prepared statement, stage 1: prepare */
if (!($stmt = $mysqli->prepare("SELECT idDataSources FROM DataSources WHERE `description`=(?)"))) {
echo "Prepare failed: (" . $mysqli->errno . ") " . $mysqli->error;
}
/* Prepared statement, stage 2: bind and execute */
$description = "File - 01/10/2015";
if (!$stmt->bind_param('s', $description)) {
echo "Binding parameters failed: (" . $stmt->errno . ") " . $stmt->error;
}
if (!$stmt->execute()) {
echo "Execute failed: (" . $stmt->errno . ") " . $stmt->error;
}
/* explicit close recommended */
$stmt->close();
?>
请注意,$ mysqli 或 $ stmt可以保存错误说明。
答案 1 :(得分:0)
我有同样的问题。问题是我正在使用多个准备好的语句重新使用相同的mysqli连接。 在每个execute语句之后,我确定要包括显式的close命令:
$stmt->close();
这阻止了错误消息的显示,然后我可以在$mysqli->error
中看到错误消息。
答案 2 :(得分:-1)
mysqli_error()不是函数,除非你已定义它。
试试这个,它应该告诉你错误的来源。
echo $db::$error;
答案 3 :(得分:-1)
在你的初始帖子中;
$q = "INSERT INTO Members (`wp_users_ID`,`MemberID`,`Status`,`MiddleName`,`Nickname`,`Prefix`,`Suffix`,`HomeAddress`,`City`,`State`,`Zip`,`ExtendedZip`,`BadAddress`,`SpouseFirstName`,`SpouseMiddleName`,`HomePhone`,`CellPhone`,`WorkPhone`,`WorkPhoneExt`,`OfficePhone`,`OfficePhoneExt`,`Pager`,`Fax`,`Company`,`CompanyType`,`OfficeAddress`,`OfficeAddress2`,`OfficeCity`,`OfficeState`,`OfficeZip`,`OTYPECO`,`OSTAG`,`UPCODE`,`Region`,`Department`,`Classification`,`Retired`,`Industry`,`Comments`,`Officer`,`OfficerType`,`OfficerTitle`,`OUNIT`,`ReceiveEMagazine`,`CD`,`SD`,`AD`,`isOrganization`,`DEL`,`Dues`,`DataSource`) VALUES ((?),(?),(?),(?),(?),(?),(?),(?),(?),(?),(?),(?),(?),(?),(?),(?),(?),(?),(?),(?),(?),(?),(?),(?),(?),(?),(?),(?),(?),(?),(?),(?),(?),(?),(?),(?),(?),(?),(?),(?),(?),(?),(?),(?),(?),(?),(?),(?),(?),(?),(?));";
我会改变它;
$q = "INSERT INTO Members (`wp_users_ID`,`MemberID`,`Status`,`MiddleName`,`Nickname`,`Prefix`,`Suffix`,`HomeAddress`,`City`,`State`,`Zip`,`ExtendedZip`,`BadAddress`,`SpouseFirstName`,`SpouseMiddleName`,`HomePhone`,`CellPhone`,`WorkPhone`,`WorkPhoneExt`,`OfficePhone`,`OfficePhoneExt`,`Pager`,`Fax`,`Company`,`CompanyType`,`OfficeAddress`,`OfficeAddress2`,`OfficeCity`,`OfficeState`,`OfficeZip`,`OTYPECO`,`OSTAG`,`UPCODE`,`Region`,`Department`,`Classification`,`Retired`,`Industry`,`Comments`,`Officer`,`OfficerType`,`OfficerTitle`,`OUNIT`,`ReceiveEMagazine`,`CD`,`SD`,`AD`,`isOrganization`,`DEL`,`Dues`,`DataSource`) VALUES (?, ?, ..., ?, ?)";
我删除了MySQL查询的双引号中的一个分号。我也从问号周围删除了括号。当然,值中的省略号(...)也是如此,所以我不必输入所有问号(你应该把它们放回代码中)。