Php 如何在PDO包装器中返回execute的值
下面是我的PDO包装。我希望能够使用Php 如何在PDO包装器中返回execute的值,php,pdo,return,prepared-statement,Php,Pdo,Return,Prepared Statement,下面是我的PDO包装。我希望能够使用run方法,但是,我希望能够检查执行是否成功,例如: if($sth->execute()) { ... } 但是,正如您在包装器中看到的,run命令只返回prepare语句,实现这一点的最有效方法是什么 因为在成功时返回true/false,而当前的run方法在失败时返回PDOStatement。我建议检查prepare和execute是否为false,并在成功时返回PDO语句,否则返回false,就像PDO::prepare和PDO::query一样
run
方法,但是,我希望能够检查执行是否成功,例如:
if($sth->execute())
{
...
}
但是,正如您在包装器中看到的,run命令只返回prepare
语句,实现这一点的最有效方法是什么
因为在成功时返回true/false,而当前的run
方法在失败时返回PDOStatement
。我建议检查prepare
和execute
是否为false,并在成功时返回PDO语句
,否则返回false,就像PDO::prepare
和PDO::query
一样
功能示例
另一种方法是将最后一个执行值存储在属性中,以便以后检索 例子
为了解决以下关于使用异常处理确定
PDO::execute
方法何时在Database::run
方法中特别失败的问题的最佳实践注释
请记住,它们不是对的或错的,“它们只是编写代码的推荐方法。”指的是在专业应用程序开发中通常首选的编程方法。始终使用最适合您、您为之开发的环境和您的应用程序需求的工具
一般来说,StackOverlow不是讨论或评估作者的申请的合适场所
最佳做法。这些类型的讨论或评论应该保留给其他人。堆栈溢出是
旨在或提供一种可行的替代方法来实现用户的要求。不推断用户提出了错误的问题
要使用异常,您需要启用PDO::ERRMODE\u异常
(请参见下面的数据库
类)
将try/catch
与PDO包装器方法一起使用的问题是,PDO只会抛出一个异常对象PDOException
,这无法让您确定哪个PDO方法调用特别失败。让你去读手术室,去确定原因
一种简单的方法是检查引起异常的函数名的PDOException::trace
功能示例(PHP 5.6+):
请参见by上的答案,以了解对PDOException
处理
上述方法防止您仅处理Database::run
方法中的特定异常类型,要求您使用throw$e代码>在您的条件之后,当异常意外时。
为了解决这个问题,另一种方法是创建自定义异常类。您可以通过扩展基本的PDOException
类来实现这一点,使其与其他异常处理方法兼容或捕获其中的任何一种
为了捕获任何run
特定异常,可以使用空接口,然后在扩展的PDOException
类上实现该接口
interface DatabaseRunException{}
然后为要处理的每个特定PDO方法创建一个新的异常类,该类实现了DatabaseRunException
接口
class PDOPrepareException extends PDOException implements DatabaseRunException{}
class PDOExecuteException extends PDOException implements DatabaseRunException{}
class PDOQueryException extends PDOException implements DatabaseRunException{}
要使用自定义异常来确定哪个PDO方法失败,您需要在数据库::run()
方法中处理PDO异常
,并抛出其中一个自定义异常。
为了简洁起见,我删除了某些部分,注释掉了可能会改变当前配置的内容,对PHP5.6+进行了一些最佳实践和优化更改
class Database
{
private const OPTIONS = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
// PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_OBJ,
// PDO::ATTR_EMULATE_PREPARES => false
];
//...
protected function __construct()
{
$this->pdo = new PDO($dsn, self::user, self::password, self::OPTIONS);
}
public static function instance()
{
if (null === self::$instance) {
self::$instance = new self;
}
return self::$instance;
}
public function __call($method, $args)
{
//always ensure the desired method is callable!
if (is_callable([$this->pdo, $method])) {
//php 5.6+ variadic optimization (aka splat operator)
return $this->pdo->$method(...$args);
//php <= 5.5
//return call_user_func_array(array($this->pdo, $method), $args);
}
throw new \BadMethodCallException(sprintf('Unknown method PDO::%s called!', $method));
}
public function run($sql, $args = [])
{
if (!$args) {
try {
return $this->query($sql);
} catch(\PDOException $e) {
throw new \PDOQueryException($e->getMessage(), (int) $e->getCode(), $e);
}
}
try {
$stmt = $this->prepare($sql);
} catch(\PDOException $e) {
throw new \PDOPrepareException($e->getMessage(), (int) $e->getCode(), $e);
}
try {
$stmt->execute($args);
return $stmt;
} catch(\PDOException $e) {
throw new \PDOExecuteException($e->getMessage(), (int) $e->getCode(), $e);
}
throw new \LogicException('Unknown error occurred');
}
}
在PHP7.1+中,您可以捕获多个异常
try {
$db = Database::instance();
$db->run('SELECT ?', ['foo', 'bar']);
} catch(\PDOQueryException $e) {
//Handle the query exception
throw $e;
} catch(\PDOPrepareException $e) {
//Handle the prepare exception
throw $e;
} catch(\PDOExecuteException $e) {
echo 'PDO::execute() failed';
//Handle the execute exception
throw $e;
}
在PHPSince中,返回true/false,当前的run
方法在成功时返回PDOStatement
,在失败时返回false。我建议检查prepare
和execute
是否为false,并在成功时返回PDO语句
,否则返回false,就像PDO::prepare
和PDO::query
一样
功能示例
另一种方法是将最后一个执行值存储在属性中,以便以后检索
例子
为了解决以下关于使用异常处理确定PDO::execute
方法何时在Database::run
方法中特别失败的问题的最佳实践注释
请记住,它们不是对的或错的,“它们只是编写代码的推荐方法。”指的是在专业应用程序开发中通常首选的编程方法。始终使用最适合您、您为之开发的环境和您的应用程序需求的工具
一般来说,StackOverlow不是讨论或评估作者的申请的合适场所
最佳做法。这些类型的讨论或评论应该保留给其他人。堆栈溢出是
旨在或提供一种可行的替代方法来实现用户的要求。不推断用户提出了错误的问题
要使用异常,您需要启用PDO::ERRMODE\u异常
(请参见下面的数据库
类)
将try/catch
与PDO包装器方法一起使用的问题是,PDO只会抛出一个异常对象PDOException
,这无法让您确定哪个PDO方法调用特别失败。让你去读手术室,去确定原因
一种简单的方法是检查引起异常的函数名的PDOException::trace
功能示例(PHP 5.6+):
关于p的更一般化方法,请参见by上的答案
try {
$db = Database::instance();
var_dump($db->run('SELECT ?', ['foo', 'bar'])->fetch());
} catch(\PDOException $e) {
if ('execute' === $e->getTrace()[0]['function']) {
echo 'PDO::execute() failed';
//Handle the execute exception
}
throw $e;
}
interface DatabaseRunException{}
class PDOPrepareException extends PDOException implements DatabaseRunException{}
class PDOExecuteException extends PDOException implements DatabaseRunException{}
class PDOQueryException extends PDOException implements DatabaseRunException{}
class Database
{
private const OPTIONS = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
// PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_OBJ,
// PDO::ATTR_EMULATE_PREPARES => false
];
//...
protected function __construct()
{
$this->pdo = new PDO($dsn, self::user, self::password, self::OPTIONS);
}
public static function instance()
{
if (null === self::$instance) {
self::$instance = new self;
}
return self::$instance;
}
public function __call($method, $args)
{
//always ensure the desired method is callable!
if (is_callable([$this->pdo, $method])) {
//php 5.6+ variadic optimization (aka splat operator)
return $this->pdo->$method(...$args);
//php <= 5.5
//return call_user_func_array(array($this->pdo, $method), $args);
}
throw new \BadMethodCallException(sprintf('Unknown method PDO::%s called!', $method));
}
public function run($sql, $args = [])
{
if (!$args) {
try {
return $this->query($sql);
} catch(\PDOException $e) {
throw new \PDOQueryException($e->getMessage(), (int) $e->getCode(), $e);
}
}
try {
$stmt = $this->prepare($sql);
} catch(\PDOException $e) {
throw new \PDOPrepareException($e->getMessage(), (int) $e->getCode(), $e);
}
try {
$stmt->execute($args);
return $stmt;
} catch(\PDOException $e) {
throw new \PDOExecuteException($e->getMessage(), (int) $e->getCode(), $e);
}
throw new \LogicException('Unknown error occurred');
}
}
try {
$db = Database::instance();
$db->run('SELECT ?', ['foo', 'bar']);
} catch(\PDOExecuteException $e) {
echo 'PDO::execute() failed';
//Handle the execute exception
throw $e;
}
try {
$db = Database::instance();
$db->run('SELECT ?', ['foo', 'bar']);
} catch(\PDOQueryException $e) {
//Handle the query exception
throw $e;
} catch(\PDOPrepareException $e) {
//Handle the prepare exception
throw $e;
} catch(\PDOExecuteException $e) {
echo 'PDO::execute() failed';
//Handle the execute exception
throw $e;
}
try {
$db = Database::instance();
$db->run('SELECT ?', ['foo', 'bar']);
} catch(\DatabaseRunException $e) {
if ($e instanceof \PDOQueryException) {
//Handle the query exception
} elseif ($e instanceof \PDOPrepareException) {
//Handle the prepare exception
} elseif ($e instanceof \PDOExecuteException) {
echo 'PDO::execute() failed';
//Handle the execute exception
}
throw $e;
}
try {
throw new \Exception('FooBar');
$foo = 'foo';
} catch(\Exception $e) {
var_dump(isset($foo)); //false
}
var_dump(isset($foo)); //false