Related
I wrote an Install File for my own CMS which I'm working atm. I changed the SQL statements to make it a bit saver but now nothing works and I can't figure out why...
I change my code from:
$db = new mysqli($_POST['db_ip'], $_POST['db_user'], $_POST['db_key'], '', $_POST['db_port']);
if(!$db) {
exit('Connection error to database');
}
$query = "CREATE DATABASE IF NOT EXISTS $db_name;";
$ergebnis = mysqli_query($db, $abfrage);
to:
$db = new mysqli($_POST['db_ip'], $_POST['db_user'], $_POST['db_key'], '', $_POST['db_port']);
if(!$db) {
exit('Error connecting to database'); //Should be a message a typical user could understand in production
}
$db_name = $_POST['db_name'];
$query = "CREATE DATABASE IF NOT EXISTS ?;";
$stmt->bind_param('s', $db_name);
$stmt = $db->prepare($query);
$stmt->execute();
I even tried:
$db = new mysqli($_POST['db_ip'], $_POST['db_user'], $_POST['db_key'], '', $_POST['db_port']);
if(!$db) {
exit('Error connecting to database'); //Should be a message a typical user could understand in production
}
$db_name = $_POST['db_name'];
$query = mysqli_prepare "CREATE DATABASE IF NOT EXISTS ?;";
mysqli_stmt_bind_param($query, 's', $db_name);
mysqli_stmt_execute($stmt);
mysqli_stmt_close($stmt);
last one added me a database but with the ? as name...
I hoped some one here can help me with that.
Not every SQL statement supports prepared statements. And CREATE DATABASE is one of them.
So, as a general rule, you are supposed to choose the database/table name from the white list.
In your specific case, however, when a user is apparently a database owner, there is not much point in protecting them from SQL injection as they apparently has the database password and can run any SQL statement much more convenient way. So you changed the code for nought. Just revert it back to the regular query() call.
I would only add backticks around the table name so it would always make a correct identifier name. And also may be add a regex validation just in order to avoid a human error.
I have information spread out across a few databases and want to put all the information onto one webpage using PHP. I was wondering how I can connect to multiple databases on a single PHP webpage.
I know how to connect to a single database using:
$dbh = mysql_connect($hostname, $username, $password)
or die("Unable to connect to MySQL");
However, can I just use multiple "mysql_connect" commands to open the other databases, and how would PHP know what database I want the information pulled from if I do have multiple databases connected.
Warning : mysql_xx functions are deprecated since php 5.5 and removed since php 7.0 (see http://php.net/manual/intro.mysql.php), use mysqli_xx functions or see the answer below from #Troelskn
You can make multiple calls to mysql_connect(), but if the parameters are the same you need to pass true for the '$new_link' (fourth) parameter, otherwise the same connection is reused. For example:
$dbh1 = mysql_connect($hostname, $username, $password);
$dbh2 = mysql_connect($hostname, $username, $password, true);
mysql_select_db('database1', $dbh1);
mysql_select_db('database2', $dbh2);
Then to query database 1 pass the first link identifier:
mysql_query('select * from tablename', $dbh1);
and for database 2 pass the second:
mysql_query('select * from tablename', $dbh2);
If you do not pass a link identifier then the last connection created is used (in this case the one represented by $dbh2) e.g.:
mysql_query('select * from tablename');
Other options
If the MySQL user has access to both databases and they are on the same host (i.e. both DBs are accessible from the same connection) you could:
Keep one connection open and call mysql_select_db() to swap between as necessary. I am not sure this is a clean solution and you could end up querying the wrong database.
Specify the database name when you reference tables within your queries (e.g. SELECT * FROM database2.tablename). This is likely to be a pain to implement.
Also please read troelskn's answer because that is a better approach if you are able to use PDO rather than the older extensions.
If you use PHP5 (And you should, given that PHP4 has been deprecated), you should use PDO, since this is slowly becoming the new standard. One (very) important benefit of PDO, is that it supports bound parameters, which makes for much more secure code.
You would connect through PDO, like this:
try {
$db = new PDO('mysql:dbname=databasename;host=127.0.0.1', 'username', 'password');
} catch (PDOException $ex) {
echo 'Connection failed: ' . $ex->getMessage();
}
(Of course replace databasename, username and password above)
You can then query the database like this:
$result = $db->query("select * from tablename");
foreach ($result as $row) {
echo $row['foo'] . "\n";
}
Or, if you have variables:
$stmt = $db->prepare("select * from tablename where id = :id");
$stmt->execute(array(':id' => 42));
$row = $stmt->fetch();
If you need multiple connections open at once, you can simply create multiple instances of PDO:
try {
$db1 = new PDO('mysql:dbname=databas1;host=127.0.0.1', 'username', 'password');
$db2 = new PDO('mysql:dbname=databas2;host=127.0.0.1', 'username', 'password');
} catch (PDOException $ex) {
echo 'Connection failed: ' . $ex->getMessage();
}
I just made my life simple:
CREATE VIEW another_table AS SELECT * FROM another_database.another_table;
hope it is helpful... cheers...
Instead of mysql_connect use mysqli_connect.
mysqli is provide a functionality for connect multiple database at a time.
$Db1 = new mysqli($hostname,$username,$password,$db_name1);
// this is connection 1 for DB 1
$Db2 = new mysqli($hostname,$username,$password,$db_name2);
// this is connection 2 for DB 2
Try below code:
$conn = mysql_connect("hostname","username","password");
mysql_select_db("db1",$conn);
mysql_select_db("db2",$conn);
$query1 = "SELECT * FROM db1.table";
$query2 = "SELECT * FROM db2.table";
You can fetch data of above query from both database as below
$rs = mysql_query($query1);
while($row = mysql_fetch_assoc($rs)) {
$data1[] = $row;
}
$rs = mysql_query($query2);
while($row = mysql_fetch_assoc($rs)) {
$data2[] = $row;
}
print_r($data1);
print_r($data2);
$dbh1 = mysql_connect($hostname, $username, $password);
$dbh2 = mysql_connect($hostname, $username, $password, true);
mysql_select_db('database1', $dbh1);
mysql_select_db('database2',$dbh2);
mysql_query('select * from tablename', $dbh1);
mysql_query('select * from tablename', $dbh2);
This is the most obvious solution that I use but just remember, if the username / password for both the database is exactly same in the same host, this solution will always be using the first connection. So don't be confused that this is not working in such case. What you need to do is, create 2 different users for the 2 databases and it will work.
Unless you really need to have more than one instance of a PDO object in play, consider the following:
$con = new PDO('mysql:host=localhost', $username, $password,
array(PDO::ATTR_PERSISTENT => true));
Notice the absence of dbname= in the construction arguments.
When you connect to MySQL via a terminal or other tool, the database name is not needed off the bat. You can switch between databases by using the USE dbname statement via the PDO::exec() method.
$con->exec("USE someDatabase");
$con->exec("USE anotherDatabase");
Of course you may want to wrap this in a catch try statement.
You might be able to use MySQLi syntax, which would allow you to handle it better.
Define the database connections, then whenever you want to query one of the database, specify the right connection.
E.g.:
$Db1 = new mysqli('$DB_HOST','USERNAME','PASSWORD'); // 1st database connection
$Db2 = new mysqli('$DB_HOST','USERNAME','PASSWORD'); // 2nd database connection
Then to query them on the same page, use something like:
$query = $Db1->query("select * from tablename")
$query2 = $Db2->query("select * from tablename")
die("$Db1->error");
Changing to MySQLi in this way will help you.
You don't actually need select_db. You can send a query to two databases at the same time. First, give a grant to DB1 to select from DB2 by GRANT select ON DB2.* TO DB1#localhost;. Then, FLUSH PRIVILEGES;. Finally, you are able to do 'multiple-database query' like SELECT DB1.TABLE1.id, DB2.TABLE1.username FROM DB1,DB2 etc. (Don't forget that you need 'root' access to use grant command)
if you are using mysqli and have two db_connection file. like
first one is
define('HOST','localhost');
define('USER','user');
define('PASS','passs');
define('**DB1**','database_name1');
$connMitra = new mysqli(HOST, USER, PASS, **DB1**);
second one is
define('HOST','localhost');
define('USER','user');
define('PASS','passs');
define(**'DB2**','database_name1');
$connMitra = new mysqli(HOST, USER, PASS, **DB2**);
SO just change the name of parameter pass in mysqli like DB1 and DB2.
if you pass same parameter in mysqli suppose DB1 in both file then second database will no connect any more. So remember when you use two or more connection pass different parameter name in mysqli function
<?php
// Sapan Mohanty
// Skype:sapan.mohannty
//***********************************
$oldData = mysql_connect('localhost', 'DBUSER', 'DBPASS');
echo mysql_error();
$NewData = mysql_connect('localhost', 'DBUSER', 'DBPASS');
echo mysql_error();
mysql_select_db('OLDDBNAME', $oldData );
mysql_select_db('NEWDBNAME', $NewData );
$getAllTablesName = "SELECT table_name FROM information_schema.tables WHERE table_type = 'base table'";
$getAllTablesNameExe = mysql_query($getAllTablesName);
//echo mysql_error();
while ($dataTableName = mysql_fetch_object($getAllTablesNameExe)) {
$oldDataCount = mysql_query('select count(*) as noOfRecord from ' . $dataTableName->table_name, $oldData);
$oldDataCountResult = mysql_fetch_object($oldDataCount);
$newDataCount = mysql_query('select count(*) as noOfRecord from ' . $dataTableName->table_name, $NewData);
$newDataCountResult = mysql_fetch_object($newDataCount);
if ( $oldDataCountResult->noOfRecord != $newDataCountResult->noOfRecord ) {
echo "<br/><b>" . $dataTableName->table_name . "</b>";
echo " | Old: " . $oldDataCountResult->noOfRecord;
echo " | New: " . $newDataCountResult->noOfRecord;
if ($oldDataCountResult->noOfRecord < $newDataCountResult->noOfRecord) {
echo " | <font color='green'>*</font>";
} else {
echo " | <font color='red'>*</font>";
}
echo "<br/>----------------------------------------";
}
}
?>
I have a database table and i am updating the table columns this way.
$mysqli = new mysqli('localhost', 'root', '', 'db');
if (mysqli_connect_errno()) {
echo 'failed to connect to db.. <br>' . mysqli_connect_errno();
return 'error';
}
$username = $data['username'];
$data['image'] = $this->replace_whitespace($data['image']);
foreach($data as $key=>$value){
$this->query = "UPDATE users SET $key=? WHERE username='$username'";
$this->statement = $mysqli->prepare($this->query);
if($this->statement){
$this->statement->bind_param('s', $value);
$this->statement->execute();
$this->statement->close();
}
}
Is it possible to update more than one table columns in one go. I tried this but in-vain.
$this->query = "UPDATE users SET col1=?, col2=?, col3=? WHERE username='$username'";
$this->statement = $mysqli->prepare($this->query);
if($this->statement){
$this->statement->bind_param('sss', $value1, $value2, $value3);
$this->statement->execute();
$this->statement->close();
}
Is there a better way doing this?
$mysqli = new mysqli('localhost', 'root', '', 'db');
if (mysqli_connect_errno()) {
echo 'failed to connect to db.. <br>' . mysqli_connect_errno();
return 'error';
}
$username = $data['username'];
$this->query = "UPDATE users SET fname=?, lname=?, email=?, tpin=?, image=?, address=? country=?, city=?, state=?, postal=? WHERE username='$username'";
$this->statement = $mysqli->prepare($this->query);
if ($this->statement) {
$this->statement->bind_param('ssssssssss', $data['fname'],$data['lname'],$data['email'],$data['tpin'], $data['file'], $data['address'],$data['country'],$data['city'],$data['state'], $data['post_code']);
$this->statement->execute();
$this->statement->close();
}
This is my real code.
Remove the "," after col3=?
This will fix the syntax error
$this->query = "UPDATE users SET col1=?, col2=?, col3=?, WHERE username='$username'";
You have an extra comma, meaning your SQL is reading "WHERE" as another column and everything gets messed up.
$this->query = "UPDATE users SET col1=?, col2=?, col3=? WHERE username='$username'";
Should work fine.
In response to the comment below, this is the correct way of going about it, so it must be a faulty variable somewhere, what error messages are you getting? (If any)
It could also be that one of the parameters you are binding is not a string. Regardless, we'd need a more in-depth example.
Is it possible to update more than one table columns in one go
Yes. Actually, updating many fields in one query is a very core feature of any DBMS. You can always expect it to be supported.
I tried this but in-vain.
Well, you have to try more, like we all do. After all, it's your job.
Two notes regarding your "real" code:
You have to bind ALL variables in the query, not only some of them
you have to configure mysqli to report errors:
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
I assume it works the same way as putting new values into the database.
Update a row mysql in php
I'm finding that a prepared update using mysqli is updating all the rows in my table instead of the one referenced in the WHERE clause. I'm stumped as for the reason this is happening. I used simplified code below to run as a test, and it still happens. I'm using PHP 5.3.18 and the Client API library version 5.0.96.
$mysqli = new mysqli("localhost", "user", "pass", "db");
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
}
$query = "UPDATE test SET first_name = ? WHERE last_name = ?";
if(!$stmt = $mysqli->prepare($query)) {
die("Unable to prepare<br />");
}
$first = 'test';
$second = 'something';
$stmt->bind_param("ss", $first, $second);
if (!$stmt->execute()) {
die("Could not execute<br />");
}
echo "done";
The query executes, but the first_name is updated for all rows in the table. Yes, there is a last_name with "something." No, the three other test rows do not have the last_name = something.
Is this something wrong with the library? My PHP config? Perhaps not enough sleep? What?
Oh... in addition... if I use a query like
"UPDATE test SET first_name = ? WHERE id = ?"
and update the params to use an id, it works. It only updates the single row. So why can't I use the last_name column in the WHERE clause?
I had the server techs update my server to MySql 5.5 and the issue is now fixed. I'm guessing it had something to do with the library or MySql install.
I have information spread out across a few databases and want to put all the information onto one webpage using PHP. I was wondering how I can connect to multiple databases on a single PHP webpage.
I know how to connect to a single database using:
$dbh = mysql_connect($hostname, $username, $password)
or die("Unable to connect to MySQL");
However, can I just use multiple "mysql_connect" commands to open the other databases, and how would PHP know what database I want the information pulled from if I do have multiple databases connected.
Warning : mysql_xx functions are deprecated since php 5.5 and removed since php 7.0 (see http://php.net/manual/intro.mysql.php), use mysqli_xx functions or see the answer below from #Troelskn
You can make multiple calls to mysql_connect(), but if the parameters are the same you need to pass true for the '$new_link' (fourth) parameter, otherwise the same connection is reused. For example:
$dbh1 = mysql_connect($hostname, $username, $password);
$dbh2 = mysql_connect($hostname, $username, $password, true);
mysql_select_db('database1', $dbh1);
mysql_select_db('database2', $dbh2);
Then to query database 1 pass the first link identifier:
mysql_query('select * from tablename', $dbh1);
and for database 2 pass the second:
mysql_query('select * from tablename', $dbh2);
If you do not pass a link identifier then the last connection created is used (in this case the one represented by $dbh2) e.g.:
mysql_query('select * from tablename');
Other options
If the MySQL user has access to both databases and they are on the same host (i.e. both DBs are accessible from the same connection) you could:
Keep one connection open and call mysql_select_db() to swap between as necessary. I am not sure this is a clean solution and you could end up querying the wrong database.
Specify the database name when you reference tables within your queries (e.g. SELECT * FROM database2.tablename). This is likely to be a pain to implement.
Also please read troelskn's answer because that is a better approach if you are able to use PDO rather than the older extensions.
If you use PHP5 (And you should, given that PHP4 has been deprecated), you should use PDO, since this is slowly becoming the new standard. One (very) important benefit of PDO, is that it supports bound parameters, which makes for much more secure code.
You would connect through PDO, like this:
try {
$db = new PDO('mysql:dbname=databasename;host=127.0.0.1', 'username', 'password');
} catch (PDOException $ex) {
echo 'Connection failed: ' . $ex->getMessage();
}
(Of course replace databasename, username and password above)
You can then query the database like this:
$result = $db->query("select * from tablename");
foreach ($result as $row) {
echo $row['foo'] . "\n";
}
Or, if you have variables:
$stmt = $db->prepare("select * from tablename where id = :id");
$stmt->execute(array(':id' => 42));
$row = $stmt->fetch();
If you need multiple connections open at once, you can simply create multiple instances of PDO:
try {
$db1 = new PDO('mysql:dbname=databas1;host=127.0.0.1', 'username', 'password');
$db2 = new PDO('mysql:dbname=databas2;host=127.0.0.1', 'username', 'password');
} catch (PDOException $ex) {
echo 'Connection failed: ' . $ex->getMessage();
}
I just made my life simple:
CREATE VIEW another_table AS SELECT * FROM another_database.another_table;
hope it is helpful... cheers...
Instead of mysql_connect use mysqli_connect.
mysqli is provide a functionality for connect multiple database at a time.
$Db1 = new mysqli($hostname,$username,$password,$db_name1);
// this is connection 1 for DB 1
$Db2 = new mysqli($hostname,$username,$password,$db_name2);
// this is connection 2 for DB 2
Try below code:
$conn = mysql_connect("hostname","username","password");
mysql_select_db("db1",$conn);
mysql_select_db("db2",$conn);
$query1 = "SELECT * FROM db1.table";
$query2 = "SELECT * FROM db2.table";
You can fetch data of above query from both database as below
$rs = mysql_query($query1);
while($row = mysql_fetch_assoc($rs)) {
$data1[] = $row;
}
$rs = mysql_query($query2);
while($row = mysql_fetch_assoc($rs)) {
$data2[] = $row;
}
print_r($data1);
print_r($data2);
$dbh1 = mysql_connect($hostname, $username, $password);
$dbh2 = mysql_connect($hostname, $username, $password, true);
mysql_select_db('database1', $dbh1);
mysql_select_db('database2',$dbh2);
mysql_query('select * from tablename', $dbh1);
mysql_query('select * from tablename', $dbh2);
This is the most obvious solution that I use but just remember, if the username / password for both the database is exactly same in the same host, this solution will always be using the first connection. So don't be confused that this is not working in such case. What you need to do is, create 2 different users for the 2 databases and it will work.
Unless you really need to have more than one instance of a PDO object in play, consider the following:
$con = new PDO('mysql:host=localhost', $username, $password,
array(PDO::ATTR_PERSISTENT => true));
Notice the absence of dbname= in the construction arguments.
When you connect to MySQL via a terminal or other tool, the database name is not needed off the bat. You can switch between databases by using the USE dbname statement via the PDO::exec() method.
$con->exec("USE someDatabase");
$con->exec("USE anotherDatabase");
Of course you may want to wrap this in a catch try statement.
You might be able to use MySQLi syntax, which would allow you to handle it better.
Define the database connections, then whenever you want to query one of the database, specify the right connection.
E.g.:
$Db1 = new mysqli('$DB_HOST','USERNAME','PASSWORD'); // 1st database connection
$Db2 = new mysqli('$DB_HOST','USERNAME','PASSWORD'); // 2nd database connection
Then to query them on the same page, use something like:
$query = $Db1->query("select * from tablename")
$query2 = $Db2->query("select * from tablename")
die("$Db1->error");
Changing to MySQLi in this way will help you.
You don't actually need select_db. You can send a query to two databases at the same time. First, give a grant to DB1 to select from DB2 by GRANT select ON DB2.* TO DB1#localhost;. Then, FLUSH PRIVILEGES;. Finally, you are able to do 'multiple-database query' like SELECT DB1.TABLE1.id, DB2.TABLE1.username FROM DB1,DB2 etc. (Don't forget that you need 'root' access to use grant command)
if you are using mysqli and have two db_connection file. like
first one is
define('HOST','localhost');
define('USER','user');
define('PASS','passs');
define('**DB1**','database_name1');
$connMitra = new mysqli(HOST, USER, PASS, **DB1**);
second one is
define('HOST','localhost');
define('USER','user');
define('PASS','passs');
define(**'DB2**','database_name1');
$connMitra = new mysqli(HOST, USER, PASS, **DB2**);
SO just change the name of parameter pass in mysqli like DB1 and DB2.
if you pass same parameter in mysqli suppose DB1 in both file then second database will no connect any more. So remember when you use two or more connection pass different parameter name in mysqli function
<?php
// Sapan Mohanty
// Skype:sapan.mohannty
//***********************************
$oldData = mysql_connect('localhost', 'DBUSER', 'DBPASS');
echo mysql_error();
$NewData = mysql_connect('localhost', 'DBUSER', 'DBPASS');
echo mysql_error();
mysql_select_db('OLDDBNAME', $oldData );
mysql_select_db('NEWDBNAME', $NewData );
$getAllTablesName = "SELECT table_name FROM information_schema.tables WHERE table_type = 'base table'";
$getAllTablesNameExe = mysql_query($getAllTablesName);
//echo mysql_error();
while ($dataTableName = mysql_fetch_object($getAllTablesNameExe)) {
$oldDataCount = mysql_query('select count(*) as noOfRecord from ' . $dataTableName->table_name, $oldData);
$oldDataCountResult = mysql_fetch_object($oldDataCount);
$newDataCount = mysql_query('select count(*) as noOfRecord from ' . $dataTableName->table_name, $NewData);
$newDataCountResult = mysql_fetch_object($newDataCount);
if ( $oldDataCountResult->noOfRecord != $newDataCountResult->noOfRecord ) {
echo "<br/><b>" . $dataTableName->table_name . "</b>";
echo " | Old: " . $oldDataCountResult->noOfRecord;
echo " | New: " . $newDataCountResult->noOfRecord;
if ($oldDataCountResult->noOfRecord < $newDataCountResult->noOfRecord) {
echo " | <font color='green'>*</font>";
} else {
echo " | <font color='red'>*</font>";
}
echo "<br/>----------------------------------------";
}
}
?>