When I create database without using bind param, it works perfectly.
$login = 'root';
$password = 'root';
$dsn = "mysql:host=localhost";
$opt = array(
// any occurring errors wil be thrown as PDOException
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
// an SQL command to execute when connecting
PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'UTF8'"
);
// Making a new PDO conenction.
$conn = new PDO($dsn, $login, $password,$opt);
$db = $conn->prepare( 'CREATE SCHEMA IF NOT EXISTS account');
$db->execute();
// End Connection and Return to other files.
But after applying the bindParam it is not working properly.
$db = $conn->prepare( 'CREATE SCHEMA IF NOT EXISTS ?');
$db->bindParam(1,`account`);
$db->execute(); //line 18
Showing error:
Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'NULL' at line 1' in /Applications/MAMP/htdocs/create/index.php:18 Stack trace: #0 /Applications/MAMP/htdocs/create/index.php(18): PDOStatement->execute() #1 {main} thrown in /Applications/MAMP/htdocs/create/index.php on line 18
UPDATE:
<?php
$login = 'root'; // Login username of server host.
$password = 'root'; // Password of server host.
$dsn = "mysql:host=localhost"; // Set up a DSN for connection with Database Frat.
$dbb = 'sale';
$opt = array(
// any occurring errors wil be thrown as PDOException
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
// an SQL command to execute when connecting
PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'UTF8'"
);
// Making a new PDO conenction.
$conn = new PDO($dsn, $login, $password,$opt);
$db = $conn->prepare( 'CREATE SCHEMA IF NOT EXISTS ?');
$db->bindParam(1,'$dbb'); //line 17
$db->execute();
?>
it showing error:
Cannot pass parameter 2 by reference on line 17
There are two big problems here. The first is minor. These lines of code will never work:
$db->bindParam(1,`account`);
$db->bindParam(1,'$dbb'); //line 17
This is because both of them are attempting to call bindParam as a string. This is impossible. bindParam needs a reference to a variable. This is why you get a "cannot pass parameter 2 by reference" error: you can only pass variables by reference.
Either of these, however, would work:
$db->bindParam(1, $dbb); // call bindParam on a variable
$db->bindValue(1, 'account'); // call bindValue on a string literal
The more fundamental problem, however, is your understanding of prepared statements. The idea of prepared statements is not simple substitution of strings into another string. It is fundamentally about separation of the structure of the query from the data. The name of a table is considered part of the structure of the query, not part of the data. You need to put the table name in the original query. Your first code is the way to do it.
$db = $conn->prepare( 'CREATE SCHEMA IF NOT EXISTS account');
Related
This question already has answers here:
Pdo connection without database name?
(4 answers)
Closed 5 years ago.
I've installed the latest available version of XAMPP Package on my machine running on Windows 10 Home Single Language Edition.
I'm learning PHP and MySQL.
So, first of all in order to create a new database I wrote following code :
<?php
$servername = "localhost";
$username = "root";
$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);
$sql = "CREATE DATABASE myDBPDO";
// use exec() because no results are returned
$conn->exec($sql);
echo "Database created successfully<br>";
}
catch(PDOException $e) {
echo $sql . "<br>" . $e->getMessage();//Getting 'Notice : Undefined variable : sql' for this line
}
$conn = null;
?>
The database didn't get created and I received following error in output after running above file in a web browser :
Notice: Undefined variable: sql in prog_1.php on line 16
SQLSTATE[HY000] [1049] Unknown database 'mydb'
Can someone please help me by correcting my code, so that I can further start studying the database concepts in actual manner?
Is it necessary to have a database already present when accessing the same using PDO?
P.S. : The database titled 'mydb' is currently not present in MySQL RDBMS.
You're setting the DB name in your DSN connection string, and it looks like mydb doesn't exists.
Just remove that part from the DSN string and try again.
Your $conn = new PDO() fails because there isn't a database called myDB (SQLSTATE[HY000] [1049]). Because that line fails your try catch statement will evaluate to the catch part before it declares the $sql variable. So when you try to access the $sql variable in the catch part it does not exist and will throw an Undefined variable error.
You'll have to move the $sql above the $conn = new PDO() line to fix the undefined variable error. To fix the missing database error you'll have to create a database called myDB.
try {
$sql = "CREATE DATABASE myDBPDO"; // moved it here
$conn = new PDO("mysql:host=$servername;dbname=myDB", $username, $password);
// (...)
} catch(PDOException $e) {
echo $sql . "<br>" . $e->getMessage(); // no undefined variable
}
To connect to the database without selecting a specific database you'll have to change your new PDO() DSN to this:
$conn = new PDO("mysql:host=$servername", $username, $password);
For more information please check this answer.
I am working with PHP slim framework to develop API. I can GET and DELETE but with the inserting (POST) and updating (PUT), I am facing problems.
class db {
//Propertise
private $dbhost = 'localhost';
private $dbuser = 'root';
private $dbpass = '';
private $dbname = 'bralivnara-api';
//Connect
public function connect(){
try {
$options = array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8', 'CHARSET utf8');
$dbConnection = new PDO("mysql:host=$this->dbhost;dbname=$this->dbname;", $this->dbuser, $this->dbpass, $options);
// set the PDO error mode to exception
$dbConnection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
//echo "Connected successfully";
}
catch(PDOException $e)
{
echo "Connection failed: " . $e->getMessage();
}
return $dbConnection;
}
}
When I use rest easy I receive the 500 error.
Response Status: 500 (Internal Server Error)
When I passed the URL and press enter in browser, it shows the error
Connection failed: SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'add' at line 1
Before I had an issue with Swedish letters also, it was not displaying in browser correctly. If anyone has same issue you can fix this issue with that header. It will work for all non-English letters
return $response->withStatus(200)
->withHeader('Content-Type', 'application/json;charset=utf-8;')
->write(json_encode($tranasVcDatainsamling, JSON_UNESCAPED_UNICODE));
If you want to see complete get code you can join our discussion.
Now the last problem which still remains is inserting to database. Here is the code for insertion to the database.
$app->post('/api/tranas-vc/add', function (Request $request, Response $response){
$besöksdatum = $request->getParam('besöksdatum');
$kön = $request->getParam('kön');
$ålder_år = $request->getParam('ålder_år');
$sökorsak = $request->getParam('sökorsak');
$vp_objektiv_prio = $request->getParam('vp_objektiv_prio');
$vp_objektiv_variabel_med_högst_prio = $request->getParam('vp_objektiv_variabel_med_högst_prio');
$vp_mätning_prio = $request->getParam('vp_mätning_prio');
$vp_mätning_variabel_med_högst_prio = $request->getParam('vp_mätning_variabel_med_högst_prio');
$ess_val = $request->getParam('ess_val');
$prio_ess = $request->getParam('prio_ess ');
$prio_total = $request->getParam('prio-total');
$utskrivning_hänvisning_återbesök = $request->getParam('utskrivning_hänvisning_återbesök');
$åtgärd_remiss = $request->getParam('åtgärd_remiss');
$om_lab_vilka_prover = $request->getParam('om-lab-vilka-prover');
$sql = "INSERT INTO
`tranasvcdatainsamling`
(
`besöksdatum`,
`kön`,
`ålder_år`,
`sökorsak`,
`vp_objektiv_prio`,
`vp_objektiv_variabel_med_högst_prio`,
`vp_mätning_prio`,
`vp_mätning_variabel_med_högst_prio`,
`ess_val`,
`prio_ess`,
`prio_total`,
`utskrivning_hänvisning_återbesök`,
`åtgärd_remiss`,
`om_lab_vilka_prover`
)
VALUES
(
:`besöksdatum`,
:`kön`,
:`ålder_år`,
:`sökorsak`,
:`vp_objektiv_prio`,
:`vp_objektiv_variabel_med_högst_prio`,
:`vp_mätning_prio`,
:`vp_mätning_variabel_med_högst_prio`,
:`ess_val`,
:`prio_ess`,
:`prio_total`,
:`utskrivning_hänvisning_återbesök`,
:`åtgärd_remiss`,
:`om_lab_vilka_prover`
)";
try {
// Get DB Objects
$db = new db();
// Connect
$db = $db->connect();
// Execute Query
$stmt = $db->prepare($sql);
$stmt->bindParam(':besöksdatum', $besöksdatum);
$stmt->bindParam(':kön', $kön);
$stmt->bindParam(':ålder_år', $ålder_år);
$stmt->bindParam(':sökorsak', $sökorsak);
$stmt->bindParam(':vp_objektiv_prio', $vp_objektiv_prio);
$stmt->bindParam(':vp_objektiv_variabel_med_högst_prio', $vp_objektiv_variabel_med_högst_prio);
$stmt->bindParam(':vp_mätning_prio', $vp_mätning_prio);
$stmt->bindParam(':vp_mätning_variabel_med_högst_prio', $vp_mätning_variabel_med_högst_prio);
$stmt->bindParam(':ess_val', $ess_val);
$stmt->bindParam(':prio_ess', $prio_ess);
$stmt->bindParam(':prio_total', $prio_total);
$stmt->bindParam(':utskrivning_hänvisning_återbesök', $utskrivning_hänvisning_återbesök);
$stmt->bindParam(':åtgärd_remiss', $åtgärd_remiss);
$stmt->bindParam(':om_lab_vilka_prover', $om_lab_vilka_prover);
$stmt->execute();
echo '{"notice": {"text": "Tranås VC Entry Added"}';
} catch(PDOEception $e) {
echo '{"error": {"text": '.$e->getMessage().'}';
}
});
We did all possible experiments on that code, you can see those suggestions in comments, but we still had the problem in POST and PUT.
I commented the $stmt->execute(); to stop the execution of the query and check, I got 200 success in rest easy, but data was not inserted. I browser the error was same. It shows that the problem is in execution. I checked that code on English letters kind of data, and it was working.
I am quite sure that I had the problem because of Swedish letter, which is non-English.
I database those columns which contain Swedish letters look like that
kön varchar(125) latin1_swedish_ci
sökorsak varchar(125) latin1_swedish_ci
Which show latin1_swedish_ci, that I want you to consider also.
I will appreciate your help, and please join this discussion. If we fix this issue it will be very good research for non-English letters issue. I google almost whole day but did not got solution.
You already use SET NAMES which is the right approach, but you need to wrap the utf8 inside a single quotation mark, as defined in the MySQL documentation
SET NAMES 'charset_name' [COLLATE 'collation_name']
$options = array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'utf8'", 'CHARSET utf8');
^ ^
I have currently switched to using PDO but am having trouble in handling the exceptions. The connection is correct and queries work perfectly, but when I put in a deliberate mistake the error is not handled as I would expect.
I have changed the name of the table in my query to a table that does not exist. From the code seen below, I would expect the page to print out 'Database Error' but instead get the horrible orange error saying...
'Uncaught exception 'PDOException' with message 'SQLSTATE[42S02]: Base table or view not found: 1146 Table 'test.post' doesn't exist' in C:\wamp\www\website\functions.php on line 46'
Here is the code when connecting the database...
$hostname = 'localhost';
$username = '';
$password = '';
try{
$dbh = new PDO("mysql:host=$hostname;dbname=test", $username, $password);
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
print ("Database Error");
}
Am I making a mistake or is there a different way to handle PDO errors?
After connecting, you need to set the error handling:
$dbh = new PDO("mysql:host=$hostname;dbname=test", $username, $password);
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
Edit: Note that the exception gets caught at the place it is thrown, so you need to put a try catch block around the query, the one you use when connecting only catches exceptions there (if any, see #Crontab's comment).
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');
I want to wean myself from the teat of the old mysql extension and am just doing a test PDO connection and simple query on a table in a database. I seem to be able to connect, ('connection successful' echoes out) but that's where the good times end. I have spent way too much time now just trying to get started with PDO.
<?php
$host = 'localhost';
$port = '3306';
$username = 'user';
$password = 'blabla';
$database = 'workslist';
try {
$db = new PDO("mysql:host=$host; port = $port; dbname = $database", $username, $password);
echo 'connection successful<br />';
$query = 'SELECT * FROM main';
$statement = $db->prepare($query);
$statement->execute();
$results = $statement->fetchAll();
$statement->closeCursor();
foreach($results as $r){
echo $r['work'] . '<br />';
}
} catch (PDOException $e) {
echo 'Error!: ' . $e->getMessage() . '<br />';
die();
}
?>
Is there anything wrong with the above?
The database name is 'workslist', the table name is 'main', and 'work' is one of the columns in that table. The PHP version I'm using is 5.3.4, and am using wamp on win7. I ran phpinfo() and under the PDO heading, the PDO drivers mysql, sqlite are enabled. To be sure the database and table actually exist I've tried it with MySQL and can return rows with the old mysql_fetch_array() method. I've checked the php.ini file to make sure the "extension=php_pdo..." lines are all uncommented.
cheers
This should work.
Please double-check that you actually have a table named "main" in that database.
Note that this error will not be discovered by PDO until you execute() the query, and if there is a problem with your query the default behavior is to return an empty result, not throw an exception.
To make PDO noisier, add the PDO::ERRMODE_EXCEPTION option when constructing PDO:
$db = new PDO("mysql:host=$host;port=$port;dbname=$database", $username, $password,
array(PDO::ATTR_ERRMODE=>PDO::ERRMODE_EXCEPTION)
);
Now check if you see the following:
Error!: SQLSTATE[42S02]: Base table or view not found: 1146 Table 'workslist.main' doesn't exist
The particular problem is that spaces aren't allowed in the DSN string. With the spaces, the "dbname" directive isn't processed, so there's no default database. Besides removing the spaces, explicitly specifying the database in the statement can help prevent this sort of problem:
SELECT `work` FROM `workslist`.`main`
That way, should there not be a default database for some reason, the query will still succeed.
PDO won't throw an error unless you configure it to:
$db->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING );