Transfer mysql table between two databases with PDO - php

I have been researching this for the past hour, and yet to come up with a simple solution that doesnt involve some weird exports/imports.
All I am trying to do is open up a PDO connection with two databases so that I can use them both in queries.
It seems that there is disagreements in Stack Overflow about this.
One answer:
...you will need to create two PDO objects for the seperate
connections if you would like to use both at runtime.
But others seem to suggest you can just "use" two databases in your query:
$sql = "SELECT * FROM dbname.tablename";
$sql = "SELECT * FROM anotherdbname.anothertablename"
I tried preforming a SELECT command on another database besides the one explicitly defined in my PDO connection function. I got this:
Fatal error: Uncaught exception 'PDOException' with message
'SQLSTATE[42000]: Syntax error or access violation: 1142 SELECT
command denied to user 'dbusername'#'localhost' for table
'table_name'
I made sure to add the user to both databases and grant full privileges.
Is a query that uses two databases in the same connection possible? Or do you have to setup two different objects?

"a PDO connection with two databases" (singular form) is a misnomer, because by definition a PDO connection is a single connection to a single data store. If you want two connections, you will need to instantiate two instances.

Turns out preforming a query across two databases is possible with a single PDO connection. Even though one database is defined in my PDO initiation, I still have access to another database.
The solution is to make both databases have the same credentials.
function db_connect(){
$host = 'localhost';
$port = 3306; // This is the default port for MySQL
$database = 'db1';
$username = 'user';
$password = 'pass';
$dsn = "mysql:host=$host;port=$port;dbname=$database";
$db = new PDO($dsn, $username, $password);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
return $db;
}
$db=db_connect();
$statement = $db->prepare("SELECT * FROM db2.table LIMIT 1");
$statement->execute();
$x=$statement->fetchObject();
var_dump($x); //A full row from the table was the output.

I made sure to add the user to both databases and grant full privileges.
The error message is quite unambiguous. Reading this, I wouldn't be so sure.
Anyway, to answer the title question:
Why not to just run this simple query from the console?
INSERT INTO db2.table SELECT * FROM db1.table;
It will not only transfer your data but also will prove if your users have sufficient rights or not.
If not - you have to really make sure that.

Related

mysqli_insert_id() is returning 0 but inserting the data

The Code is:
class anything_i
{
/*Every variable is defined and hidden fro privacy.*/
public function connect(){
return mysqli_connect(self::HOST,self::USERNAME,self::PASSWORD,self::DATBASE);
}
public function insertData($postData){
$sqli = 'INSERT INTO `payments`(`item_name`,`price`,`email`,`date`,`time`,`detail`,`volume`,`ip`,`payment_status`) VALUES ("'.$productData['name'].'","'.$productData['price'].'","'.$postData['email'].'","'.$date.'","'.$time.'","'.$postData['list'].'","'.$productData['volume'].'","'.$ip.'","On Hold")';
if(mysqli_query($this->connect(),$sqli)){
print_r(mysqli_insert_id($this->connect()));
}else{
print_r(mysqli_error($this->connect()));
}
}
}
It is inserting the data and working fine but does not return anything other than a 0 (zero) not getting any error.
Let me clear that my table contains auto_increment and my connection is fine because it is entering data just fine. Please don't disregard the question because you found similar once answered. I also found similar questions but most of them have connection problems, some of them the no AUTO_INCREMENT column and there may be some which included another query in between. So, please read it before mentioning another answer.
Here is the proof of AUTO_INCREMENT:
I suspect this code has been migrated from the legacy mysql extension where mysql_connect():
Opens or reuses a connection to a MySQL server.
This is no longer the case with mysqli_connect():
Opens a connection to the MySQL Server.
You really need to store the connection in a variable and reuse that same connection. Currently you're starting many different connections within the same script run.
When you call mysqli_connect() it will create a new connection each time. It does not reuse the previous connection. When a new connection is created all the properties of the old one are lost.
You are calling mysqli_connect() every time you call $this->connect() so you will never get the errors or the auto-generated ID.
mysqli connection should be global to your application. It does not make sense to keep recreating the same connection because it will lead to terrible performance issues and it will cause you problems like this one. If you are using dependency injection it should be easy to create the mysqli at the start of your application and then pass it as an argument to your class' constructor.
Connecting to the database using mysqli is always the same 3 lines of code. Only the details you pass as arguments are different.
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$mysqli = new mysqli('localhost', 'user', 'pass', 'db_name');
$mysqli->set_charset('utf8mb4'); // always set the charset
You can then pass this to your constructor whenever you create an object and store it in a private property.
Your fixed code would like this:
<?php
class anything_i {
private mysqli $db = null;
public function connect(mysqli $db) {
$this->db = $db;
}
public function insertData($postData) {
/*
...
*/
$stmt = $this->db->prepare('INSERT INTO `payments`(`item_name`,`price`,`email`,`date`,`time`,`detail`,`volume`,`ip`,`payment_status`) VALUES (?,?,?,?,?,?,?,"On Hold")');
$stmt->bind_param('ssssssss', $productData['name'], $productData['price'], $postData['email'], $date, $time, $postData['list'], $productData['volume'], $ip);
$stmt->execute();
}
}
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$mysqli = new mysqli('localhost', 'inet', '5432', 'test');
$mysqli->set_charset('utf8mb4'); // always set the charset
$obj = new anything_i($mysqli);

How do I check the DB connection

I have host, database name, username and the password given as form inputs like:
$form['dbname']->getData()
I need to check if these data is correct for the mysql connection. So I chose to use mysql_connect() to check this:
$conn = mysql_connect($form['host']->getData(), $form['username']->getData(), $form['password']->getData(), $form['dbname']->getData());
if($conn) // ...
else // ...
But it displays some mysql_connect() warning with no other specific message...
What's wrong? Does the symfony 2 has any mechanism to check the connection?
Symfony uses repositories and entities to manage the database. The programmer doesn't manipulate the connection itself (Doctrine).
You could try to check a connection using PDO. Try to instance a PDO Object, and catch exceptions (PDOException for connection errors). However, you're "breaking" the framework's philosophy, trying to initiate an "extern" DB connection. If you need to work with several connections in Symfony, I suggest this reference :
http://symfony.com/doc/current/cookbook/doctrine/multiple_entity_managers.html
use the following format to receive the connection error if there is any.
$con = mysql_query() or die(mysql_error());

Call controller from controller in PHP MVC? [duplicate]

This question already has answers here:
Closed 10 years ago.
Can i call admin panel controller from account controller?
I mean in account controller i set acessible parts of admin panel and i want to transfer that variable with accessible place to admin panel controller.
and now can i do sth like:
<?php
// Code here
$this->panel = new Admin_Panel();
$this->panel->accessibleparts = $this->data['accessible'];
?>
Or is it disallowed in mvc rules?
Stuff like this:
public function connect(){
try {
$db = new PDO('mysql:host=localhost;dbname=radiolev_db', 'radiolev_user', 'ceowwyso1');
is all fine and dandy, but you're not actually storing that database connection object anywhere in your object. It's just a local variable in that particular method, and will be destroyed when the function exits. e.g. you're connecting, then as soon as your connct() method returns, the local $db variable goes out of scope, and your brand new database connection is closed and destroyed.
You need to store that $db in your OWN object, so it'll be preserved for later use, e.g:
$this->db = new PDO(...);
instead.
And as everyone else above has said, you cannot mix mysql_(), mysqli_(), and PDO connections with each other. Each is a completely distinct and separate library (even though they all use the same underlying mysql low-level library). A connection established in one of those is completely distinct/separate/unusuable by the other libraries. Since you're using PDO to connect, you cannot use mysql_ functions, because mysql_ has no knowledge of anything going on in PDO.
The answer is read about how it works in the manual: http://php.net/oop5
Answer to your previous question:
You get the following errors:
Warning: mysql_real_escape_string() [function.mysql-real-escape-string]: Access denied for user 'radiolev'#'localhost' (using password: NO) in /home/radiolev/public_html/top/toplist.class.php on line 10
Warning: mysql_real_escape_string() [function.mysql-real-escape-string]: A link to the server could not be established in /home/radiolev/public_html/top/toplist.class.php on line 10
You then ask:
I don't understand why it appears cause the mysql passwords are good.
No worries. You just made a little mistake. The mistake is that you make use of the function mysql_real_escape_string while not using a connection of the mysql_* extensions (note: extension, not database server).
In case you're calling that function without establishing a mysql_* extension database connection, PHP will automatically create one based on the settings provided in php.ini. That is normally only the host set to localhost - but wihout username and password.
This is why you see the first error that the connection fails and the second error is the result of the failed connection - there is no link to the databse, so ?mysql_real_escape_string can not work.
To solve the problem, just do not use mysql_real_escape_string when you're using mysql via PDO. Prepared statements is all you need.
Your problem is that mysql_real_escape_string() expects a connection (which you have made, just not using the mysql_* subset of commands).
Use PDO, and actual prepared statements, not whatever it is you're doing now.
$pdo = $conn->prepare('SELECT * FROM myTable WHERE theColumn = :myParam');
$pdo->bindParam(':myParam', $_GET['data']);
$pdo->execute();
By 'call' I assume you mean use it.
Just add a return value, return $db; -- This would be at the end of your connect(), after the error mode was set.
Now
$db = new mysql();
$conn = $db->connect();
$conn->prepare('SELECT * FROM myTable WHERE myColumn = ?');
$conn->execute(array('test'));
Replace mysql_real_escape_string with PDO's quote or bindValue
You are getting a bunch of errors because mysql_real_escape_string is trying to use the last open connection used by mysql_connect (as explained in the PHP Manual). Since you are using PDO instead of the mysql_* functions, there is no connection and mysql_real_escape_string is throwing an error.

Access denied error when using mysql_real_escape_string()

i am trying escape some data before it goes into my database, but i keep getting this error:
Warning: mysql_real_escape_string(): Access denied for user
Now this would usually suggest that i have not connected to the database (it also states (using password: NO)).
I was a little confused by this because when connecting to a database i have a 'die' clause so if it fails to connect i get told about it. So i tested this theory by running a simple query in the same function that im trying to escape the data and it works just fine.
So why on earth won't the escape method work or get a connection to the database. I did notice that the user the error states is not the user i use to access the database its something like 'www-data#localhost'. Could it be trying to log in with a different user, if so why and how? Because i another area of my website the escape function works just fine and i didn't do anything special to make it work, just added the code into my web page.
thanks for the help.
Are there any other ways of sanitizing my code?
Okay, so here we go, when the user submits the form, i use AJAX to collect the data and put it into an obj to post(JSON encoding) it to the first PHP script which is here:
http://codepad.org/kGPljN4I
This script checks all the data is there and then calls a function to add it to the database
this Mysql class is called to escape the data and then add a new record to the database, when and instance of the class is made it makes a connection to the database:
http://codepad.org/wwGNrTJm
The third file is for constants, it holds the information for the database like pass, user and so on:
http://codepad.org/dl0QQbi9
any better?
thanks again for the help.
The problem is that you have established your connection using MySQLi, but are then calling mysql_real_escape_string(). You intend to be calling mysqli_real_escape_string() either in procedural context, or object oriented contex.
class Mysql
{
private $conn;
function __construct()
{
$this->conn = new mysqli(DB_SERVER, DB_USER, DB_PASSWORD, DB_NAME) or
die('No Connection to database!');
}
function add_non_member($data)
{
$email = $data->email;
// Procedural call
$san_email = mysqli_real_escape_string($this->conn, $email);
// Or OO call (recommended)
$san_email = $this->conn->real_escape_string($email);
// etc...
}
// etc...;
}
You're mixing ext/mysqli
$this->conn = new mysqli(DB_SERVER, DB_USER, DB_PASSWORD, DB_NAME
with ext/mysql functions:
$san_email = mysql_real_escape_string($email);
that last line should be
$san_email = $this->conn->real_escape_string($email);
I also got this access denied warning and I was able to find the solution. The problem is that I have not setup mysql db connection before calling mysql_real_escape_string function.
Solution:
Call mysql_connect($host, $user, $password) first (Or you can call your database connect function)
Then use mysql_real_escape_string($var)

PHP/PDO - Flush privileges

I'm doing some mysql server management with a script that flushes the MySQL users privileges when new privileges are added to a MySQL user.
I'm using the PDO class to do my queries, but when I do a simple
FLUSH PRIVILEGES;
I get, for
$connection->exec('FLUSH PRIVILEGES;');
and
$connection->query('FLUSH PRIVILEGES;');
SQLSTATE[42S02]: Base table or view
not found: 1146 Table 'mysql.servers'
doesn't exist
Is it possible to do such query with the PDO class or do I have to resort to using mysql(i)?
I've just tried the following portion of code :
$dsn = 'mysql:dbname=mysql;host=127.0.0.1';
$user = 'root';
$password = '********';
try {
$db = new PDO($dsn, $user, $password);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$db->query('flush privileges;');
} catch (PDOException $e) {
var_dump($e);
}
And I don't get any kind of error like the one you are describing.
Are you sure you don't have some problem with you MySQL server ?
Your error message says that table "mysql.servers" doesn't exists... But when I look at my local MySQL server, there is such a table -- are you sure your installation/configuration is not "broken" and you didn't delete that table or anything like that ?
BTW, it doesn't seem to be some kind of privilege you're not having : if you try to flush privileges without having the required privilege, you get the following error : "SQLSTATE[42000]: Syntax error or access violation: 1227 Access denied; you need the RELOAD privilege for this operation"

Categories