因此,我使用以下代码备份数据库:
$rows = $this->_getDb()->fetchAll("SELECT * FROM $table");
foreach ($rows AS $row)
{
foreach ($row AS &$value)
{
if (!is_numeric($value))
{
$value = "'".addcslashes($value, "'\\")."'";
$value = str_replace("\n", '\n', $value);
}
}
if (!$count)
{
$output .= "INSERT INTO `$table` (" .implode(', ', $columns). ") VALUES";
}
$count++;
$output .= "\n(" .implode(', ', $row). "),";
if ($count >= $limit)
{
$count = 0;
$output = preg_replace('#,$#', ";\n\n", $output);
}
}
$output = preg_replace('#,$#', ";\n\n", $output);
这似乎工作得很好...但是我正在将输出与从PHPMyAdmin获得的输出进行比较,并且注意到一些细微的差异。对于我的代码,由于我使用
addcslashes
的方式,如果字符串包含'
,它将使用\'
对其进行转义。但是,在PHPMyAdmin的输出中,它将改为用两个单引号'
连续替换一个''
。真的有区别吗?请查看我转义非数字字段的方式,并告诉我是否有更好的方法。
最佳答案
连续两个单引号''
的方法是更标准的SQL,因此更可移植。
甚至MySQL也支持称为NO_BACKSLASH_ESCAPES
的SQL_MODE,如果您尝试将备份导入启用了该模式的服务器,则会使反斜杠处理的字符串无效。
但是我必须添加注释,以使您的数据库备份方法充满其他问题。
您不处理NULL:
if (!is_numeric($value))
这不会处理需要定界的列名,因为它们可能与SQL保留字冲突:
$output .= "INSERT INTO `$table` (" .implode(', ', $columns). ") VALUES";
如果您的任何表中都有数百万行,那么尝试以一系列INSERT语句的形式在单个字符串中存储该表的全部内容,将超出PHP的最大内存限制:
$output .= "\n(" .implode(', ', $row). "),";
您仅显示脚本的一部分,但也可能无法正确处理二进制字符串,字符集,触发器,存储的例程,视图,表选项等。
您真的在重新发明轮子。
我看过过去的问题,人们尝试做您正在做的事情,但是很难做到正确:
PHP Database Dump Script - are there any issues?
Why is my database backup script not working in php?
仅使用PHP中的shell_exec()来调用mysqldump或mydumper会更好地利用您的时间。