PHP数据库转储脚本 - 有什么问题吗?

时间:2010-06-23 13:24:17

标签: php mysql backup database-backups

我找到了一个PHP函数来转储其他人编写的mySQL数据库,然后将其清理并稍微格式化。我想知道我是否可以批评它。我已经运行它,在Wordpress博客上测试它并且数据库完全恢复,但是想要了解代码。

具体来说,我正在寻找反馈:

  • 任何可能破坏数据的内容 - 未正确转义等
  • 违反任何最佳做法/原则
  • 安全问题
  • 您可能会将其他任何问题视为问题

注意:我 NOT 希望使用mysqldump,我想从代码中完全生成这个sql备份。我也意识到文件名可以随机生成,但SQL文件也会上传到dropbox,我想以相同的名称对它进行版本化。

谢谢!

代码:

  // Variables
  $dbHost = 'DBHOST';
  $dbUser = 'DBUSER';
  $dbPassword = 'DBPASSWORD';
  $dbName = 'DBNAME';
  $tables = '*';
  $fileName = 'mydatabase.sql';


  // Logic
    $link = @mysql_connect($dbHost, $dbUser, $dbPassword);
    $db = @mysql_select_db($dbName, $link);

if(!$link || !$db)
 die("Database Error");

//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);


// Loop through tables    
foreach($tables as $table) {

    $result = mysql_query('SELECT * FROM '. $table);
    $num_fields = mysql_num_fields($result);
    $return.= 'DROP TABLE IF EXISTS ' . $table . ';';
  $createTable = mysql_fetch_row(mysql_query('SHOW CREATE TABLE ' . $table));
    $return .= "\n\n" . $createTable[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 the file
$handle = fopen($fileName, 'w+');
fwrite($handle, $return);
fclose($handle);

6 个答案:

答案 0 :(得分:4)

该脚本存在严重的交易问题。除了最琐碎的数据库之外,它不会起作用。

  • 不支持NULL。
  • 不考虑字符集。
  • 表名称未分隔。
  • 仅支持表 - 不支持视图,存储过程,触发器,函数等。
  • addslashes() is not character-set safe
  • mysql_query()从表中预取所有行,因此如果查询包含数百万行的表,则会超出PHP内存限制。请改用mysql_unbuffered_query()。第二个想法,我看到你收集$ return中的所有输出,所以这没有实际意义。
  • 使用@运算符抑制错误是不好的做法。检查错误并通过信息性消息正常失败。

您不使用mysqldump的要求是荒谬的。

为什么要为自己重新制造轮子做出这么多工作,但仍然如此错误?只需通过shellexec()运行mysqldump。


另见:

答案 1 :(得分:2)

尝试mysql命令或mysqldump命令

答案 2 :(得分:1)

字符集?也许SET NAMES utf8可能是一个很好的补充。

此外,如果数据库包含视图会发生什么?

答案 3 :(得分:1)

这不会转储存储过程,函数,视图,触发器等。

编辑:您也可以通过这种方式转储程序等。只需使用ie SHOW PROCEDURE STATUS; 获取程序列表,然后为每个程序获取SHOW CREATE PROCEDURE。功能,视图,触发器也是如此......

不要忘记SHOW CREATE DATABASE;

答案 4 :(得分:1)

如果这是一个非常庞大的数据库需要转储,请确保您的服务器(以及每个脚本的php max执行内存)有足够的内存来保留内存中的整个$ return,否则最好先刷新文件一次一段时间,或每一行。

答案 5 :(得分:0)

创建备份数据库:

<system.web>
    <trust level="Full" />
</system.web>