问题
What is a decent way to handle PDO error when using try catch block?
Currently I have something like this:
BlogModel.php
class BlogModel extends Model {
public function save($id, $value) {
$stmt = $this->getDb()->prepare('UPDATE setting SET name = :name WHERE id = :id');
$stmt->bindParam(':id', $id);
$stmt->bindParam(':name', $values);
return ($stmt->execute() !== false) ? $id : false;
}
}
So, in the controller BlogController.php, I would do something like this:
<?php
class Blog extends Controller {
public function comments()
{
$data = array();
$model = new BlogModel;
if ($model->save(2,'test')) {
$data['result']['message'] = 'Settings saved';
$data['result']['status'] = 'success';
} else {
$data['result']['message'] = 'Could not save the settings';
$data['result']['status'] = 'error';
}
$view = new View("view.php", $data)
$view->render();
}
}
?>
This is the way I handle PDO error using if
conditions. What is the decent way to translate this into try catch block? I don't want to code the variables ($data['result']['message']
$data['result']['status']
) all the time.
Is possible to add "throw exception" in the catch block somehow?
If there is a lot of try catch blocks in the controller, it going to look messy.. right?
回答1:
None of the answers here are wrong. But actually all three combined are the real answer. You should definitely set
$this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
as said by Cerad.
From now on every single issue about anything regarding database is thrown via exception of type PDOException
. You just don't have to throw your own Exception
as said by ladar because it's useless. Just take the ladar code and convert it into
...
$data = array();
$model = new BlogModel;
try{
$model->save(2,'test');
$data['result']['message'] = 'Settings saved';
$data['result']['status'] = 'success';
}catch(PDOException $e){
$data['result']['message'] = 'Could not save the settings';
$data['result']['status'] = 'error';
}
And do NOT throw anything by yourself.
Then a very nice way for debugging PDO queries is using the catch script linked by Basic that you can find here once again.
Combining this things togheter you'll have a flexible, clean and easy-debug way to catch all the errors that could come.
回答2:
What about:
class BlogModel extends Model {
public function save($id, $value) {
...
if (!$stmt->execute()) {
throw new Exception($stmt->errorInfo());
}
return $id;
And then
...
$data = array();
$model = new BlogModel;
try{
$model->save(2,'test');
$data['result']['message'] = 'Settings saved';
$data['result']['status'] = 'success';
}catch(Exception $e){
$data['result']['message'] = 'Could not save the settings';
$data['result']['status'] = 'error';
}
回答3:
Have you considered letting PDO itself throw exceptions instead of errors?
$this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
Now you can eliminate checking PDO errors which can significantly reduce code. You can add some try/catch block to catch exceptions that can be recovered from such as constraint violations.
For the rest just use a Try/Catch somewhere high up in your front end controller to catch the truly exceptional exceptions.
The only difference in my approach is that in BlogModel you just:
$stmt->execute();
No checking or anything else. Just let PDO throw an exception if the insert fails. Then you would use the try/catch in your controller as shown by ladar
Or in my case, if I was pretty sure the insert would never fail then I'd just use a generic try/catch block up in my front controller and not spend time trying to handle each possible exception manually.
来源:https://stackoverflow.com/questions/9252276/how-to-use-try-catch-block-for-pdo