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;
Related
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;
}
?>
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.
What is the proper way to "encapsulate" the sql queries scripts and connection script with try/catch or if/else blocks? I want to have a config.php file that will contain the connection part:
<?php
$servername = "localhost";
$username = "username";
$password = "password";
try {
$conn = new PDO("mysql:host=$servername;dbname=myDB", $username, $password);
// set the PDO error mode to exception
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
echo "Connected successfully";
}
catch(PDOException $e)
{
echo "Connection failed: " . $e->getMessage();
}
?>
Now taken from w3schools, when they insert a value to the database, they simply re-write the entire connection part again:
<?php
$servername = "localhost";
$username = "username";
$password = "password";
$dbname = "myDBPDO";
try {
$conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password);
// set the PDO error mode to exception
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$sql = "INSERT INTO MyGuests (firstname, lastname, email)
VALUES ('John', 'Doe', 'john#example.com')";
// use exec() because no results are returned
$conn->exec($sql);
echo "New record created successfully";
}
catch(PDOException $e)
{
echo $sql . "<br>" . $e->getMessage();
}
$conn = null;
?>
but I want to properly separate the two. Also, if I use prepared statements, do I need to check if on each part? i.e the prepare, bindParam and execute? Or a single try/catch or if/else is enough:
// Prepare an insert statement
$sql = "INSERT INTO table(value) VALUES (:value)";
$stmt = $conn->prepare($sql);
// Bind variables to the prepared statement as parameters
$stmt->bindParam(':value', $value, PDO::PARAM_STR);
$stmt->execute(); //does each part here need an if/else?
You should only make the connection once. There's no need to close and reopen the connection between queries. I assume the reason the example at w3schools is written that way is so that it will be self-contained, executable as-is without relying on a connection established in another example.
If you have the code that defines your connection in one file like the first example you showed, you can include that file in other files that need a connection to execute queries, and $conn will be available there. For a simple project, that's all you really need.
As far as if/else or try/catch, since you have set the PDO::ATTR_ERRMODE attribute on your connection to PDO::ERRMODE_EXCEPTION, then wrapping bits of code where a query may fail in if/else probably won't be that useful, because an exception will be thrown if the query fails, so handling the exception in a catch block will work better. You can examine the exception to see exactly what went wrong, log the error, and show an appropriate error message to the user where applicable. Dumping every exception message to the screen as shown in the second example is generally not a good way to show appropriate error messages to users.
You should include the prepare, bind, and execute in the try block. execute() is not the only thing that can cause an exception. prepare() may throw an exception if you aren't using emulated prepared statements (depending on the setting of PDO::ATTR_EMULATE_PREPARES), and bind can also cause an exception, for example if you mess up a named placeholder.
if/else is more useful for checking the results of queries that executed successfully (e.g. did this select statement return any records). The level of detail of error handling you need determines how many if/else, try/catch blocks you need.
How can I perform a SQLite3 exec at the same time in PHP?
I have this code (by example):
$bd = new SQLite3("database.db");
$bd->busyTimeout(5000);
$bd->exec("INSERT into 'foo' ('data') values ('bar')");
$bd->close();
unset($bd);
And it works, but the real problem is when I connect another computer to my server and I made the insert at the same time (really, I press the key that trigger the code at the same time in both computers) and it show an error "database is locked".
I know that with the pragma WAL the database works in multithread, but it even show the error. Thank you a lot! and sorry for my bad english.
The problem is sqlite3 employs database locking, as opposed to row or column locking like mysql or postgresql. If you want to do two things at the same time try using mysql, or postgresql. In mysql you would have to create the database. Your code would then look something like this:
$servername = "localhost";
$username = "username";
$password = "password";
try {
$conn = new PDO("mysql:host=$servername;dbname=myDB", $username, $password);
// set the PDO error mode to exception
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
echo "Connected successfully";
}
catch(PDOException $e)
{
echo "Connection failed: " . $e->getMessage();
}
$count = $conn->exec("INSERT into 'foo' ('data') values ('bar')");
$conn = null // close connection
I want to select a MySQL database to use after a PHP PDO object has already been created. How do I do this?
// create PDO object and connect to MySQL
$dbh = new PDO( 'mysql:host=localhost;', 'name', 'pass' );
// create a database named 'database_name'
// select the database we just created ( this does not work )
$dbh->select_db( 'database_name' );
Is there a PDO equivalent to mysqli::select_db?
Perhaps I'm trying to use PDO improperly? Please help or explain.
EDIT
Should I not be using PDO to create new databases? I understand that the majority of benefits from using PDO are lost on a rarely used operation that does not insert data like CREATE DATABASE, but it seems strange to have to use a different connection to create the database, then create a PDO connection to make other calls.
Typically you would specify the database in the DSN when you connect. But if you're creating a new database, obviously you can't specify that database the DSN before you create it.
You can change your default database with the USE statement:
$dbh = new PDO("mysql:host=...;dbname=mysql", ...);
$dbh->query("create database newdatabase");
$dbh->query("use newdatabase");
Subsequent CREATE TABLE statements will be created in your newdatabase.
Re comment from #Mike:
When you switch databases like that it appears to force PDO to emulate prepared statements. Setting PDO::ATTR_EMULATE_PREPARES to false and then trying to use another database will fail.
I just did some tests and I don't see that happening. Changing the database only happens on the server, and it does not change anything about PDO's configuration in the client. Here's an example:
<?php
// connect to database
try {
$pdo = new PDO('mysql:host=huey;dbname=test', 'root', 'root');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
} catch(PDOException $err) {
die($err->getMessage());
}
$stmt = $pdo->prepare("select * from foo WHERE i = :i");
$result = $stmt->execute(array("i"=>123));
print_r($stmt->fetchAll(PDO::FETCH_ASSOC));
$pdo->exec("use test2");
$stmt = $pdo->prepare("select * from foo2 WHERE i = :i AND i = :i");
$result = $stmt->execute(array("i"=>456));
print_r($stmt->fetchAll(PDO::FETCH_ASSOC));
If what you're saying is true, then this should work without error. PDO can use a given named parameter more than once only if PDO::ATTR_EMULATE_PREPARES is true. So if you're saying that this attribute is set to true as a side effect of changing databases, then it should work.
But it doesn't work -- it gets an error "Invalid parameter number" which indicates that non-emulated prepared statements remains in effect.
You should be setting the database when you create the PDO object. An example (from here)
<?php
$hostname = "localhost";
$username = "your_username";
$password = "your_password";
try {
$dbh = new PDO("mysql:host=$hostname;dbname=mysql", $username, $password);
echo "Connected to database"; // check for connection
}
catch(PDOException $e)
{
echo $e->getMessage();
}
?>
Alternatively, you can select a MySQL database to use after a PHP PDO object has already been created as below:
With USE STATEMENT. But remember here USE STATEMENT is mysql command
try
{
$conn = new PDO("mysql:host=$servername;", $username, $password);
// set the PDO error mode to exception
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$conn->exec("use databasename");
//application logic
}
catch(PDOException $e)
{
echo $sql . "<br>" . $e->getMessage();
}
$conn = null;
I hope my code is helpful for requested
As far as I know, you have to create a new object for each connection. You can always extend the PDO class with a method which connects to multiple databases. And then use it as you like:
public function pickDatabase($db) {
if($db == 'main') {
return $this->db['main']; //instance of PDO object
else
return $this->db['secondary']; //another instance of PDO object
}
and use it like $yourclass->pickDatabase('main')->fetchAll('your stuff');