Reputation: 1518
While learning PHP I've came across this dillema. For example I have this function to check if a client exists in the database.
public function is_client( int $client_id ) {
$query = "SELECT * FROM clients WHERE id='$client_id'";
$res = DB::run($query)->fetch();
if(empty($res)) {
return false;
}
return true;
}
I wanted to add try/catch functionality so I could catch the PDO errors, and this is how it looks after:
public function is_client( int $client_id ) {
try {
$query = "SELECT * FROM clients WHERE id='$client_id'";
$res = DB::run($query)->fetch();
if(empty($res)) {
return false;
}
return true;
}
catch(PDOException $e) {
return $e->getMessage();
}
}
But I was wondering, what should I put in the 'try block'? Only the queries? Should I return my values within the 'try block' or outside?
I've tried a little bit more on that so I ended up with the following:
public function is_client( int $client_id ) {
try {
$query = "SELECT * FROM clients WHERE id='$client_id'";
$res = DB::run($query)->fetch();
}
catch(PDOException $e) {
return $e->getMessage();
}
if(empty($res)) {
return false;
}
return true;
}
Can you please explain to me what are the differences between those examples and which is the correct way to do it?
UPDATE after people answers
After reading your answers I did this:
public function is_client( int $client_id ) {
$query = "SELECT * FROM clients WHERE id='$client_id'";
$res = DB::run($query)->fetch();
if(empty($res)) {
return false;
}
return true;
}// the function returns only boolean now
try {
if(is_client(11) === true) {
echo 'client';
}
else {
echo 'client does not exist';
}
}
catch(PDOException $e) {
echo $e->getMessage();
}
Upvotes: 1
Views: 33
Reputation: 1769
Put the try/catch block in the code that calls the function, not the function itself.
The try/catch block will watch for an exception to be thrown and, if an exception is thrown, break to the catch portion of the block. Specifically in this case that catch block is watching for an instance of PDOException
.
In the case of an PDOException
being thrown you'll most certainly not be getting any results back from the query. That being the case it makes more sense to return the exception from the function and skip returning the results that don't exist.
The normal preferred method for this is to set up the function to throw the PDOException
back to the code that calls the function and handle the exception in a try/catch block there. This makes sure that your function is consistently returning the same type of value.
Upvotes: 1
Reputation: 5857
In your first example:
public function is_client( int $client_id ) {
try {
$query = "SELECT * FROM clients WHERE id='$client_id'";
$res = DB::run($query)->fetch();
if(empty($res)) {
return false;
}
return true;
}
catch(PDOException $e) {
return $e->getMessage();
}
}
Imagine a PDO Exception is somehow thrown during your query (this would happen in the $res = DB::run($query)->fetch();
line), this would cause execution to jump directly to the catch
-Block and your is_client
function (which you'd normally expect to return a boolean) suddenly returns a string.
So, if you're using your is_client
function like this:
if (is_client(123))
{
echo "We have a valid client";
} else {
echo "Client Invalid!";
}
Would actually print the valid-statement since a non-empty string (your exception error message) evaluates to true.
The correct way would either be to not catch the exception in is_client
but rather later in your program flow (eg in the block where you're using is_client
) or to return a valid/expected value (or throw a new/custom exception) in your function, for example:
public function is_client( int $client_id ) {
try {
$query = "SELECT * FROM clients WHERE id='$client_id'";
$res = DB::run($query)->fetch();
if(empty($res)) {
return false;
}
return true;
}
catch(PDOException $e) {
// Somehow write a log file with the error message $e->getMessage()
return false; // Return false just to be save
}
}
Upvotes: 1
Reputation: 91
I prefer the second example. If DB::run($query)->fetch()
throws an exception, if(empty($res)) {
won't be called either way.
Upvotes: 0