所以这对我来说是新的。当David Walsh使用这个MySQL数据库PHP脚本时,我在运行它时得到一个空的SQL文件。
<?php
backup_tables('localhost','username','password','blog');
/* backup the db OR just a table */
function backup_tables($host,$user,$pass,$name,$tables = '*')
{
$return = '';
$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] = 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);
mysql_close($link);
}
?>
当我理解代码时,我输入了数据库名称,其中博客位于顶部的函数backup_tables()
中。
为什么脚本会创建一个空的SQL文件?
答案 0 :(得分:4)
我尝试过这个脚本,它对我有用,虽然有一些错误和一些折旧警告。
要保存文件,请确保脚本所在的目录具有写入权限。
chmod 0777 /home/site/dir
要阻止Undefined variable: return
通知,请添加以下代码
$return = '';
就在这一行之前
$link = mysql_connect($host,$user,$pass);
并且 - 我知道这似乎很明显 - 但请确保您连接到正确的数据库,或者您没有数据库名称的拼写错误。
backup_tables('localhost','myUsername','myPassword','myDatabase');
最后:确保数据库有表。我在数据库中没有表运行它来查看发生了什么 - 它吐了一个空白文档。就像你描述的那样。 :)
答案 1 :(得分:4)
有一种更好的方法可以做到这一点,即mysqldump
。它是为了创建表的备份而构建的,它比php快得多。您只需在终端中运行以下命令:
mysqldump -h localhost -u root -p --result-file ~/backup.sql my_database
如果您只想备份几张桌子,可以这样做:
mysqldump -h localhost -u root -p --result-file ~/backup.sql my_database table_a table_b
您可以使用更多选项,因此我不会列出它们,但您可以在此处阅读它们:
https://dev.mysql.com/doc/refman/5.1/en/mysqldump.html
如果您需要php来执行此操作,您可以通过exec()
或其他类似方法执行此操作:
exec("mysqldump -h $host -u $user -p$pass --result-file ~/$file $database $tables");
答案 2 :(得分:2)
我没有在。='DROP行之前的任何地方看到$ return。我有涉及未定义变量的错误。在foreach()之上添加$ return ='';
答案 3 :(得分:2)
要添加到timgavin的答案,您还可以为此脚本添加压缩,只需添加
即可$compression = true;
到顶部
并改变底部 从
$handle = fopen('db-backup-'.time().'-'.(md5(implode(',',$tables))).'.sql','w+');
fwrite($handle,$return);
fclose($handle);
mysql_close($link);
到
if ($compression) {
$zp = gzopen($BACKUP_PATH . 'db-backup-'.time().'-'.(md5(implode(',',$tables))).'.sql.gz', "w9");
gzwrite($zp, $return);
gzclose($zp);
} else {
$handle = fopen($BACKUP_PATH . 'db-backup-'.time().'-'.(md5(implode(',',$tables))).'.sql','w+');
fwrite($handle,$return);
fclose($handle);
}
解释
答案 4 :(得分:1)
如果您使用表名运行脚本,它可以正常工作。你应该添加$ return ='';到第26行。
backup_tables('localhost','root','arcd','unilicadb', 'fa_university');
如果您使用通配符运行backup_tables('localhost','root','arcd','unilicadb', '*');
,则可能会遇到内存错误,以防您拥有较大的数据库。
“致命错误:允许的内存大小为134217728字节耗尽(试图分配34399640字节)”
尝试添加error_reporting(E_ALL);
答案 5 :(得分:1)
backup_tables('localhost','root','','dbname');
/* backup the db OR just a table */
function backup_tables($host,$user,$pass,$name,$tables = '*')
{
$return = '';
$link = mysqli_connect($host,$user,$pass, $name);
//get all of the tables
if($tables == '*')
{
$tables = array();
$result = mysqli_query($link, 'SHOW TABLES');
while($row = mysqli_fetch_row($result))
{
$tables[] = $row[0];
}
}
else
{
$tables = is_array($tables) ? $tables : explode(',',$tables);
}
//cycle through
foreach($tables as $table)
{
$result = mysqli_query($link, 'SELECT * FROM '.$table);
$num_fields = mysqli_num_fields($result);
$return.= 'DROP TABLE '.$table.';';
$tableResult = mysqli_query($link, 'SHOW CREATE TABLE '.$table);
$row2 = mysqli_fetch_row($tableResult);
$return.= "\n\n".$row2[1].";\n\n";
for ($i = 0; $i < $num_fields; $i++)
{
while($row = mysqli_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
$handle = fopen('db-backup-'.time().'-'.(md5(implode(',',$tables))).'.sql','w+');
fwrite($handle,$return);
fclose($handle);
mysqli_close($link);
}
答案 6 :(得分:1)
我从一开始就一直关注你的问题,我做了我的研究,发现你的问题很有意思。
通过php代码备份mysql的大多数解决方案都已过时,并且在当今的环境中存在问题。因此,我很想知道是否有任何更新和有用的一次。我的计划是,如果我找不到一个,那么我想开发一个。
但我找到了一个解决方案并且有效。我通过导出和重新导入表来测试它。我想你会喜欢它。
在转到代码之前,我有以下注释:
注意:代码在代码所有者的page上找到,我添加了额外的代码行,以使其适用于OP。
非常重要的说明: 取决于您的服务器资源和容量和数据库大小,执行此类代码可能需要一些时间,特别是如果您有共享主机,则需要将执行时间延长至300秒(5分钟),并且应在低负载时间内执行备份。 最糟糕的情况是,如果代码阻止了该部分,您可能需要请求主机提供商延长执行时间。
工作代码
<?php
define("MAX_EXECUTION_TIME", 100); // seconds
$timeline = time() + MAX_EXECUTION_TIME;
EXPORT_TABLES('localhost', 'root', '', 'blog');
function EXPORT_TABLES($host, $user, $pass, $name, $tables = false, $backup_name = false)
{
$mysqli = new mysqli($host, $user, $pass, $name);
$mysqli->select_db($name);
$mysqli->query("SET NAMES 'utf8'");
$queryTables = $mysqli->query('SHOW TABLES');
while ($row = $queryTables->fetch_row())
{
$target_tables[] = $row[0];
}
if ($tables !== false)
{
$target_tables = array_intersect($target_tables, $tables);
}
try
{
foreach ($target_tables as $table)
{
$result = $mysqli->query('SELECT * FROM ' . $table);
$fields_amount = $result->field_count;
$rows_num = $mysqli->affected_rows;
$res = $mysqli->query('SHOW CREATE TABLE ' . $table);
$TableMLine = $res->fetch_row();
$content = (!isset($content) ? '' : $content) . "\n\n" . $TableMLine[1] . ";\n\n";
for ($i = 0, $st_counter = 0; $i < $fields_amount; $i ++, $st_counter = 0)
{
while ($row = $result->fetch_row())
{ //when started (and every after 100 command cycle):
if ($st_counter % 100 == 0 || $st_counter == 0)
{
$content .= "\nINSERT INTO " . $table . " VALUES";
}
$content .= "\n(";
for ($j = 0; $j < $fields_amount; $j ++)
{
$row[$j] = str_replace("\n", "\\n", addslashes($row[$j]));
if (isset($row[$j]))
{
$content .= '"' . $row[$j] . '"';
} else
{
$content .= '""';
}
if ($j < ($fields_amount - 1))
{
$content .= ',';
}
}
$content .= ")";
//every after 100 command cycle [or at last line] ....p.s. but should be inserted 1 cycle eariler
if ((($st_counter + 1) % 100 == 0 && $st_counter != 0) || $st_counter + 1 == $rows_num)
{
$content .= ";";
} else
{
$content .= ",";
}
$st_counter = $st_counter + 1;
}
}
$content .= "\n\n\n";
}
} catch (Exception $e)
{
echo 'Caught exception: ', $e->getMessage(), "\n";
}
$backup_name = $backup_name ? $backup_name : $name . "___(" . date('H-i-s') . "_" . date('d-m-Y') . ")__rand" . rand(1, 11111111) . ".sql";
header('Content-Type: application/octet-stream');
header("Content-Transfer-Encoding: Binary");
header("Content-disposition: attachment; filename=\"" . $backup_name . "\"");
echo $content;
exit;
}
?>