如何在 laravel 中备份/导出连接的数据库 database.sql 文件?
Posted
技术标签:
【中文标题】如何在 laravel 中备份/导出连接的数据库 database.sql 文件?【英文标题】:How to backup/export the connected Database database.sql file in laravel? 【发布时间】:2020-02-01 01:26:13 【问题描述】:我已查看此问题的所有可用主题,但没有得到任何准确的答案... 有人有明确的想法将当前数据库备份到 .sql 文件中并下载吗?
【问题讨论】:
使用您的数据库编辑器(mysqlWorkBench、phpMyAdmin 等)并进行导出。 转到 phpMyAdmin,单击导出,然后转到。您将在.sql
文件中获取您的数据库。
如果您有兴趣,还有一个很棒的package by spatie。可以很容易地自动化和转储文件夹。
数据库将从数据库管理面板中导出,例如从phpmyadmin
选择数据库然后导出数据库,您将获得所需的格式选择选项,然后导出。
【参考方案1】:
// 代码
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);
// 路由
Route::get('/our_backup_database', 'YourControllerController@our_backup_database')->name('our_backup_database');
//查看
<form action=" route('our_backup_database') " method="get">
<button style="submit" class="btn btn-primary"> download</button>
</form>
【讨论】:
感谢您的好主意,我已经修改了您上面的代码以使用 Laravel 现有的数据库连接,如果未安装,则无需重新输入凭据或使用 PDO 扩展(在我的情况下它不是t) 先生,这可以正常离线工作。但在网上它不起作用【参考方案2】:我已经调整了@Abdelhakim Ezzahouri 的代码,使用 Laravel 与 DB 的现有连接,而不是再次连接、输入凭据和安装 PDO(如果尚未安装)。
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";
);
【讨论】:
添加wordwrap()
以像这样包装数据:$data .= "('" . wordwrap(implode("','", $table_value_array),400,"\n",TRUE) . "');\n";
。如果数据过长超过了一行的限制,当您尝试将其导入数据库时,它将被截断并导致错误【参考方案3】:
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);
);
【讨论】:
请修正代码格式并解释为什么您的答案与上述其他人不同且更好,并且投票率更高 我喜欢这个答案的地方在于它实际上导出了所有表,而不仅仅是@Amins 答案中的两个常量表。【参考方案4】:最佳解决方案之一
首先在本地服务器上安装 spatie https://spatie.be/docs/laravel-backup/v6/installation-and-setup
现在检查备份是否工作php artisan backup:run
如果备份成功,那么你也可以在 cpanel 上为这个 go ro app/Console/Kernal.php 注册这个命令
protected function schedule(Schedule $schedule)
$schedule->command('backup:run')->everyMinute();
现在打开您的 cpanel 并打开 cron 作业并在那里注册此命令
/usr/local/bin/php /home/replaceyourdirectoryname/public_html/artisan backup:run > /dev/null 2>&1
现在您可以成功地在实时服务器上进行备份
现在可以在 clcik 上下载
<a href=" route('download') " class="btn btn-sm btn-primary"><i class="fa fa-download"></i>Download Backup</a>
注册路由Route::get('/download/','DownloadController@download')->name('download');
最后是控制器
<?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);
【讨论】:
【参考方案5】:感谢@Abdelhakim Ezzahraoui 提供的解决方案。我刚刚更改了一些代码。所以在这里你可以备份所有表。但是如果你想要具体的,那么你可以设置那个表名。
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);
【讨论】:
【参考方案6】:如果您想即时下载备份,请在备份内容后使用此代码。
$headers = [
'Content-Disposition' => sprintf('attachment; filename="%s"', 'backup.sql'),
];
return response()->make($output, 200, $headers);
【讨论】:
以上是关于如何在 laravel 中备份/导出连接的数据库 database.sql 文件?的主要内容,如果未能解决你的问题,请参考以下文章