INTO OUTFILE / mysql转储的替代方案

时间:2011-12-02 11:07:18

标签: php mysql

好的,所以我的网站主机不允许使用INTO OUTFILE / mysql转储,我需要开发一个备份脚本。

我将如何在PHP中执行此操作。感谢

1 个答案:

答案 0 :(得分:0)

那里有一些漂亮而且简单的备份脚本;来自PHPMyAdmin的那个可能是非常好的,因为经过充分测试,问题是从整个包中提取它以便能够自动调用它。

对于完全相同的任务,我开发了自己的小脚本,它迭代数据库中的所有表,并将内容发送到一个bzip压缩的sql文件中(这意味着如果需要备份,可以轻松地再次导入它)。 / p>

因为它非常简单,所以这个脚本当然也有其局限性,如下面的评论所指出的:它只备份表格内容。甚至表结构都没有被保留,这里的假设是表结构很少变化,并且如果需要也可以很容易地重建。但是,如果您的软件经常自动更改架构,或者它使用函数或视图,您可能需要寻找更高级的脚本!

到目前为止,对于“免责声明”,我们在这里使用简单的脚本:

<?php
$db_host = "localhost";
$db_name = $_GET["db"];
$db_user = $_GET["user"];
$db_pass = $_GET["pass"];
$do_truncate = $_GET["truncate"];

function datadump ($table, $do_truncate)
{
    $result .= "-- -------- TABLE '$table' ----------\n";
    $query = mysql_query("SELECT * FROM ".$table);
    $numrow = mysql_num_rows($query);
    $numfields = mysql_num_fields($query);
    if ($numrow > 0)
    {
        if (strcmp($do_truncate, "yes") == 0)
        {
            $result .= "TRUNCATE TABLE ".$table.";\n";
        }
        $result .= "INSERT INTO `".$table."` (";
        $i = 0;
        for($k=0; $k<$numfields; $k++ )
        {
            $result .= "`".mysql_field_name($query, $k)."`";
            if ($k < ($numfields-1))
            {
                $result .= ", ";
            }
        }
        $result .= ") VALUES ";
        while ($row = mysql_fetch_row($query))
        {
            $result .= " (";
            for($j=0; $j<$numfields; $j++)
            {
                if (mysql_field_type($query, $j) == "string" ||
                    mysql_field_type($query, $j) == "timestamp" ||
                    mysql_field_type($query, $j) == "time" ||
                    mysql_field_type($query, $j) == "datetime" ||
                    mysql_field_type($query, $j) == "blob")
                {
                    $row[$j] = addslashes($row[$j]);
                    $row[$j] = ereg_replace("\n","\\n",$row[$j]);
                    $row[$j] = ereg_replace("\r","",$row[$j]);
                    $result .= "'$row[$j]'";
                }
                else if (is_null($row[$j]))
                {
                    $result .= "NULL";
                else
                {
                    $result .= $row[$j];
                }
                if ( $j<($numfields-1))
                {
                    $result .= ", ";
                }
            }
            $result .= ")";
            $i++;
            if ($i < $numrow)
            {
                $result .= ",";
            }
            else
            {
                $result .= ";";
            }
            $result .= "\n";
        }
    }
    else
    {
        $result .= "-- table is empty";
    }
    return $result . "\n\n";
}


mysql_connect($db_host,$db_user,$db_pass);
@mysql_select_db($db_name) or die("Unable to select database.");
$tableQ = mysql_list_tables ($db_name);
$i = 0;
$content  =  "-- --------------------------------\n";
$content .=  "-- DATABASE DUMP\n";
$content .=  "-- DATE: ".date("d-M-Y")."\n";
$content .=  "-- DB NAME: ".$db_name."\n";
$content .=  "-- TRUNCATE: ".((strcmp($do_truncate, "yes") == 0)? "YES" : "NO")."\n";
$content .=  "-- ---------------------------------\n\n";
while ($i < mysql_num_rows ($tableQ))
{
    $tb_names[$i] = mysql_tablename ($tableQ, $i);
    $content .= datadump($tb_names[$i], $do_truncate);
    $i++;
}
$file_name = "MySQL_Database_Backup.sql.bz2";
Header("Content-type: application/octet-stream");
Header("Content-Disposition: attachment; filename=$file_name");
echo(bzcompress(utf8_encode($content)));
exit;
?>

我想它仍然需要一些改进(例如安全性),但它很好地达到了目的。要使用它,请将其上传到您的网站空间,假设为'backup-db.php'(最好在某些隐藏文件夹中),并像这样调用它

http://yoursite/backup-db.php?host=yourdbhost&name=<yourdbname>&user=<dbuser>&pass=<dbpass>&truncate=<whethertoaddtruncatestatementforeachtable>

您当然首先必须调整括号中的值&lt;&gt;。随意使用和改编它;如果你做任何改进,我会很高兴听到它!