gibberish data in utf8 columns while exporting sql database - php

I have used the db_backup function from PongoCMS to make the backup of the MySQL database. Almost all the columns in all the database tables are exported properly but on table columns with 'utf8' encoding (i've used utf8_unicode_ci collation), the exported data of that columns are filled with question marks.
Following is the function that I used:
public static function db_backup()
{
$type_db = Config::get('database.default');
$connections = Config::get('database.connections');
switch($type_db) {
case 'sqlite':
$file_name = $connections[$type_db]['database'] . '.' . $connections[$type_db]['driver'];
break;
case 'mysql':
$link = mysql_connect($connections[$type_db]['host'],$connections[$type_db]['username'],$connections[$type_db]['password']);
mysql_select_db($connections[$type_db]['database'],$link);
$tables = array();
$result = mysql_query('SHOW TABLES');
while($row = mysql_fetch_row($result))
{
$tables[] = $row[0];
}
//Set time now
$now = date('Y-m-d-H-i-s');
//File header
$return ="### DB BACKUP: " . $connections[$type_db]['database'] . " at " . $now . " ###\n\n\n";
//cycle through
foreach($tables as $table)
{
$result = mysql_query('SELECT * FROM '.$table);
$num_fields = mysql_num_fields($result);
$return.= 'DROP TABLE IF EXISTS '.$table.';';
$row2 = mysql_fetch_row(mysql_query('SHOW CREATE TABLE '.$table));
$return.= "\n\n".$row2[1].";\n\n";
for ($i = 0; $i < $num_fields; $i++)
{
while($row = mysql_fetch_row($result))
{
$return.= 'INSERT INTO '.$table.' VALUES(';
for($j=0; $j<$num_fields; $j++)
{
$row[$j] = addslashes($row[$j]);
$row[$j] = preg_replace("#\n#i","\\n",$row[$j]);
if (isset($row[$j])) { $return.= '"'.$row[$j].'"' ; } else { $return.= '""'; }
if ($j<($num_fields-1)) { $return.= ','; }
}
$return.= ");\n";
}
}
$return.="\n\n\n";
}
//save file
$file_name = 'db-backup-'.$now.'.sql';
$handle = fopen(path('storage') . 'database/' . $file_name, 'w+');
fwrite($handle, utf8_encode($return));
fclose($handle);
}
return $file_name;
}
However, if I export the database from phpmyadmin, the database is exported properly. What should be changed/added in the above function so that the function also exports the database properly?

Try execute DB query: "SET NAMES 'utf8'".
But it needs to be executed first! So, put next line in you script:
mysql_query("SET NAMES 'utf8'");
And keep in mind, this query must be very first query after "mysql_select_db"
Hope it will solve your issue, good luck!

Related

backup up db using php script and cron job

I'm using the script I posted below and it appeared to have worked based on the email and the fact it actually generated the file. However, It didn't backup anything.
Here is the output stored in the file it created:
SET FOREIGN_KEY_CHECKS=0;
SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";
SET AUTOCOMMIT=0;
START TRANSACTION;
SET FOREIGN_KEY_CHECKS=1;
COMMIT;
Here is the php script being used to generate the backup:
#!/usr/bin/php
<?php
backup_tables();
// backup all tables in db
function backup_tables()
{
$day_of_backup = ''; //possible values: `Monday` `Tuesday` `Wednesday` `Thursday` `Friday` `Saturday` `Sunday`
$backup_path = '/home/user/public_html/path/to/BACKUP.file/destination/'; //make sure it ends with "/"
$db_host = 'localhost';
$db_user = 'root';
$db_pass = 'replace_w_ur_password';
$db_name = 'replace_w_ur_db_name';
//set the correct date for filename
if (date('l') == $day_of_backup) {
$date = date("Y-m-d");
} else {
//set $date to the date when last backup had to occur
$datetime1 = date_create($day_of_backup);
$date = date("Y-m-d", strtotime($day_of_backup.'-1 days'));
}
if (!file_exists($backup_path.$date.'-backup'.'.sql')) {
//connect to db
$link = mysqli_connect($db_host,$db_user,$db_pass);
mysqli_set_charset($link,'utf8');
mysqli_select_db($link,$db_name);
//get all of the tables
$tables = array();
$result = mysqli_query($link, 'SHOW TABLES');
while($row = mysqli_fetch_row($result))
{
$tables[] = $row[0];
}
//disable foreign keys (to avoid errors)
$return = 'SET FOREIGN_KEY_CHECKS=0;' . "\r\n";
$return.= 'SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";' . "\r\n";
$return.= 'SET AUTOCOMMIT=0;' . "\r\n";
$return.= 'START TRANSACTION;' . "\r\n";
//cycle through
foreach($tables as $table)
{
$result = mysqli_query($link, 'SELECT * FROM '.$table);
$num_fields = mysqli_num_fields($result);
$num_rows = mysqli_num_rows($result);
$i_row = 0;
//$return.= 'DROP TABLE '.$table.';';
$row2 = mysqli_fetch_row(mysqli_query($link,'SHOW CREATE TABLE '.$table));
$return.= "\n\n".$row2[1].";\n\n";
if ($num_rows !== 0) {
$row3 = mysqli_fetch_fields($result);
$return.= 'INSERT INTO '.$table.'( ';
foreach ($row3 as $th)
{
$return.= '`'.$th->name.'`, ';
}
$return = substr($return, 0, -2);
$return.= ' ) VALUES';
for ($i = 0; $i < $num_fields; $i++)
{
while($row = mysqli_fetch_row($result))
{
$return.="\n(";
for($j=0; $j<$num_fields; $j++)
{
$row[$j] = addslashes($row[$j]);
$row[$j] = preg_replace("#\n#","\\n",$row[$j]);
if (isset($row[$j])) { $return.= '"'.$row[$j].'"' ; } else { $return.= '""'; }
if ($j<($num_fields-1)) { $return.= ','; }
}
if (++$i_row == $num_rows) {
$return.= ");"; // last row
} else {
$return.= "),"; // not last row
}
}
}
}
$return.="\n\n\n";
}
// enable foreign keys
$return .= 'SET FOREIGN_KEY_CHECKS=1;' . "\r\n";
$return.= 'COMMIT;';
//set file path
if (!is_dir($backup_path)) {
mkdir($backup_path, 0755, true);
}
//delete old file
//$old_date = date("Y-m-d", strtotime('-4 weeks', strtotime($date)));
//$old_file = $backup_path.$old_date.'-backup'.'.sql';
//if (file_exists($old_file)) unlink($old_file);
//save file
$handle = fopen($backup_path.$date.'-backup'.'.sql','w+');
fwrite($handle,$return);
fclose($handle);
}
}
?>
Any recommendations or leads on why it wouldn't actually backup all the tables would be greatly appreciated.

How to take backup of database in php?

I am doing some projects related to finance and for that i am using mysql database.Can any one suggest me how to take backup of database after each operation?
In this code, enter host, username, password, database or table name in first line : backup_tables('localhost','useranme','password','database_or_table_name');
You will get a file named db-backup....... in htdocs.
This works for me. Try This code:
<?php
// Enter database name here
backup_tables('localhost','useranme','password','database_or_table_name');
/* backup the db OR just a table */
function backup_tables($host,$user,$pass,$name,$tables = '*')
{
$link = mysql_connect($host,$user,$pass);
mysql_select_db($name,$link);
//get all of the tables
if($tables == '*')
{
$tables = array();
$result = mysql_query('SHOW TABLES');
while($row = mysql_fetch_row($result))
{
$tables[] = $row[0];
}
}
else
{
$tables = is_array($tables) ? $tables : explode(',',$tables);
}
//cycle through
$return = "";
foreach($tables as $table)
{
$result = mysql_query('SELECT * FROM '.$table);
$num_fields = mysql_num_fields($result);
$return.= 'DROP TABLE IF EXISTS '.$table.';';
$row2 = mysql_fetch_row(mysql_query('SHOW CREATE TABLE '.$table));
$return.= "\n\n".$row2[1].";\n\n";
for ($i = 0; $i < $num_fields; $i++)
{
while($row = mysql_fetch_row($result))
{
$return.= 'INSERT INTO '.$table.' VALUES(';
for($j=0; $j < $num_fields; $j++)
{
$row[$j] = addslashes($row[$j]);
$row[$j] = ereg_replace("\n","\\n",$row[$j]);
if (isset($row[$j])) { $return.= '"'.$row[$j].'"' ; } else { $return.= '""'; }
if ($j < ($num_fields-1)) { $return.= ','; }
}
$return.= ");\n";
}
}
$return.="\n\n\n";
}
//save file
$handle = fopen('db-backup-'.time().'-'.(md5(implode(',',$tables))).'.sql','w+');
fwrite($handle,$return);
fclose($handle);
}
?>

how to output a MYSQL Database Backup file without saving the file first?

I have the below script which is not working as it should:
The script should create a sql file for my database and output the file directly instead of saving it but instead i am getting an empty file!!
please help!
// Connect to database
$connection = #mysql_connect($server, $dbusername, $dbpassword) or die(mysql_error());
$db = #mysql_select_db($db_name,$connection) or die(mysql_error());
//get all of the tables
$tables = array();
$result = mysql_query('SHOW TABLES');
while($row = mysql_fetch_row($result))
{
$tables[] = $row[0];
}
//cycle through
foreach($tables as $table)
{
$result = mysql_query('SELECT * FROM '.$table);
$num_fields = mysql_num_fields($result);
$return.= 'DROP TABLE '.$table.';';
$row2 = mysql_fetch_row(mysql_query('SHOW CREATE TABLE '.$table));
$return.= "\n\n".$row2[1].";\n\n";
for ($i = 0; $i < $num_fields; $i++)
{
while($row = mysql_fetch_row($result))
{
$return.= 'INSERT INTO '.$table.' VALUES(';
for($j=0; $j<$num_fields; $j++)
{
$row[$j] = addslashes($row[$j]);
$row[$j] = str_replace("\n","\\n",$row[$j]);
if (isset($row[$j])) { $return.= '"'.$row[$j].'"' ; } else { $return.= '""'; }
if ($j<($num_fields-1)) { $return.= ','; }
}
$return.= ");\n";
}
}
$return.="\n\n\n";
}
$FileName = $db_name . '_' . date("d-m-y") . '.sql';
header('Content-Type: application/sql');
header("Content-length: " . filesize($NewFile));
header('Content-Disposition: attachment; filename="' . $FileName . '"');
echo $return;
exit();
Update #1: I cannot use mysqldump as i am on shared hosting and shell exec() is diabled
Just wrap around mysqldump:
<?=shell_exec("mysqldump -h $server -u $dbusername -p$dbpassword $db_name");?>
Note that you should really escape the variable terms of the command with escapeshellarg(), but I ommitted it for brevity.

Error backup sql database but succeed creating database dump file

I tried this following code to backup mysql database into file and it works perfectly create the .sql file I need.
function backup_tables()
{
$host='localhost';
$user='root';
$pass='';
$name='evote';
$tables = '*';
$link = mysql_connect($host,$user,$pass);
mysql_select_db($name,$link);
//get all of the tables
if($tables == '*')
{
$tables = array();
$result = mysql_query('SHOW TABLES');
while($row = mysql_fetch_row($result))
{
$tables[] = $row[0];
}
}
else
{
$tables = is_array($tables) ? $tables : explode(',',$tables);
}
//cycle through
foreach($tables as $table)
{
$result = mysql_query('SELECT * FROM '.$table);
$num_fields = mysql_num_fields($result);
$return.= 'DROP TABLE '.$table.';';
$row2 = mysql_fetch_row(mysql_query('SHOW CREATE TABLE '.$table));
$return.= "\n\n".$row2[1].";\n\n";
for ($i = 0; $i < $num_fields; $i++)
{
while($row = mysql_fetch_row($result))
{
$return.= 'INSERT INTO '.$table.' VALUES(';
for($j=0; $j<$num_fields; $j++)
{
$row[$j] = addslashes($row[$j]);
$row[$j] = str_replace("\n","\\n",$row[$j]);
if (isset($row[$j])) { $return.= '"'.$row[$j].'"' ; } else { $return.= '""'; }
if ($j<($num_fields-1)) { $return.= ','; }
}
$return.= ");\n";
}
}
$return.="\n\n\n";
}
//save file
$sql_name='db-backup.sql';
$handle = fopen($sql_name,'w+');
fwrite($handle,$return);
fclose($handle);
return $sql_name;
}
but it shows the error code :
A PHP Error was encountered
Severity: Notice
Message: Undefined variable: return
Filename: models/vote_m.php
can somebody tell me how to fix this?
The first time you reach this line;
$return.= 'DROP TABLE '.$table.';';
...$return has no value to append to. To get rid of the warning, you'll need to initialize $return (to an empty string probably) before starting the loop.

Backup an entire database with PHP/MYSQL

I am trying to perform php/mysql backups
I receive values from a form page and then with the command "select tables", i save those values in a array.
After that i do a "for" loop to backup each table:
<?php
$dbname = $_POST['txt_db_name'];
$tbname = $_POST['txt_tb_name'];
$ligacao=mysql_connect('localhost','root','')
or die ('Problemas na ligação ao Servidor de MySQL');
$res = mysql_query("SHOW TABLES FROM pessoal");
$tables = array();
mysql_select_db($dbname,$ligacao);
while($row = mysql_fetch_array($res, MYSQL_NUM)) {
$tables[] = "$row[0]";
}
$length = count($tables);
for ($i = 0; $i < $length; $i++) {
$query=
"SELECT * INTO OUTFILE 'pessoa_Out.txt'".
"FIELDS TERMINATED BY ',' ".
"ENCLOSED BY '\"'".
"LINES TERMINATED BY '#'".
"FROM $tables[$i]";
$resultado = mysql_query($query,$ligacao);
}
mysql_close();
if ($resultado)
$msg ='Sucesso na Exportaçao da Database '.$dbname.' ';
else
$msg ='Erro Impossivel Exportar a Database '.$tbname.' ';
?>
Don't do this — you are re-inventing existing tools!
Invoke mysqldump instead, which is expressly designed for the purpose.
With the proper permissions, you can use PHP's system or exec to invoke this.
First, I agree with the ones saying that mysqldump should be used for this. But basing on your comment that you just need it to be done with php/mysql for educational (or whatever) purposes, here is the script (yep, it re-invents the wheel). Note that you should create a backup directory in the folder where you upload this and allow web server to write to it :
<?php
error_reporting(E_ALL);
ini_set('display_errors',1);
ini_set('memory_limit','1500M');
set_time_limit(0);
backup_tables('localhost','user','xxxxxxx','xxxxxxxxxx');
/* backup the db OR just a table */
function backup_tables($host,$user,$pass,$name,$tables = '*')
{
//save file
$handle = gzopen(getcwd() . DIRECTORY_SEPARATOR . 'backup' . DIRECTORY_SEPARATOR . 'db-backup-'.time().'.sql.gz','w9');
$link = mysql_connect($host,$user,$pass);
mysql_select_db($name,$link);
//get all of the tables
if($tables == '*')
{
$tables = array();
$result = mysql_query('SHOW TABLES');
while($row = mysql_fetch_row($result))
{
$tables[] = $row[0];
}
}
else
{
$tables = is_array($tables) ? $tables : explode(',',$tables);
}
//cycle through
foreach($tables as $table)
{
$result = mysql_query('SELECT * FROM '.$table);
$num_fields = mysql_num_fields($result);
$return = 'DROP TABLE IF EXISTS '.$table.';';
$row2 = mysql_fetch_row(mysql_query('SHOW CREATE TABLE '.$table));
$return .= "\n\n".$row2[1].";\n\n";
gzwrite($handle,$return);
for ($i = 0; $i < $num_fields; $i++)
{
while($row = mysql_fetch_row($result))
{
$return = 'INSERT INTO '.$table.' VALUES(';
for($j=0; $j<$num_fields; $j++)
{
$row[$j] = addslashes($row[$j]);
$row[$j] = str_replace("\n","\\n",$row[$j]);
if (isset($row[$j])) { $return.= '"'.$row[$j].'"' ; } else { $return.= '""'; }
if ($j<($num_fields-1)) { $return.= ','; }
}
$return.= ");\n";
gzwrite($handle,$return);
}
}
$return ="\n\n\n";
gzwrite($handle,$return);
}
gzclose($handle);
}

Categories