Php 模拟PDO获取失败的情况
根据php文档,PDO方法在未找到任何记录时返回值Php 模拟PDO获取失败的情况,php,mysql,pdo,exception-handling,fetch,Php,Mysql,Pdo,Exception Handling,Fetch,根据php文档,PDO方法在未找到任何记录时返回值FALSE,在失败时返回值(例如,当数据库访问出现问题时) 假设我将PHP错误报告系统设置为在失败时抛出异常: PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION 我需要一个案例,即fetch()方法将抛出异常的情况。为什么?因为我想检查,100%确保fetch()在失败时抛出异常,而不是在失败时返回FALSE 如果是这样的话,那么我确实会考虑 > FETCH()/中返回的错误/代码>,因为在DB表中没
FALSE
,在失败时返回值(例如,当数据库访问出现问题时)
假设我将PHP错误报告系统设置为在失败时抛出异常:
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
我需要一个案例,即fetch()
方法将抛出异常的情况。为什么?因为我想检查,100%确保fetch()
在失败时抛出异常,而不是在失败时返回FALSE
如果是这样的话,那么我确实会考虑<代码> > FETCH()/<代码>中返回的<代码>错误/代码>,因为在DB表中没有找到任何记录。
因此,我的问题是:您知道一种方法来模拟fetch()
方法的失败情况吗?
多谢各位
p.S.:我的问题的答案将帮助我找到其他问题的答案:
编辑1: 我还准备了一个示例,演示如何处理异常。这是一个简单的sql查询,从
users
表中获取用户:
<?php
// Activate error reporting.
error_reporting(E_ALL);
ini_set('display_errors', 1);
try {
// Create a PDO instance as db connection to a MySQL db.
$connection = new PDO(
'mysql:host=localhost;port=3306;dbname=mydb;charset=utf8'
, 'myuser'
, 'mypass'
, array(
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_EMULATE_PREPARES => FALSE,
PDO::ATTR_PERSISTENT => TRUE
)
);
// Define the sql statement.
$sql = 'SELECT * FROM users WHERE name = :name';
/*
* Prepare and validate the sql statement.
*
* --------------------------------------------------------------------------------
* If the database server cannot successfully prepare the statement, PDO::prepare()
* returns FALSE or emits PDOException (depending on error handling settings).
* --------------------------------------------------------------------------------
*/
$statement = $connection->prepare($sql);
if (!$statement) {
throw new UnexpectedValueException('The sql statement could not be prepared!');
}
// Bind the input parameter to the prepared statement.
$bound = $statement->bindValue(':name', 'Sarah', PDO::PARAM_STR);
// Validate the binding of the input parameter.
if (!$bound) {
throw new UnexpectedValueException('An input parameter can not be bound!');
}
/*
* Execute the prepared statement.
*
* ------------------------------------------------------------------
* PDOStatement::execute returns TRUE on success or FALSE on failure.
* ------------------------------------------------------------------
*/
$executed = $statement->execute();
if (!$executed) {
throw new UnexpectedValueException('The prepared statement can not be executed!');
}
/*
* Fetch and validate the result set.
*
* =========================================================
* Note:
* =========================================================
* PDOStatement::fetch returns FALSE not only on failure,
* but ALSO when no record is found!
*
* Instead, PDOStatement::fetchAll returns FALSE on failure,
* but an empty array if no record is found. This is the
* natural, desired behaviour.
* =========================================================
*/
$resultset = $statement->fetch(PDO::FETCH_ASSOC);
if ($resultset === FALSE) {
throw new UnexpectedValueException('Fetching data failed!');
}
// Display the result set.
var_dump($resultset);
echo '<pre>' . print_r($resultset, TRUE) . '</pre>';
// Close connection.
$connection = NULL;
} catch (PDOException $exc) {
echo '<pre>' . print_r($exc, TRUE) . '</pre>';
exit();
} catch (Exception $exc) {
echo '<pre>' . print_r($exc, TRUE) . '</pre>';
exit();
}
以及下表中的值:
$sql = 'SELECT * FROM users WHERE name = :name';
$stmt = $connection->prepare($sql);
$stmt->bindValue(':name', 'Sarah');
$executed = $stmt->execute();
if (!$executed) {
throw new UnexpectedValueException('The prepared statement can not be executed!');
}
$result_set = fetch($stmt);
if ($result_set === false) {
throw new UnexpectedValueException('Fetching data failed!');
}
// handle result set
因此,该表如下所示:
<?php
// Activate error reporting.
error_reporting(E_ALL);
ini_set('display_errors', 1);
try {
// Create a PDO instance as db connection to a MySQL db.
$connection = new PDO(
'mysql:host=localhost;port=3306;dbname=tests;charset=utf8'
, 'root'
, 'root'
, array(
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_EMULATE_PREPARES => FALSE,
PDO::ATTR_PERSISTENT => TRUE
)
);
// Define the sql statement.
$sql = 'SELECT * FROM users WHERE name = :name';
/*
* Prepare the sql statement.
*
* --------------------------------------------------------------------------------
* If the database server cannot successfully prepare the statement, PDO::prepare()
* returns FALSE or emits PDOException (depending on error handling settings).
* --------------------------------------------------------------------------------
*/
$statement = $connection->prepare($sql);
// Validate the preparation of the sql statement.
if (!$statement) {
throw new UnexpectedValueException('The sql statement could not be prepared!');
}
// Bind the input parameter to the prepared statement.
$bound = $statement->bindValue(':name', 'Sarah', PDO::PARAM_STR);
// Validate the binding of the input parameter.
if (!$bound) {
throw new UnexpectedValueException('An input parameter can not be bound!');
}
/*
* Execute the prepared statement.
*
* ------------------------------------------------------------------
* PDOStatement::execute returns TRUE on success or FALSE on failure.
* ------------------------------------------------------------------
*/
$executed = $statement->execute();
// Validate the execution of the prepared statement.
if (!$executed) {
throw new UnexpectedValueException('The prepared statement can not be executed!');
}
// Fetch the result set.
$resultset = $statement->fetch(PDO::FETCH_KEY_PAIR);
// If no records found, define the result set as an empty array.
if ($resultset === FALSE) {
$resultset = [];
}
// Display the result set.
var_dump($resultset);
// Close connection.
$connection = NULL;
} catch (PDOException $exc) {
echo '<pre>' . print_r($exc->getMessage(), TRUE) . '</pre>';
exit();
} catch (Exception $exc) {
echo '<pre>' . print_r($exc->getMessage(), TRUE) . '</pre>';
exit();
}
除非循环需要PDO语句,否则可以在方法/函数中使用fetchAll来获得所需的结果。只需执行fetchAll而不是fetch,检查false,并根据需要返回。在这种情况下,您的查询应该确保只返回1行 像这样的东西
DROP TABLE IF EXISTS `users`;
CREATE TABLE `users` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(100) DEFAULT NULL,
`phone` varchar(100) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
请注意,fetchColumn也有类似的问题
以上内容将返回
- 查询失败时为false
- 如果找不到行,则获取空数组
- 如果找到,则获取相应的结果集
- 如果找不到fetchColumn,则为null
- fetchColumn的列值(如果找到)
INSERT INTO `users` (`id`, `name`, `phone`)
VALUES
(1,'Sarah','12345'),
(2,'John','67890');
您还可以做更多的工作来改进上述内容,但希望您能理解。使用
PDO::ATTR_ERRMODE=>PDO::ERRMODE_EXCEPTION
fetch在出现错误时始终会抛出异常。你可以在你的catch块中处理它们,它返回什么并不重要。因此,如果您没有捕获到异常,并且它返回false,那么您可以安全地假定它是由于一个空集引起的。这是处理PDO错误的一种非常有效的方法。要回答您的问题,有许多方法可以模拟错误。最基本的是不正确的查询语法。您还可以尝试绑定不存在的参数、绑定错误数量的参数等。使用此方案的时间越长,您将看到越多类型的错误/异常。它非常有效,因为每个错误都包含一条详细的消息来帮助您调试它。最后,我发现了一个案例,它允许我测试PDOStatement::fetch
是否确实会在失败时引发异常
信用:
文章提出了这样一种情况。它基于使用PDOStatement::fetchAll
和作为参数传递的PDO::FETCH_KEY_PAIR
常量
测试:
所以,我自己做了一个测试。但是我使用了PDOStatement::fetch
方法。根据定义,PDO::FETCH_KEY_PAIR
常量要求数据源表仅包含两列。在我的测试中,我定义了三个表列PDOStatement::fetch
已将此情况识别为失败,并引发异常:
SQLSTATE[HY000]:一般错误:PDO::FETCH_KEY_PAIR FETCH模式
要求结果集包含extactly 2列
结论:
如果未找到任何记录,则返回PDOStatement::fetch
。FALSE
确实会在失败时抛出异常。PDOStatement::fetch
- 相反,
如果找不到任何记录,则返回一个空数组PDOStatement::fetchAll
- 官方页面上没有记录
常量PDO::FETCH_KEY_PAIR
用于测试的代码: 插入值语法: 表值:
启用基于异常的错误报告手册中说:“此函数在成功时的返回值取决于获取类型。在所有情况下,失败时返回FALSE。”。当没有结果时,我希望它返回
NULL
。所以有两种不同的测试是可能的:if($result==FALSE)
测试失败,if(!isset($result))..
或if(is_null($result))
测试没有记录。谢谢,@teresko。我已经有了。但是,由于php.net说,失败时返回FALSE,我真的不知道是否在失败时引发异常,而不是FALSE。在这种情况下,处理异常是一种方法。试试看。它会起作用的。@MasivuyeCokile我终于找到了一个案例,它允许我模拟PDOStatement::fetch()
的失败情况。我贴出了答案。再次感谢您的评论!你的帖子没有回答这个问题,也没有回答之前的问题。我的帖子是回应他在上面问题中的评论。具体来说,他最后做的两个。@user2430012非常感谢您的回答!在<代码> FETCH()/代码>问题(以及我最后2个评论)中,我个人认为您的答案是符合条件的。@ USER 24012现在,基于我的问题的第三个版本:我倾向于99%考虑,在<代码> FET()的情况下,没有失败的情况。:-)我非常感谢你给我一个好答案!不客气。要添加,无论使用什么PDO::ATTR_ERRMOD,fetch()都不会引发异常。失败时它总是返回false。即使将stmt包装在try/catch块中,并在之后调用fetch(),它也会
$sql = 'SELECT * FROM users WHERE name = :name';
$stmt = $connection->prepare($sql);
$stmt->bindValue(':name', 'Sarah');
$executed = $stmt->execute();
if (!$executed) {
throw new UnexpectedValueException('The prepared statement can not be executed!');
}
$result_set = fetch($stmt);
if ($result_set === false) {
throw new UnexpectedValueException('Fetching data failed!');
}
// handle result set
<?php
// Activate error reporting.
error_reporting(E_ALL);
ini_set('display_errors', 1);
try {
// Create a PDO instance as db connection to a MySQL db.
$connection = new PDO(
'mysql:host=localhost;port=3306;dbname=tests;charset=utf8'
, 'root'
, 'root'
, array(
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_EMULATE_PREPARES => FALSE,
PDO::ATTR_PERSISTENT => TRUE
)
);
// Define the sql statement.
$sql = 'SELECT * FROM users WHERE name = :name';
/*
* Prepare the sql statement.
*
* --------------------------------------------------------------------------------
* If the database server cannot successfully prepare the statement, PDO::prepare()
* returns FALSE or emits PDOException (depending on error handling settings).
* --------------------------------------------------------------------------------
*/
$statement = $connection->prepare($sql);
// Validate the preparation of the sql statement.
if (!$statement) {
throw new UnexpectedValueException('The sql statement could not be prepared!');
}
// Bind the input parameter to the prepared statement.
$bound = $statement->bindValue(':name', 'Sarah', PDO::PARAM_STR);
// Validate the binding of the input parameter.
if (!$bound) {
throw new UnexpectedValueException('An input parameter can not be bound!');
}
/*
* Execute the prepared statement.
*
* ------------------------------------------------------------------
* PDOStatement::execute returns TRUE on success or FALSE on failure.
* ------------------------------------------------------------------
*/
$executed = $statement->execute();
// Validate the execution of the prepared statement.
if (!$executed) {
throw new UnexpectedValueException('The prepared statement can not be executed!');
}
// Fetch the result set.
$resultset = $statement->fetch(PDO::FETCH_KEY_PAIR);
// If no records found, define the result set as an empty array.
if ($resultset === FALSE) {
$resultset = [];
}
// Display the result set.
var_dump($resultset);
// Close connection.
$connection = NULL;
} catch (PDOException $exc) {
echo '<pre>' . print_r($exc->getMessage(), TRUE) . '</pre>';
exit();
} catch (Exception $exc) {
echo '<pre>' . print_r($exc->getMessage(), TRUE) . '</pre>';
exit();
}
DROP TABLE IF EXISTS `users`;
CREATE TABLE `users` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(100) DEFAULT NULL,
`phone` varchar(100) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
INSERT INTO `users` (`id`, `name`, `phone`)
VALUES
(1,'Sarah','12345'),
(2,'John','67890');
id name phone
-----------------
1 Sarah 12345
2 John 67890