Working with multiple databases in php/mysql - php

I am working on a project needing me to work with multiple database connections. From what I have read, I should be able to switch between connections in the query itself, something like:
mysql_query("SELECT * FROM user_types", $db_core)or die(mysql_error());
But I receive the error:
Table 'db_company.user_types' doesn't exist
So I can see it is looking at the incorrect db, it is grabbing the last mysql_select_db
I wouldn't want to have to re-select the database everytime but if that is the better way to go I can.
I have the databases selected like so:
<?
$currentpage = $_SERVER["REQUEST_URI"];
//Core DB
$db_core_host = "localhost";
$db_core_username = "root";
$db_core_password = "";
$db_core_name = "db_main";
//
$db_core = mysql_connect($db_core_host,$db_core_username,$db_core_password);
mysql_select_db($db_core_name, $db_core)or die(mysql_error());
//Company DB
$db_company_host = $company['db_server'];
$db_company_username = $company['db_username'];
$db_company_password = $company['db_password'];
$db_company_name = $company['db_name'];
//
$db_company = mysql_connect($db_company_host,$db_company_username,$db_company_password);
mysql_select_db($db_company_name, $db_company)or die(mysql_error());
?>
Not sure if it helps at all but when I echo either of the database connections I get Resource id #5

Use the db.table syntax in the query:
mysql_query("SELECT * FROM databas_ename.table_name", $db_core) or die(mysql_error());

The code you have in your question should work, except when both databases are on the same server. Take a look at the $new_link parameter of mysql_connect (see docs here): if you call it twice with the same server/user/pass, the connection will be re-used - which makes you end up with the mysql_select_db call on one connection influence the other one.
So if you have two different servers, or set $new_link to true, your code should work.

Related

Pros and cons of connecting more than one database in single script

Let's say user have two databases hosted on single host and I need to connect to both of them so that I can use any table anytime without adding connection code multiple times.
I have implemented this in CodeIgniter with adding authorization details of both databases in database.php file and to load required database with $this->load->database('dbname'); in script.
Now, for core PHP, we can do this like:
mysql_connect ('host','user','password','port','dbname'); // connection with one database.
It was connected with my first database.
Now, I want to connect with second database:
1) I have not closed above connection and connected with second one with
mysql_connect ('host','user','password','port','dbname1');.
2) Would it be bad practice to do so ? Would it consume more objects ? Should we be required to close first one anyhow?
It is not neccessary to open 2 connection just to use tables from 2 databases on the same server. You just need to use the database.table notation. Doing that means that you can even join tables from different databases in the same query
SELECT t1.col1, t1.col2, t2.col2, t2.col2
FROM db1.table1 AS t1 JOIN db2.table1 AS t2 ON t1.col1 = t2.col3
So if you have connected to db1 initially you can use db2 tables and the same if you connected to db2 you can use db1 tables.
Have you tried this?
$mysqli1 = new mysqli("example.com", "user", "password", "database1");
$mysqli2 = new mysqli("example.com", "user", "password", "database2");
Why do you need two connections? The pros/advantages of two databases are actually primarily performance issues. But if you are on the same machine actually the only advantage you have, would be a cleaner separation. So it would be better to use one DB with two different prefixes for the table.
So you seperate the diffent data by prefix and not by DB.
You can do this by following object oriented approach
First of all create connection with two databases:
$Db1 = new mysqli('localhost','root','','database1'); // this is object of database 1
$Db2 = new mysqli('localhost','root','','database2'); // this is object of database 2
$query1 = 'select * from `table_name_of_database1`'; // Query to be run on DB1
$query2 = 'select * from `table_name_of_database2`'; // Query to be run on DB2
$result1 = $Db1->query($query1); // Executing query on database1 by using $Db1
$result2 = $Db2->query($query2); // Executing query on database2 by using $Db2
echo "<pre>";
/* Print result of $query1 */
if ($result1->num_rows > 0) {
while($row = $result1->fetch_assoc()) {
print_r($row);
}
} else {
echo "0 results";
}
/*========================================================*/
/* Print result of $query2 */
if ($result2->num_rows > 0) {
while($row = $result2->fetch_assoc()) {
print_r($row);
}
} else {
echo "0 results";
}
Conclusion: When you want to use database1 use $Db1 object and if you want to use database2 then use $DB2.
I don't think how to connect to 2 DBs simultaneously is the problem, as you have successfully done it ( or know how to do it ). I can gather that from your question. So I won't show how to do this. See other answers if you need to.
But to address your issues directly:
Would it be bad practice to do so ? Generally, you should avoid 2 simultaneous DB connection handles as much as possible. If you only need to get data from one DB and use them to do something on the other, your best bet is to put the data from DB1 into appropriate PHP variables, close the connection; then make the second connection. That would be cheaper than keeping 2 DB connections open at the same time. However, if you are doing something like INSERT INTO db1.table SELECT FROM db2.table AND ALSO NEED TO COMMIT OR ROLLBACK depending on success or failure of some queries, then AFAIK, you need to keep both connections open until your processes are over. You see, there always trade-offs. So you decide based on the need of your application and bear the cost.
As a practical example of this scenario, I once worked on a project where I needed to SELECT a table1, INSERT INTO a table2, if the INSERT succeeds, I delete all the rows from table1, if the DELETE fails, I rollback the INSERT operation because the data cannot live in the two tables at the same time.
Of course, my own case involved only one DB, so no need of a second connection. But assuming the two tables were on different DBs, then that may be similar to your situation.
Would it consume more objects ? No other objects other than the ones pointed out in 1 above, namely the DB connection handles according to your question.
Should we compulsory require to close first one anyhow ? Once again, depending on your application needs.
Instead of mysql_connect use mysqli_connect.
mysqli is provide a functionality for connect multiple database at a time.
Q: What cons are there to connect with other database without closing previous database?
A: When you connect to a database server physically are assigning resources to interact with you, if two databases are on the same server you would unnecessarily using resources that could be used to address other connections or other activities. Therefore you would be right close connections that do not need to continue using.
Q: Is this a appropriate practice to do so ? What is the best way to do so without opening this connection in every script multiple times ? I want this to get done in core php only as I have already know this in codeigniter.
One way SESSIONS, but you can't store database conections in sessions. Read in PHP.net this Warning: "Some types of data can not be serialized thus stored in sessions. It includes resource variables or objects with circular references (i.e. objects which passes a reference to itself to another object)." MySQL connections are one such kind of resource.
You have to reconnect on each page run.
This is not as bad as it sounds if you can rely on connection pooling via mysql_pconnect(). When connecting, the function would first try to find a (persistent) link that's already open with the same host, username and password. If one is found, an identifier for it will be returned instead of opening a new connection. The connection to the SQL server will not be closed when the execution of the script ends. Instead, the link will remain open for future use (mysql_close() will not close links established by mysql_pconnect()).
Reference:
http://php.net/manual/en/function.mysql-pconnect.php
http://www.php.net/manual/en/intro.session.php
Can't pass mysqli connection in session in php
1) Is it possible to connect with more than one database in one script ?
Yes we can create multiple MySQL link identifier in a same script.
2) It should be not like to close one connection with mysql_close and open new one,rather both connection should open at a time and user can use any table from any of the database ?
Use Persistent Database Connections like mysql_pconnect
3) If it is possible,what can be disadvantage of this ? Will there create two object and this will going to create issue ?
I don't think so it create any issue other than increasing some load on server.
You can use like this
$db1 = mysql_connect($hostname, $username, $password);
$db2 = mysql_connect($hostname, $username, $password, true);
mysql_select_db('abc', $db1);
mysql_select_db('def', $db2);
For Database 1
mysql_query('select * from table1', $db1);
For Database 2
mysql_query('select * from table2', $db2);
The best way to use multiple databases is to use PDO functions
EXAMPLE
// database cobfigurations
$config= array(
// first database
array(
'type'=>'mysql', // DB type
'host'=>'localhost', // DB host
'dbname'=>'database1', // DB name
'user'=>'root', // DB username
'pass'=>'12345', // DB password
),
// second database
array(
'type'=>'mysql', // DB type
'host'=>'localhost', // DB host
'dbname'=>'database2', // DB name
'user'=>'root', // DB username
'pass'=>'987654', // DB password
),
);
// database connections
$mysql=array();
foreach($config as $con)
{
$con=(object)$con;
$start= new PDO($con->type.':host='.$con->host.';dbname='.$con->dbname.'', $con->user, $con->pass, array(
// pdo setup
PDO::ATTR_PERSISTENT => FALSE,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_OBJ,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES UTF8'
));
if ($start && !empty($start) && !is_resource($start))
$mysql[]=$start; // connection is OK prepare objects
else
$mysql[]=false; // connection is NOT OK, return false
}
/**********************
**** HOW TO USE ****
**********************/
// fetch data from database 1
$data1 = $mysql[0]->query("SELECT id, title, text FROM content1")->fetchAll();
if(count($data1)>0)
{
foreach($data1 as $i=>$result)
{
echo $result->id.' '.$result->title.' '.$result->text.'<br>'
}
}
// fetch data from database 2
$data2 = $mysql[1]->query("SELECT id, title, text FROM content2")->fetchAll();
if(count($data2)>0)
{
foreach($data2 as $i=>$result)
{
echo $result->id.' '.$result->title.' '.$result->text.'<br>'
}
}
If you not use PDO before, please read this short tutorial:
http://www.mysqltutorial.org/php-querying-data-from-mysql-table/
Is practicly same like mysql and mysqli connections but is more advanced, fast and secure.
Read this documentations:
http://php.net/manual/en/book.pdo.php
And you can add more then 2 databases
Use PDO supported by php 5 version instead mysql connect
Here is a simple class that selects the required database automatically when needed.
class Database
{
private $host = 'host';
private $user = 'root';
private $pass = 'pass';
private $dbname = '';
private $mysqli = null;
function __construct()
{
// dbname is not defined in constructor
$this->mysqli = new mysqli( $this->host, $this->user, $this->pass );
}
function __get( $dbname )
{
// if dbname is different, and select_db() is succesfull, save current dbname
if ( $this->dbname !== $dbname && $this->mysqli->select_db( $dbname ) ) {
$this->dbname = $dbname;
}
// return connection
return $this->mysqli;
}
}
// examples
$db = new Database();
$result = $db->db1->query( "SELECT DATABASE()" );
print_r( $result->fetch_row() );
$result = $db->db2->query( "SELECT DATABASE()" );
print_r( $result->fetch_row() );
$result = $db->{'dbname with spaces'}->query( "SELECT DATABASE()" );
print_r( $result->fetch_row() );
$con1 = mysql_connect($hostname, $username, $password);
$con2 = mysql_connect($hostname, $username, $password, true);
mysql_select_db('database1', $con1);
mysql_select_db('database2', $con2);
Then to query database 1 pass the first link identifier:
mysql_query('select * from tablename', $con1);
and for database 2 pass the second:
mysql_query('select * from tablename', $con2);
if mysql's user have permission to two database , you can join two table from two database
etc:
SELECT database1.table.title title1,database2.table.title title2
FROM database1.table
INNER JOIN database2.table
ON (database1.table.id=database2.table.id)

Select Number of Values in Database Column

I have a mySQL table called palettes, and I want to return the number of links in the table. Basically, I want to return the number of values in the link column. (In this case, 6).
I tried using this code, but it didn't work. I'm a front-end dev, with NO knowledge of php or anything..
include "mysql.php";
$select_rows = $mysqli->query("SELECT COUNT(link) FROM palettes");
$rows = mysqli_fetch_array($select_rows);
$total = $rows[0];
echo $total;
The above code should or echoed 6, right? Selecting from column link
This is what my table looks like:
Use the WHERE clause with LIKE 'http%' and change your query to count id's that fit:
First, I'll assume your file 'mysql.php' has a connection to the database somewhere in the file like this:
<?php
if (session_status() !== PHP_SESSION_ACTIVE) {session_start();}
$hostname = 'localhost';
$dbname = 'myDatabaseName';
$username = 'admin';
$password = 'myPassword';
$cxn = mysqli_connect($hostname, $username, $password, $dbname) or DIE('Connection to host is failed, perhaps the service is down!');
?>//End connect.php
Now you can try this:
include 'mysql.php';
$select_rows = mysqli_num_rows(mysqli_query($cxn, "SELECT id FROM palettes WHERE link LIKE 'http%'"));
echo $select_rows; //Should = 6
I would say place NULL in case you don't have the link available:
You can do it by making the Link column to allow NULL as default. You can make use of the COUNT(Link) in that case. This is recommended.
If you have to have empty string instead of NULLs.
select sum(if(Link != "",1,0)) counting from palettes;
Or if you can make sure all the links start with http/https
select sum(if(Link like "http%",1,0)) counting from palettes;

Transferred to new hosting/server - Now having issues with using MySQL for form validation

I'm having a lot of problems with the new hosting, but the more I look at it, it seems that they're all related to doing checks in my database when validating logins, registrations, and submissions. Here's an example of one.
I use jQuery to validate forms. One I use to determine if a username actually exists when a user is trying to log in (don't worry, I also check server side). On my development server, this works flawlessly. If you're not familiar with jQuery Validation, basically this returns a true or false back to the server in a form of some kind of JSON, but I'm not entirely knowledgeable on that part.
The code:
//Database Information vars (removed)
mysql_connect ($dbhost, $dbuser, $dbpass)or die("Could not connect: ".mysql_error());
mysql_select_db($dbname) or die(mysql_error());
$username = mysql_real_escape_string($login_username); // In validation, I can grab inputs like this.
$query = "SELECT username FROM registerusers WHERE username='$username';";
$res = mysql_query($query);
if (mysql_num_rows($res) > 0) {
$output = true;
} else {
$output = false;
}
echo json_encode($output);
The problem with this is that it always refers to the first clause and returns true, even if the username does not exist. For whatever reason, I think it's always returning 1 for mysql_num_rows($res).
This EXACT code (except for new database vars which I've checked a hundred times to be accurate) works as intended on my development server still. I can only assume that it has something to do with the new server, and that's why I'm asking Stack Overflow, because I have no clue.
The problem is that register_globals is enabled.
This poses a high security problem which is why it is disabled and deprecated.
Changing $login_username to $_GET['login_username']solves the problem.
Using the $_GET and $_POST super global arrays is not a security problem, but you should always sanitize your input (like you do with mysql_real_escape_string()).
Have you tried setting the MySQL connection to a variable, then calling the connection variable as the second parameter inside of the mysql_query? This has sometimes given me an issue on some servers, especially if they have certain debugging methods, errors, and warnings shut off by default:
//Database Information vars (removed)
$connect = mysql_connect ($dbhost, $dbuser, $dbpass) or die("Could not connect: ".mysql_error());
mysql_select_db($dbname) or die(mysql_error());
$username = mysql_real_escape_string($login_username); // In validation, I can grab inputs like this.
$query = "SELECT `username` FROM `registerusers` WHERE `username` = '".$username."';";
$res = mysql_query($query, $connect);
if (mysql_num_rows($res) > 0) {
$output = true;
} else {
$output = false;
}
echo json_encode($output);
I've also changed the $query to a concatenated string with the variable, as some servers I have worked on sometimes are finicky in terms of putting variables inside of a string without delimiting them with "..".

How does one implement a MySQL database into a webpage?

I am a complete database newbie. So far, I know that I can connect to MySQL using PHP's mysql_connect() command, but apart from that, I really don't see how to take that data and put it onto a web page.
a) are there ways other than mysql_connect()
b) lets say I had a table of data in mysql and all I wanted was for that table (for example: list of names and telephone numbers) to now appear on my web page. I can't for the life of me find a tutorial for this.
<?
$database_name = "dbname";
$mysql_host = "localhost"; //almost always 'localhost'
$database_user = "dbuser";
$database_pwd = "dbpass";
$dbc = mysql_connect($mysql_host, $database_user, $database_pwd);
if(!$dbc)
{
die("We are currently experiencing very heavy traffic to our site, please be patient and try again shortly.");
}
$db = mysql_select_db($database_name);
if(!$db)
{
die("Failed to connect to database - check your database name.");
}
$sql = "SELECT * FROM `table` WHERE `field`= 'value'";
$res = mysql_query($sql);
while($row = mysql_fetch_assoc($res)) {
// code here
// access variables like the following:
echo $row['field'].'<br />';
echo $row['field2'];
}
?>
Check out mysql_fetch_assoc mysql_fetch_array and mysql_fetch_object
This is the very basics, you will want to search for tutorials. There are many about.

my insert query is working in my localhost but not in web server

I am using flex builder 3 to insert into mysql database using php and everything is working perfectly in my localhost, the problem is when I deploy the project in the web server and run it, it connect to the database but i can't insert data ( it shows nothing when i insert data )
another stupid thing is in another piece of code for retrieving (select) data that works good on both my localhost and web server.
here is the php code:
<?php
$host = "******";
$user = "******";
$pass = "******";
$database = "******";
$linkID = mysql_connect($host, $user, $pass) or die("Could not connect to host.");
mysql_select_db($database, $linkID) or die("Could not find database.");
$nickname = $_POST['nickname'];
$steam = $_POST['steam'];
$c1 = $_POST['c1'];
$c2 = $_POST['c2'];
$c3 = $_POST['c3'];
$results = mysql_query("INSERT INTO `phantom`.`members` (`TF2_Nickname` ,`Steam_User_Name`,
`class1` ,`class2` ,`class3` ,`time`) VALUES ($nickname, $steam, $c1, $c2, $c3,NOW())");
?>
You need to declare the values as strings in your MySQL query as well:
"INSERT INTO `phantom`.`members` (`TF2_Nickname`, `Steam_User_Name`, `class1`, `class2`, `class3`, `time`)
VALUES ('$nickname', '$steam', '$c1', '$c2', '$c3', NOW())"
And you should also prepare them in some way to avoid that they are mistakenly treated as SQL command (see SQL Injection). PHP has the mysql_real_escape_string function to do that:
"INSERT INTO `phantom`.`members` (`TF2_Nickname`, `Steam_User_Name`, `class1`, `class2`, `class3`, `time`)
VALUES ('".mysql_real_escape_string($nickname)."', '".mysql_real_escape_string($steam)."', '".mysql_real_escape_string($c1)."', '".mysql_real_escape_string($c2)."', '".mysql_real_escape_string($c3)."', NOW())"
Insert into requires either user right or admin right. Check if by chance You didnt modify somewhere in the code these rights, e.g., You changed by hand the name of your admin... If it works the select it is because selecting doesnt need so many rights. Even non user status can retrieve info through select but insert needs special rights. You know your code so think about this difference

Categories