1
\$\begingroup\$

I try to handle or catch possible errors with PHP/MySQL for security reasons and would like to know if I'm doing it right.

The first case, connection: I use it as a function and call it always when I need a database connection:

function pdo () {
  try {
    $pdo = new PDO('mysql:host=localhost;dbname=dbname', 'user', 'pw');
  }
  catch(PDOException $e) {
    header("Location: handle_error.php");
    exit;
  }
  return ($pdo);
}

The second case, a query: I am not sure how to handle it. I put all prepared statements in IF conditions but that's pretty awkward. And what about $stmt->execute? This could also fail or not? To handle this also in an if condition can really get confusing. I hope there is a better way to go.

if ($stmt = $pdo->prepare("SELECT a FROM b WHERE c = :c")) {
  $stmt->execute(array(':c' => $c));
  $result = $stmt->fetch();
  echo 'All fine.';
}
else {
  echo 'Now we have a problem.';
}

Later, I would like to report the errors properly so the admin can check what's going on.

\$\endgroup\$
  • \$\begingroup\$ As friendly advise, next time, try to give a bit more context, as your question was cumulating votes to close for lacking context. It is generally a good idea to provide reviewers real working code, rather than hypothetical/obfuscated code. \$\endgroup\$ – dfhwze Sep 3 '19 at 17:35
  • \$\begingroup\$ Thank you, I will try to pay attention. I edited the code to keep it short so you can quickly see what it is about. \$\endgroup\$ – Nino Sep 3 '19 at 18:02
  • \$\begingroup\$ @dfhwze what kind of context you expect? This code is neither hypotetical/obfuscated, the context is clear - it is going to be used in every PHP script the OP writes. \$\endgroup\$ – Your Common Sense Sep 3 '19 at 18:09
  • \$\begingroup\$ @YourCommonSense The error handling is clear, but the trivial example used redacts real working sql statements. This is generally considered off-topic on CR, even if the main point of focus is the error handling. We require a real use case, not general best practices. codereview.stackexchange.com/help/how-to-ask: hypothetical identifiers. \$\endgroup\$ – dfhwze Sep 3 '19 at 18:16
2
\$\begingroup\$

First of all, it's a good thing that you asked, only a few do care about handling errors.

Unfortunately, the way you choose is frowned upon, in both cases. Luckily, I've got a couple articles that cover your question in every possible detail:

Error handling

The idea here is that a module or a part of code should never treat errors by itself. This function should be delegated to the application level. Your database interaction code should only raise an error, which would be handled according to the site-wide configuration elsewhere.

So your goal with PDO is just to make it throw an error (in the form of Exception). As to how it will be handled should be defined elsewhere. It will make your error reporting uniform and both programmer- and user-friendly.

Connection

Another issue is a function.

I use it as a function and call it always when I need a database connection.

If you call it more than once, it will create many connections to the database server and this number is not infinite. A connection should be made only once. So in its current form this function is rather useless. Given you have to create a $pdo variable only once, an include file would serve as well.

So let's create it

$host = '127.0.0.1';
$db   = 'test';
$user = 'root';
$pass = '';
$charset = 'utf8mb4';

$options = [
    \PDO::ATTR_ERRMODE            => \PDO::ERRMODE_EXCEPTION,
    \PDO::ATTR_DEFAULT_FETCH_MODE => \PDO::FETCH_ASSOC,
    \PDO::ATTR_EMULATE_PREPARES   => false,
];
$dsn = "mysql:host=$host;dbname=$db;charset=$charset";
try {
     $pdo = new \PDO($dsn, $user, $pass, $options);
} catch (\PDOException $e) {
     throw new \PDOException($e->getMessage(), (int)$e->getCode());
}

Handling query errors.

Like it was said above, do not handle errors in your code. We already configured PDO to throw exceptions in case of error, that's all. So just write your query execution code right away, without any conditions:

$stmt = $pdo->prepare("SELECT a FROM b WHERE c = :c")) {
$stmt->execute(array(':c' => $c));
$result = $stmt->fetch();
echo 'All fine.';
\$\endgroup\$
  • \$\begingroup\$ Thanks for the detailed and quick answer! Now I understand it a little better. I will read through the linked articles and try to implement it. About the function: I call it only once at the beginning. But I will include it through a separate file like you mentioned above. Thanks a lot! \$\endgroup\$ – Nino Sep 3 '19 at 17:28
  • \$\begingroup\$ Just want to thank you again, now my error handler is working fine, database connection is properly configured and all my questions got answered with the 2 provided links. Im still reading, there are good articles. \$\endgroup\$ – Nino Sep 4 '19 at 18:16
  • \$\begingroup\$ My last question to this topic: I would like to know if its possible to redirect to a separate .html file when an exception is thrown, to show the user a general message. I tried to setup ErrorPages on the server, but it didnt work. So I tried the following code, but the redirect is also not working: function myExceptionHandler ($e) { http_response_code(500); if (ini_get('display_errors')) { echo $e; } else { error_log($e); header ("Location: 500.html"); } } set_exception_handler('myExceptionHandler'); \$\endgroup\$ – Nino Sep 5 '19 at 6:54
  • \$\begingroup\$ @Nino a good question. And I believe it deserves an answer on Stack Overflow a s well (especially given it was considered off topic here ¯_(ツ)_/¯). So. I'll write in detail there so check it out in a while, but in short, it is against the standard to redirect (by means of using an HTTP header) in case of error. It's all about HTTP codes. redirect is 301 and error is 500. Redirect will overwrite 500 telling a search engine the wrong impression. If you want to have a file, just include (or better readfile()) it inside the handler. \$\endgroup\$ – Your Common Sense Sep 5 '19 at 7:22
  • \$\begingroup\$ I'll be curious to hear what you have to say. Somehow I still don't look through where my questions belong - on stack owerflow or codereview? I apologize for that, will try to find out. \$\endgroup\$ – Nino Sep 5 '19 at 8:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.