簡體   English   中英

備份MySQL DB ...正確的方法來逃避字符串?

[英]Backing up MySQL DB… Proper way to escape strings?

所以我使用以下代碼備份我的數據庫:

$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的支持SQL_MODE稱為NO_BACKSLASH_ESCAPES這將使您的反斜杠處理字符串無效的,如果你嘗試將備份導入到啟用了該模式的服務器。

但我必須添加注釋,以明確表示備份數據庫的方法充滿了其他問題。

  • 你不處理NULL:

     if (!is_numeric($value)) 
  • 這不處理需要分隔的列名,因為它們可能與SQL保留字沖突:

     $output .= "INSERT INTO `$table` (" .implode(', ', $columns). ") VALUES"; 
  • 如果您的任何tabes中有數百萬行,那么嘗試以單個字符串中的一系列INSERT語句的形式存儲該表的整個內容將超過PHP的最大內存限制:

     $output .= "\\n(" .implode(', ', $row). "),"; 
  • 您只顯示腳本的一部分,但它也可能無法正確處理二進制字符串,字符集,觸發器,存儲例程,視圖,表選項等。

你真的在重新發明輪子。

我已經看到過去的問題,人們試圖做你正在做的事情,但很難做到正確:

使用PHP中的shell_exec()來調用mysqldumpmydumper會更好地利用你的時間。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM