所以我使用以下代码备份我的数据库:
$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的输出中,它将用一行中的两个单引号'
替换单个''
。
真的有区别吗?请查看我逃避非数字字段的方式,并告诉我是否有更好的方法。
答案 0 :(得分:2)
连续''
中两个单引号的方法是更标准的SQL,因此它更具可移植性。
即使MySQL支持名为NO_BACKSLASH_ESCAPES
的{{3}},如果您尝试将备份导入启用了该模式的服务器,也会使反斜杠处理的字符串无效。
但我必须添加注释,以明确表示备份数据库的方法充满了其他问题。
您不处理NULL:
if (!is_numeric($value))
这不处理需要分隔的列名,因为它们可能与SQL保留字冲突:
$output .= "INSERT INTO `$table` (" .implode(', ', $columns). ") VALUES";
如果您的任何标签页中有数百万行,尝试以单个字符串中的一系列INSERT语句的形式存储该表的整个内容将超过PHP的最大内存限制:
$output .= "\n(" .implode(', ', $row). "),";
您只显示部分脚本,但它也可能无法正确处理二进制字符串,字符集,触发器,存储例程,视图,表格选项等。
你真的在重新发明轮子。
我已经看到过去的问题,人们会尝试做你正在做的事情,但很难做到正确:
使用PHP中的Why is my database backup script not working in php?拨打shell_exec()或mysqldump可以更好地利用您的时间。