PDO Connection error vs SQL Error, how to detect - php

I regularly send copies of WordPress data to a more structure in a Cloud SQL Database (a single woo order in a single row instead of multiple tables) for the benefits of reporting and backups etc.
Im now creating a component that will write the same data to a local copy of the Cloud DB in case there is a network error as a backup which can then be inserted at a later date once the connection is restored.
Im trying to distinguish the difference between a connection error and an SQL error. If I have a connection error then I can use the local copy, if there is an SQL error then I can write the error to a log file as the statement wouldn't work anyway.
Here is my code:
<?php
try {
//Connect to the DB
$connection = new PDO("mysql:host=$this->servername;dbname=$this->database",$this->u,$this->p,[
PDO::MYSQL_ATTR_SSL_KEY => $this->ck,
PDO::MYSQL_ATTR_SSL_CERT => $this->cc,
PDO::MYSQL_ATTR_SSL_CA => $this->sc,
PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT => false
]
);
$connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$statement = 'INSERT BLA BLA BLA';
$statement->execute();
}
//Log any errors. However, at this point I would like to drill down into the error to find out if its a connection error or an sql error!
catch(PDOException $e) {
//DcgsqlErrorLog(Object name, Object ID, PDO Error message))
new DcgsqlErrorLog('Product',$this->product->get_id(),$e->getMessage());
}
//Close connection and return
finally {
$connection = null;
return;
}
?>

Related

How to connect properly to MySQL database?

I'm trying to connect MySQL to my PHP program. The database was properly connected as it doesn't show any error messages with database connection. But when I'm trying to fetch data from the table, the output doesn't show any outputs. It leaves a blank screen. No error messages are also shown. It displays only 'Database connected successfully'.
<?php
define('user', 'root');
define('pwd', '');
$dsn = "mysql:host=localhost:3307;db_name=mydatabase";
try{
$db = new PDO($dsn,user,pwd);
echo "Database connected successfully";
$query = "SELECT * FROM student_detail";
$statementss = $db->prepare($query);
$statementss->execute();
$detail = $statementss->fetchAll();
foreach ($detail as $student) {
echo $student['Name']." ";
echo $student['Address']." ";
echo $student['Age']." ";
echo $student['Phone']." ";
echo "<br>";
}
$statementss->closeCursor();
}
catch(Exception $e){
echo $e->getMessage()."<br>";
}
?>
It's unclear whether you actually have any values in the database, but I will now explain how to connect properly to MySQL database using PDO extension in PHP.
There are 3 things you need to do always when opening DB connection:
Enable error reporting. In PDO you can pass $options array containing \PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION to enable error reporting.
Set the correct charset. The most common one is utf8mb4. If you are using utf8 I strongly recommend to make the switch as soon as possible.
Create an instance of PDO.
You should only catch exceptions if you know why you need to do it. Don't wrap everything in try-catch; this is a terrible idea. Especially don't ever catch exceptions just to echo the error message out; this is pointless. You can however wrap the new PDO(); line in try-catch and then throw a custom exception in catch block if you are paranoid about security.
The name of key-value pair for database name is dbname instead of db_name. Also, when specifying port, there is a separate key-value pair in DSN dedicated to it. It could be that your issue was because you were connecting on the wrong port or because the db_name was not recognized.
Your fixed code would look like this:
<?php
define('user', 'root');
define('pwd', '');
$dsn = "mysql:host=localhost;port=3307;dbname=mydatabase;charset=utf8mb4";
$db = new \PDO($dsn, user, pwd, [
\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
\PDO::ATTR_EMULATE_PREPARES => false,
]);
echo "Database connected successfully";
$query = "SELECT * FROM student_detail";
$statementss = $db->prepare($query);
$statementss->execute();
$detail = $statementss->fetchAll();
foreach ($detail as $student) {
echo $student['Name']." ";
echo $student['Address']." ";
echo $student['Age']." ";
echo $student['Phone']." ";
echo "<br>";
}
Unrelated issues:
You probably don't need closeCursor(). I am not sure what the idea of it was in your example.
It's always good idea to separate your database logic from your HTML. Use classes or functions to encapsulate the DB operations and then have the foreach loop in HTML.
The convention for constant naming in PHP is that they should be written in uppercase, so it is easier to distinguish them.
It's recommended to switch off emulated prepared statements. You can add \PDO::ATTR_EMULATE_PREPARES => false to the $options array.

Simple PDO write not working

I'm trying to get a simple PDO insert to work. I have successfully created a tabled named mydb10 using PDO, and the next part I want to do is insert data into that table. Running the script does not return any errors (PDO error mode exception is enabled), but the table still contains null values.
I'm using a local server to run the PHP file, and am connecting to an Amazon RDS database. Currently all inbound traffic through SSH, HTTP, HTTPS, and MYSQL is allowed through the database's security group
$link = new PDO("mysql:host=$dbhost;dbname=$dbname",$username,$password);
$statement = $link->prepare("INSERT INTO mydb10 (selectedMain, selectedSide)
VALUES(:selectedMain, :selectedSide)");
$statement->execute(array(
"selectedMain" => "test",
"selectedSide" => "test2"
));
This might be silly, but I've been stuck for a while now and any help is appreciated. If you'd like any more information, let me know. I'm trying to utilize PHP in my app, but can't even get this simple test to work, so it's a bit discouraging.
EDIT # 1
This snippet is part of a larger file. I am able to successfully
connect to the database with my credentials and create new tables on the server. I do have PDO error reporting enabled in exception mode, and it has helped me work past syntax errors, but I am no longer getting any errors when I run the code. There are also no errors on the MYSQL server log.
I can provide any additional information that may be useful in debugging if desired.
First you need to properly set connection to MySQL database. You can write this code to sql.php:
<?php
$ServerName = "******";
$Username = "******";
$Password = "******";
$DataBase = "******";
try {
$CONN = new PDO("mysql:host=$ServerName; dbname=$DataBase", $Username, $Password);
$CONN->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$CONN->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch(PDOException $e) {
echo "Connection failed: " . $e->getMessage();
}
?>
Now, when you properly set connection, you need to execute sql, but before this you need to include sql.php:
try {
$SQL = 'INSERT INTO MyDB10 (SelectedMain, SelectedSide) VALUES(:SelectedMain, :SelectedSide)'; // Write SQL Query to variable
$SQL = $CONN->prepare($SQL); // Prepare SQL Query
$SQL->execute(array('SelectedMain' => 'Test', 'SelectedSide' => 'Test2')); // Execute data to Insert in MySQL Databse
} catch(PDOException $e) {
echo "Error: " . $e->getMessage();
}
When you finish all queries you must close connection with:
$CONN = null;

Insertig php array in mysql DB - Syntax correct, values are not inserted

I have writen this pice of code that should insert into my Database some event data, but it does not insert a thing in the DB, can you tell me why?
try {
$pdo = new PDO("mysql:host={$dbhost};dbname={$dbname}", $dbuser, $dbpass);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
catch( PDOException $excepiton ) {
echo "Connection error :" . $excepiton->getMessage();
}
try{
$sql = "INSERT INTO events_DB (event_id, event_end_time, event_location, event_name) VALUES (:event_id, :event_end_time, :event_location, :event_name) ON DUPLICATE KEY UPDATE event_id = :event_id, event_end_time = :event_end_time, event_location = :event_location, event_name = :event_name";
$stm = $db->prepare($sql);
$stm->execute(array(":event_id" => $event[id], ":event_end_time" => $event[end_time], ":event_location" => $event[location], ":event_name" => $event[name]));
}
catch ( PDOException $exception )
{
// decomentati sa vedeti erorile
echo "PDO error :" . $exception->getMessage();
}
Thanks
The code you've posted is different than the code you're running as the posted code would result in a syntax error at parse time and never actually run.
However, what's happening is the SQL being sent to the prepare method is not valid in some way so that the result returned and stored in $stm is a boolean (false) rather than a valid statement object. Double check your SQL (you could try running it in another application such as phpMyAdmin or via the mysql command-line program) to ensure its validity. You could also add some error handling to find the cause with:
$stm = $db->prepare($sql);
if (!$stm) {
die($db->errorInfo());
}
Edit: You've modified the posted source code which now shows use of exception handling. However, you've commented out the line that echos the exception message. This information will be useful in telling you what's causing the error condition. Uncomment to see the message (which will most likely inform you that the SQL is invalid and which part of it caused the error).
Try to remove the <br> tag from the first line and a " is messing
$sql = "INSERT INTO events_DB (event_id, event_end_time, event_location, event_name);"

"The page cannot be displayed because an internal server error has occurred." as a result of The FastCGI process exited unexpectedly

I am working with a php application deployed on Windows Azure.
I am running into an issue that results in the error:
"The page cannot be displayed because an internal server error has occurred."
when I look at the logs I see:
HTTP Error 500.0 - Internal Server Error
D:\Program Files (x86)\PHP\v5.3\php-cgi.exe - The FastCGI process exited unexpectedly
The problem is that this happens when I want to get data from a sql server. When I try to post data to the sql server everything works fine.
The following code represents what I am trying to do with comments to explain what's happening:
try {
// Try to connect to the database.
$conn = new PDO ( "sqlsrv:server = server,1433; Database = name", "user", "password");
$conn->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
$conn->beginTransaction();
// This works out when executed (I see the row in the table).
$query = "INSERT INTO owner (email) VALUES ('email#email.com')";
$conn->exec($query);
$result = $conn->query("SELECT email FROM owner");
$conn->commit();
// If the SQL select is succesfully performed ($result not false)
if($result !== false) {
echo "there are results";
// Traverse the result set and shows the data from each row
foreach($result as $row) {
echo $row['email']. '<br />';
}
}
$conn = null; // Disconnect
} catch ( PDOException $e ) {
print( "Error connecting to SQL Server. Please call support!" );
die(print_r($e));
}
The code above does insert information in the table on the server but causes the error explained above. Please let me know if there is any more information that I can provide.
Check access database credentials or maybe you have duplicate entry in database for email#email.com.
What is logged in error log?

Cannot capture an PHP exception from an inactive MySql server when using Zend transactions

I am trying to use transactions in the Zend Framework and have a working script.
However, under testing I noticed that a try/catch function will catch any exception except one caused by the Mysql server being inactive.
Is this supposed to happen? If my server crashes I am worried that an ugly Zend exception would be returned and the application would cease to fail gracefully.
My code looks like this:
function insertInbox ($userId, $mail_id )
{
$db = Zend_Db_Table::getDefaultAdapter();
$table = new Application_Model_DbTable_Inbox;
try {
$db->beginTransaction();
$data = array (
'user_id' => $userId,
'mail_id' => $mail_id
);
$insertedId[] = $table -> insert($data);
$db -> commit();
return $insertedId;
}
catch(exception $e){
$db->rollback();
return "insert failed";//.$e;
}
}
$tt = insertInbox ( 666,666);
print_r($tt);
A duplicate entry of similar exception is caught and the temporary custom error message -insert failed- is returned. But if I turn off the database server the php catch does not capture this error:
**Message:** SQLSTATE[HY000] [2002] No connection could be made because the target machine actively refused it.
Any thoughts appreciated.
Some database extensions of PHP try to create a database connection when none is established and a function is called, that requires one. In this case $db->rollback() itself throws an exception.

Categories