I'm using PHP and PDO. Now I want to build a kind of log when things go wrong. What can go wrong with PDO?
Right now I have these tests:
Connection test
try {
$this->pdo = new PDO($dsn, $credentials['user'], $credentials['pass'], $options);
} catch(Exception $e) {
$this->file->put( date('Y-m-d') . '.txt', 'log', 'Database error');
}
Execute test
try {
$stmt->execute();
} catch(Exception $e) {
$this->error->log('SQL', 'query error');
}
Any more tests that are good?
You do not log your exception message in your logs. I suggest you to do something like this into your catch :
$this->error->log('SQL', $e . PHP_EOL);
This will give you more understandable and readable logs.
Regarding the exceptions to catch with PDO, you may read that post : How to handle PDO exceptions
Related
I have been developing complex platform, on which to build latter. I have reached the point when it works on mine lamp, but not when via webhosting. One of mine function designed to log the variables to the database during operation keeps sending just a petty
Fatal error: in /home/.../asi/kluckaSpolocne.php on line 51
This points to the exception of execute statement:
throw new \PDOException($e->getMessage(), (int)$e->getCode());
the code in question:
//echo "\n Spolocne ";
//require 'ochrana.php';
// include 'databazaCitaj.php';
$dbuzyvatel = "mine login";
$dbheslo = "mine password";
//$charset = 'utf8mb4';
$opt = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => false,
];
try {
$databaza = new PDO("mysql:host=localhost;dbname=mine_database", $dbuzyvatel, $dbheslo);
$databaza->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (\PDOException $e) {
throw new \PDOException($e->getMessage(), (int)$e->getCode());
}
# $preloz = $databaza->prepare('select ? from preklady where jazyk=?');
$GLOBALS['nová']=false;
$DlzkaVystupu=1;
$IC=0;
$Hesla=json_encode(array(1,1));
$HlavnýÚčel=0;
$Kolá=array(0);
$Hlasenia['Premenna']=' ';
$Hlasenia['Text']=' ';
$Hlasenia['Cislo']=1;
$Hlasenia['JS']='[0]';
$Hlasenia['Kdo']=0;
$Hlasenia['Vlastnosti']='[0]';
//print_r($Hlasenia);
/*$hlásenie=$databaza->prepare('insert into Hlásenia (Premenná, Text)
values (:Premenna, :Text)');//*/
$hlásenie=$databaza->prepare('insert into Hlásenia (Premenná, Text, Cislo, JS, Kdo, Vlastnosti)
values (:Premenna, :Text, :Cislo, :JS, :Kdo, :Vlastnosti)');//*/
$hlásenie->bindParam(':Premenna', $Hlasenia['Premenna']);
$hlásenie->bindParam(':Text', $Hlasenia['Text']);
$hlásenie->bindParam(':Cislo', $Hlasenia['Cislo']);
$hlásenie->bindParam(':JS', $Hlasenia['JS']);
$hlásenie->bindParam(':Kdo', $Hlasenia['Kdo']);
$hlásenie->bindParam(':Vlastnosti', $Hlasenia['Vlastnosti']);//*/
// print_r($hlásenie);
try { $hlásenie->execute();
} catch (\PDOException $e) {
throw new \PDOException($e->getMessage(), (int)$e->getCode());
}//*/
Any idea about how to get some useful info about what is wrong?
Looks like it's your "function designed to log the variables" is messing with the error message.
Make it this way:
set_exception_handler(function ($e)
{
error_log($e);
http_response_code(500);
if (ini_get('display_errors')) {
echo $e;
} else {
echo "<h1>500 Internal Server Error</h1>
An internal server error has been occurred.<br>
Please try again later.";
}
});
It will catch every exception and log it into web-server's error log.
It's part of a complete error handling solution I wrote.
I have a database class dbconnect.php, and processform.php. Inside dbconnect.php there is a method for connecting to the database.
If there's an error, how do I throw an exception? Where do I put the try catch block, in the processform.php? People say I shouldn't echo an error directly from inside the class. Here's an example:
<?php
// dbconnect.php
class DbConnect
{
public function open_connection()
{
/* Should I do it like this? */
$this->conn = PDO($dsn, $this->username, $this->password);
if (!$this->conn) {
throw new Exception('Error connecting to the database.');
}
/* Or like this */
try {
$this->conn = PDO($dsn, $this->username, $this->password);
} catch (PDOException $e) {
echo 'Error: ', $e->getMessage(), '<br>';
}
}
?>
// processform.php
<?php
require_once 'dbconnect.php';
$pdo = new DbConnect($host, $username, $password);
try {
$pdo->open_connection();
} catch (PDOException $e) {
echo 'Error connecting to the database.');
}
?>
I really want to learn the correct way of implementing the try catch in my code.
You don't have to throw an exception manually, especially on a successful connect :-)
Instead you need to tell PDO that it needs to throw exceptions when something goes wrong and you can do that when you open your database connection:
$options = array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION);
$this->conn = new PDO($dsn, $this->username, $this->password, $options);
Now you can put everything in try / catch blocks but that is not even necessary; if you don't do that, php will show you unhandled exceptions complete with a stack trace when you don't catch them manually.
And when you decide you want to fine-tune your error handling for your visitors, you can set your own exception handler using set_exception_handler(). That way you can handle everything at one place instead of wrapping different sections in try / catch blocks. Should you prefer that of course.
In my practice, I prefer to catch exception in bottom. I mean, second way in your DbConnect.
You can output error message to error log. And return an error code to front-end. So the front-end knows how to tell users an error occours in a friendly way.
What's more, you can use global error handler such as set_error_handler/set_exception_handler to do this. Redirect to an error page when error occours.
Okay, so this is my code:
try {
$pdo = new PDO ('mysql:host=127.0.0.1;dbname=db_name','user','password');
} catch (PDOException $e) {
exit ('Database error.');
}
I tried so many different combinations with host name, username and password, and every time I get 'Database error'.
My question is:
What should I do to succesfully transfer MySQL database from localhost to my hosted server using this part of code (which is my connection.php file)?
Thank you, in advance.
Get rid of this try catch stuff. Leave it as
$pdo = new PDO ('mysql:host=127.0.0.1;dbname=db_name','user','password');
And see what it says (on-screen or logs)
Use this try and catch block for error trace
try {
$this->conn = new PDO('mysql:host=127.0.0.1;dbname=db_name','user','password');
$this->conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
echo 'Error: ' . $e->getMessage();
}
I am trying to migrate a PHP app from MySQL to SQLite, and some things that used to work, simply stopped working now. I am using PDO through a custom database wrapper class (the class is a singleton, seems logical to do it like that).
The problem:
When trying to execute a query on a prepared statement, it throws a "fatal error: Call to a member function execute() on a non-object ...".
Relevant code (narrowed it down to this, after some hours of var_dumps and try-catch):
Connection string:
$this->connection = new PDO("sqlite:"._ROOT."/Storage/_sqlite/satori.sdb");
Obviously, the $connection variable here is a private variable from the class.
The error happens here (inside a function that is supposed to perform database insert):
try{
$statement = self::getInstance()->connection->prepare($sql);
}catch (PDOException $e){
print $e->getMessage;
}
try{
var_dump($statement);
$statement->execute($input);
}catch (Exception $e){
print $e->getMessage();
}
More accurately, it happens when I try to $statement->execute($input).
Any help appreciated. Thanks.
You are probably getting a mySQL error when the statement is being prepared, but you don't have PDO configured to throw an exception in case of an error.
<?php
$dbh = new PDO( /* your connection string */ );
$dbh->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
// . . .
?>
try declaring the $statement variable outside the first try block. e.g.
$statement = null;
try{
$statement = self::getInstance()->connection->prepare($sql);
}catch (PDOException $e){
print $e->getMessage;
}
try{
var_dump($statement);
$statement->execute($input);
}catch (Exception $e){
print $e->getMessage();
}
I am working with PDO in PHP.
Now I wonder if you could catch any global error and show.
With global I mean if any $sql=$connect->prepare() fails, then echo out
"Something went wrong:" . the_error
Or would you need to always do it invidually each $sql ?
You can do it using PDO::errorInfo()
http://www.php.net/manual/en/pdo.errorinfo.php
That's about as global as youre going to get.
You could always catch exceptions thrown by the PDO class.
try
{
...new PDO('odbc:SAMPLE', 'db2inst1',...
}
catch(PDOException $exception)
{
echo "Failed: " . $exception->getMessage();
}