Reputation: 492
I have viewed all the topics available for this question , but not getting any acurate answer... anybody got clear idea to backup the current database in .sql file and download it ?
Upvotes: 11
Views: 26172
Reputation: 1
I have optimized my code @Abdelhakim Ezzahraoui
//ENTER THE RELEVANT INFO BELOW
$mysqlHostName = env('DB_HOST');
$mysqlUserName = env('DB_USERNAME');
$mysqlPassword = env('DB_PASSWORD');
$DbName = env('DB_DATABASE');
$tables = array();
$connect = new \PDO("mysql:host=$mysqlHostName;dbname=$DbName;charset=utf8", "$mysqlUserName", "$mysqlPassword", array(\PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'utf8'"));
$get_all_table_query = "SHOW TABLES";
$statement = $connect->prepare($get_all_table_query);
$statement->execute();
$result = $statement->fetchAll();
$prep = "Tables_in_$DbName";
foreach ($result as $res) {
$tables[] = $res[$prep];
}
$output = '';
$alterStatements = [];
foreach ($tables as $table) {
$show_table_query = "SHOW CREATE TABLE " . $table . "";
$statement = $connect->prepare($show_table_query);
$statement->execute();
$show_table_result = $statement->fetchAll();
//detached CONSTRAINT
foreach ($show_table_result as $show_table_row) {
$preg = 'CONSTRAINT `(.*?)` FOREIGN KEY \(`(.*?)`\) REFERENCES `(.*?)` \(`(.*?)`\)';
preg_match_all('/' . $preg . '/', $show_table_row["Create Table"], $matches, PREG_SET_ORDER);
$createTableWithoutConstraints = preg_replace('/,?\s*' . $preg . ',?/', '', $show_table_row["Create Table"]);
if ($matches) {
$alterTableQuery = "ALTER TABLE `$table` ";
foreach ($matches as $match) {
$constraintName = $match[1];
$columnName = $match[2];
$referencedTable = $match[3];
$referencedColumn = $match[4];
$alterTableQuery .= "ADD CONSTRAINT `$constraintName` FOREIGN KEY (`$columnName`) REFERENCES `$referencedTable` (`$referencedColumn`), ";
}
$alterStatements[] = trim($alterTableQuery, ', ') . ';COMMIT;';
}
$output .= "\n\n" . $createTableWithoutConstraints . ";\n\n";
}
$select_query = "SELECT * FROM " . $table . "";
$statement = $connect->prepare($select_query);
$statement->execute();
$total_row = $statement->rowCount();
if(!$total_row) {
continue;
}
$columns = [];
for ($count = 0; $count < $statement->columnCount(); $count++) {
$column = $statement->getColumnMeta($count);
$columns[] = "`".$column['name'] ."`";
}
$values = [];
$output .= "\nINSERT INTO $table (";
$output .= "" . implode(", ", $columns) . ") VALUES (\n";
for ($count = 0; $count < $total_row; $count++) {
$single_result = $statement->fetch(\PDO::FETCH_ASSOC);
$table_value_array = array_values($single_result);
$rowValues = [];
foreach ($table_value_array as $value) {
if ($value === null) {
$rowValues[] = "NULL";
} elseif (is_numeric($value)) {
$rowValues[] = $value;
} elseif (is_array($value) || is_object($value)) {
$jsonValue = json_encode($value);
$rowValues[] = "'" . addslashes($jsonValue) . "'";
} else {
$rowValues[] = "'" . addslashes($value) . "'";
}
}
$values[] = "(" . implode(", ", $rowValues) . ")";
}
$output .= implode(",\n ", $values) . ");\n";
}
$file_name = 'database_backup_on_' . date('y-m-d') . '.sql';
$file_handle = fopen($file_name, 'w+');
fwrite($file_handle, $output);
//add CONSTRAINT foreign key
foreach ($alterStatements as $alterStatement) {
fwrite($file_handle, $alterStatement . "\n");
}
fclose($file_handle);
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename=' . basename($file_name));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($file_name));
ob_clean();
flush();
readfile($file_name);
unlink($file_name);
I have identified several dangers in the code. Only a portion of the table is created instead of the entire table. There are redundant statements that increase the file size unnecessarily. CONSTRAINT foreign keys are added before the table is created, which leads to errors. Data types are not preserved, resulting in errors with JSON data types. I have addressed these issues and made improvements. Please find the revised version below.
Upvotes: 0
Reputation: 1
public function serverDBBackup()
{
//ENTER THE RELEVANT INFO BELOW
$mysqlHostName = env('DB_HOST');
$mysqlUserName = env('DB_USERNAME');
$mysqlPassword = env('DB_PASSWORD');
$DbName = env('DB_DATABASE');
$tables = [];
$connect = new
\PDO(
"mysql:host=$mysqlHostName;dbname=$DbName;charset=utf8",
"$mysqlUserName", "$mysqlPassword", [
\PDO::MYSQL_ATTR_INIT_COMMAND =>
"SET NAMES 'utf8'",
]
);
$get_all_table_query = "SHOW TABLES";
$statement = $connect->prepare($get_all_table_query);
$statement->execute();
$result = $statement->fetchAll();
$prep = "Tables_in_$DbName";
foreach ($result as $res) {
$tables[] = $res[$prep];
}
$output = '';
$alterStatements = [];
foreach ($tables as $table) {
$show_table_query = "SHOW CREATE TABLE " . $table . "";
$statement = $connect->prepare($show_table_query);
$statement->execute();
$show_table_result = $statement->fetchAll();
//detached CONSTRAINT
foreach ($show_table_result as $show_table_row) {
$preg = 'CONSTRAINT `(.*?)` FOREIGN KEY \(`(.*?)`\) REFERENCES `(.*?)` \
(`(.*?)`\)';
preg_match_all(
'/' . $preg . '/',
$show_table_row["Create Table"],
$matches,
PREG_SET_ORDER
);
$createTableWithoutConstraints = preg_replace(
'/,?\s*' . $preg . ',?/',
'',
$show_table_row["Create Table"]
);
if ($matches) {
$alterTableQuery = "ALTER TABLE `$table` ";
foreach ($matches as $match) {
$constraintName = $match[1];
$columnName = $match[2];
$referencedTable = $match[3];
$referencedColumn = $match[4];
$alterTableQuery .= "ADD CONSTRAINT `$constraintName` FOREIGN KEY
(`$columnName`) REFERENCES `$referencedTable` (`$referencedColumn`), ";
}
$alterStatements[] = trim($alterTableQuery, ', ') . ';COMMIT;';
}
$output .= "\n\n" . $createTableWithoutConstraints . ";\n\n";
}
$select_query = "SELECT * FROM " . $table . "";
$statement = $connect->prepare($select_query);
$statement->execute();
$total_row = $statement->rowCount();
if (!$total_row) {
continue;
}
$columns = [];
for ($count = 0; $count < $statement->columnCount(); $count++) {
$column = $statement->getColumnMeta($count);
$columns[] = "`" . $column['name'] . "`";
}
$values = [];
$output .= "\nINSERT INTO $table (";
$output .= "" . implode(", ", $columns) . ") VALUES \n";
for ($count = 0; $count < $total_row; $count++) {
$single_result = $statement->fetch(\PDO::FETCH_ASSOC);
$table_value_array = array_values($single_result);
$rowValues = [];
foreach ($table_value_array as $value) {
if ($value === null) {
$rowValues[] = "NULL";
} elseif (is_numeric($value)) {
$rowValues[] = $value;
} elseif (is_array($value) || is_object($value)) {
$jsonValue = json_encode($value);
$rowValues[] = "'" . addslashes($jsonValue) . "'";
} else {
$rowValues[] = "'" . addslashes($value) . "'";
}
}
if ($count % 360 == 0 && $count != 0) {
$newline = "";
$newline .= "INSERT INTO $table (";
$newline .= "" . implode(", ", $columns) . ") VALUES ";
$values[] = $newline;
}
if (($count + 1) % 360 == 0 && $count != 0) {
$values[] = "(" . implode(", ", $rowValues) . ");";
} else if ($total_row - 1 == $count) {
$values[] = "(" . implode(", ", $rowValues) . ")";
} else {
$values[] = "(" . implode(", ", $rowValues) . "),";
}
}
$output .= implode("\n ", $values) . ";\n";
}
$file_name = 'database_backup_on_' . date('y-m-d') . '.sql';
$file_handle = fopen($file_name, 'w+');
fwrite($file_handle, $output);
//add CONSTRAINT foreign key
foreach ($alterStatements as $alterStatement) {
fwrite($file_handle, $alterStatement . "\n");
}
fclose($file_handle);
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header(
'Content-Disposition: attachment; filename=' .
basename($file_name)
);
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($file_name));
ob_clean();
flush();
readfile($file_name);
unlink($file_name);
}
Upvotes: 0
Reputation: 404
public function serverDBBackup()
{
try {
$database = config('app.db');
// dd(config('app.db'));
$user = config('app.dbuser');
$pass = config('app.dbpass');
$host = config('app.dbhost');
$dir = 'server_db_backup.sql';
try {
unlink($dir);
} catch (\Throwable $th) {
}
// echo "<h3>Backing up database to `<code>{$dir}</code>`</h3>";
// mysqldump -u [user name] –p [password] [options] [database_name] [tablename] > [dumpfilename.sql]
// --add-drop-database --databases
// mysqldump --user=root --password=bismib_fashion@_mysql --host=localhost --events --routines --triggers elaravel_v2 --result-file=db_backup_new.sql 2>&1
exec("mysqldump --user={$user} --password={$pass} --host={$host} --events --routines --triggers {$database} --result-file={$dir} 2>&1", $output);
$tableViewsCounts = DB::select('SELECT count(TABLE_NAME) AS TOTALNUMBEROFTABLES FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = ?', [$database]);
$tableViewsCounts = $tableViewsCounts[0]->TOTALNUMBEROFTABLES;
$viewsCounts = DB::select('SELECT count(TABLE_NAME) AS TOTALNUMBEROFVIEWS FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE LIKE "VIEW" AND TABLE_SCHEMA = ?', [$database]);
$viewsCounts = $viewsCounts[0]->TOTALNUMBEROFVIEWS;
$tablesCount = $tableViewsCounts-$viewsCounts;
$proceduresCounts = DB::select('SELECT count(TYPE) AS proceduresCounts FROM mysql.proc WHERE TYPE="PROCEDURE" AND db = ?', [$database]);
$proceduresCounts = $proceduresCounts[0]->proceduresCounts;
$functionsCounts = DB::select('SELECT count(TYPE) AS functionsCounts FROM mysql.proc WHERE TYPE="FUNCTION" AND db = ?', [$database]);
$functionsCounts = $functionsCounts[0]->functionsCounts;
$projectURL = url('/');
$deviceIP = \Request::ip();
$init_command = PHP_EOL.'-- '.$database.' Database Backup Generated time = '.YmdTodmYPm(\Carbon\Carbon::now()). PHP_EOL.PHP_EOL.
'-- Project URL = '.$projectURL.PHP_EOL.
'-- Device IP = '.$deviceIP.PHP_EOL.PHP_EOL.
'-- =============Objects Counting Start================= '.PHP_EOL.PHP_EOL.
'-- Total Tables + Views = '.$tableViewsCounts.PHP_EOL.
'-- Total Tables = '.$tablesCount.PHP_EOL.
'-- Total Views = '.$viewsCounts.PHP_EOL.PHP_EOL.
'-- Total Procedures = '.$proceduresCounts.PHP_EOL.
'-- Total Functions = '.$functionsCounts.PHP_EOL.
'-- =============Objects Counting End================= '.PHP_EOL.
PHP_EOL.PHP_EOL.
'SET FOREIGN_KEY_CHECKS=0; '. PHP_EOL.
'SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";'. PHP_EOL.
'START TRANSACTION;'. PHP_EOL.
'SET time_zone = "+06:00";'.PHP_EOL.
'drop database if exists '.$database.';'. PHP_EOL.
'CREATE DATABASE IF NOT EXISTS '.$database.' DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;'. PHP_EOL.
'use '.$database.';'.PHP_EOL;
$data = file_get_contents($dir);
$append_command = PHP_EOL.'SET FOREIGN_KEY_CHECKS=1;'.PHP_EOL.'COMMIT;'.PHP_EOL;
// dd($data);
file_put_contents ( $dir , $init_command.$data.$append_command);
return response()->download($dir);
} catch (\Throwable $th) {
}
}
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=mfw
DB_USERNAME=root
DB_PASSWORD=root
'dbhost' => env('DB_HOST', ''),
// mysql
// mysql
'db' => env('DB_DATABASE', ''),
'dbuser' => env('DB_USERNAME', ''),
'dbpass' => env('DB_PASSWORD', ''),
serverDBBackup()
Upvotes: 0
Reputation: 85
If you wanted to download backup on the fly, use this code after your backup content.
$headers = [
'Content-Disposition' => sprintf('attachment; filename="%s"', 'backup.sql'),
];
return response()->make($output, 200, $headers);
Upvotes: 1
Reputation: 1906
Thanks for @Abdelhakim Ezzahraoui for your solution. i have just change some code. so here you can backup all table. but if you want specific then you set that table name.
function backupDatabase()
{
//ENTER THE RELEVANT INFO BELOW
$mysqlHostName = env('DB_HOST');
$mysqlUserName = env('DB_USERNAME');
$mysqlPassword = env('DB_PASSWORD');
$DbName = env('DB_DATABASE');
$file_name = 'database_backup_on_' . date('y-m-d') . '.sql';
$queryTables = \DB::select(\DB::raw('SHOW TABLES'));
foreach ( $queryTables as $table )
{
foreach ( $table as $tName)
{
$tables[]= $tName ;
}
}
// $tables = array("users","products","categories"); //here your tables...
$connect = new \PDO("mysql:host=$mysqlHostName;dbname=$DbName;charset=utf8", "$mysqlUserName", "$mysqlPassword",array(\PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'utf8'"));
$get_all_table_query = "SHOW TABLES";
$statement = $connect->prepare($get_all_table_query);
$statement->execute();
$result = $statement->fetchAll();
$output = '';
foreach($tables as $table)
{
$show_table_query = "SHOW CREATE TABLE " . $table . "";
$statement = $connect->prepare($show_table_query);
$statement->execute();
$show_table_result = $statement->fetchAll();
foreach($show_table_result as $show_table_row)
{
$output .= "\n\n" . $show_table_row["Create Table"] . ";\n\n";
}
$select_query = "SELECT * FROM " . $table . "";
$statement = $connect->prepare($select_query);
$statement->execute();
$total_row = $statement->rowCount();
for($count=0; $count<$total_row; $count++)
{
$single_result = $statement->fetch(\PDO::FETCH_ASSOC);
$table_column_array = array_keys($single_result);
$table_value_array = array_values($single_result);
$output .= "\nINSERT INTO $table (";
$output .= "" . implode(", ", $table_column_array) . ") VALUES (";
$output .= "'" . implode("','", $table_value_array) . "');\n";
}
}
$file_handle = fopen($file_name, 'w+');
fwrite($file_handle, $output);
fclose($file_handle);
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename=' . basename($file_name));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($file_name));
ob_clean();
flush();
readfile($file_name);
unlink($file_name);
}
Upvotes: 1
Reputation: 202
one of the best solution
fisrt of all install spatie on local server https://spatie.be/docs/laravel-backup/v6/installation-and-setup
now check backup working or not php artisan backup:run
if backup success then u can also take it on cpanel for this go ro app/Console/Kernal.php and register this command
protected function schedule(Schedule $schedule)
{
$schedule->command('backup:run')->everyMinute();
}
now open your cpanel and open cron job and there register this command
/usr/local/bin/php /home/replaceyourdirectoryname/public_html/artisan backup:run > /dev/null 2>&1
now you are successful able to take backup on live server
now for on clcik download
<a href="{{ route('download') }}" class="btn btn-sm btn-primary"><i class="fa fa-download"></i>Download Backup</a>
register route Route::get('/download/','DownloadController@download')->name('download');
and finally controller
<?php
namespace App\Http\Controllers;
use Illuminate\Support\Facades\Artisan;
class DownloadController extends Controller{
public function download(){
Artisan::call('backup:run');
$path = storage_path('app/laravel-backup/*');
$latest_ctime = 0;
$latest_filename = '';
$files = glob($path);
foreach($files as $file)
{
if (is_file($file) && filectime($file) > $latest_ctime)
{
$latest_ctime = filectime($file);
$latest_filename = $file;
}
}
return response()->download($latest_filename);
}
}
Upvotes: 4
Reputation: 177
Route::get('/backupdb', function () {
$DbName = env('DB_DATABASE');
$get_all_table_query = "SHOW TABLES ";
$result = DB::select(DB::raw($get_all_table_query));
$prep = "Tables_in_$DbName";
foreach ($result as $res){
$tables[] = $res->$prep;
}
$connect = DB::connection()->getPdo();
$get_all_table_query = "SHOW TABLES";
$statement = $connect->prepare($get_all_table_query);
$statement->execute();
$result = $statement->fetchAll();
$output = '';
foreach($tables as $table)
{
$show_table_query = "SHOW CREATE TABLE " . $table . "";
$statement = $connect->prepare($show_table_query);
$statement->execute();
$show_table_result = $statement->fetchAll();
foreach($show_table_result as $show_table_row)
{
$output .= "\n\n" . $show_table_row["Create Table"] . ";\n\n";
}
$select_query = "SELECT * FROM " . $table . "";
$statement = $connect->prepare($select_query);
$statement->execute();
$total_row = $statement->rowCount();
for($count=0; $count<$total_row; $count++)
{
$single_result = $statement->fetch(\PDO::FETCH_ASSOC);
$table_column_array = array_keys($single_result);
$table_value_array = array_values($single_result);
$output .= "\nINSERT INTO $table (";
$output .= "" . implode(", ", $table_column_array) . ") VALUES (";
$output .= "'" . implode("','", $table_value_array) . "');\n";
}
}
$file_name = 'database_backup_on_' . date('y-m-d') . '.sql';
$file_handle = fopen($file_name, 'w+');
fwrite($file_handle, $output);
fclose($file_handle);
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename=' . basename($file_name));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($file_name));
ob_clean();
flush();
readfile($file_name);
unlink($file_name);
});
Upvotes: 8
Reputation: 682
I've tweaked @Abdelhakim Ezzahouri's code, to use Laravel's existing connection to DB instead of connecting again, entering credentials, and installing PDO, if it's not installed already.
Route::get('db_dump', function () {
/*
Needed in SQL File:
SET GLOBAL sql_mode = '';
SET SESSION sql_mode = '';
*/
$get_all_table_query = "SHOW TABLES";
$result = DB::select(DB::raw($get_all_table_query));
$tables = [
'admins',
'migrations',
];
$structure = '';
$data = '';
foreach ($tables as $table) {
$show_table_query = "SHOW CREATE TABLE " . $table . "";
$show_table_result = DB::select(DB::raw($show_table_query));
foreach ($show_table_result as $show_table_row) {
$show_table_row = (array)$show_table_row;
$structure .= "\n\n" . $show_table_row["Create Table"] . ";\n\n";
}
$select_query = "SELECT * FROM " . $table;
$records = DB::select(DB::raw($select_query));
foreach ($records as $record) {
$record = (array)$record;
$table_column_array = array_keys($record);
foreach ($table_column_array as $key => $name) {
$table_column_array[$key] = '`' . $table_column_array[$key] . '`';
}
$table_value_array = array_values($record);
$data .= "\nINSERT INTO $table (";
$data .= "" . implode(", ", $table_column_array) . ") VALUES \n";
foreach($table_value_array as $key => $record_column)
$table_value_array[$key] = addslashes($record_column);
$data .= "('" . implode("','", $table_value_array) . "');\n";
}
}
$file_name = __DIR__ . '/../database/database_backup_on_' . date('y_m_d') . '.sql';
$file_handle = fopen($file_name, 'w + ');
$output = $structure . $data;
fwrite($file_handle, $output);
fclose($file_handle);
echo "DB backup ready";
});
Upvotes: 7
Reputation: 481
// Code
public function our_backup_database(){
//ENTER THE RELEVANT INFO BELOW
$mysqlHostName = env('DB_HOST');
$mysqlUserName = env('DB_USERNAME');
$mysqlPassword = env('DB_PASSWORD');
$DbName = env('DB_DATABASE');
$backup_name = "mybackup.sql";
$tables = array("users","messages","posts"); //here your tables...
$connect = new \PDO("mysql:host=$mysqlHostName;dbname=$DbName;charset=utf8", "$mysqlUserName", "$mysqlPassword",array(\PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'utf8'"));
$get_all_table_query = "SHOW TABLES";
$statement = $connect->prepare($get_all_table_query);
$statement->execute();
$result = $statement->fetchAll();
$output = '';
foreach($tables as $table)
{
$show_table_query = "SHOW CREATE TABLE " . $table . "";
$statement = $connect->prepare($show_table_query);
$statement->execute();
$show_table_result = $statement->fetchAll();
foreach($show_table_result as $show_table_row)
{
$output .= "\n\n" . $show_table_row["Create Table"] . ";\n\n";
}
$select_query = "SELECT * FROM " . $table . "";
$statement = $connect->prepare($select_query);
$statement->execute();
$total_row = $statement->rowCount();
for($count=0; $count<$total_row; $count++)
{
$single_result = $statement->fetch(\PDO::FETCH_ASSOC);
$table_column_array = array_keys($single_result);
$table_value_array = array_values($single_result);
$output .= "\nINSERT INTO $table (";
$output .= "" . implode(", ", $table_column_array) . ") VALUES (";
$output .= "'" . implode("','", $table_value_array) . "');\n";
}
}
$file_name = 'database_backup_on_' . date('y-m-d') . '.sql';
$file_handle = fopen($file_name, 'w+');
fwrite($file_handle, $output);
fclose($file_handle);
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename=' . basename($file_name));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($file_name));
ob_clean();
flush();
readfile($file_name);
unlink($file_name);
}
// routing
Route::get('/our_backup_database', 'YourControllerController@our_backup_database')->name('our_backup_database');
//View
<form action="{{ route('our_backup_database') }}" method="get">
<button style="submit" class="btn btn-primary"> download</button>
</form>
Upvotes: 11