2014-10-30 63 views
0

我需要一個可以下載和上傳一個數據庫文件的php代碼。如何使用php下載和上傳SQL數據庫爲.sql文件?

即我有這些數據庫accounts,informationdata

備份:

我需要幫助下載數據庫data.sql文件。而對於您的額外信息,該數據庫包含5個表格。我想將所有文件下載到一個文件中。

還原:

我也應該能夠上傳同一文件.sql恢復的目的。它應該替換可用的data數據庫。

編輯

我知道通過phpMyAdmin的其可能和我打算讓我的客戶端下載SQL文件不能使用它。我不能給他們我的phpmyadmin密碼。

更重要的是,我不需要通過.sql文件來做到這一點,它可以是任何格式,很容易備份和恢復數據庫。

謝謝。

+3

你可以只安裝'phpMyAdmin'並使用它? – 2014-10-30 16:45:50

+0

首先,你想從你的數據庫下載一個SQL文件?作爲一個SQL轉儲?其次,如果你已經做到了......爲什麼你需要這樣做?我不明白 – 2014-10-30 16:46:17

+2

只需使用mysqldump,你寫了一行,bam,done。爲什麼使用php複雜化自己? – Mihai 2014-10-30 16:46:46

回答

1

我嘗試了所有的答案。但是,下面的代碼幫助了我。

後備

我粘貼下面的代碼在db_export.php

##################### 
// CONFIGURATIONS // 
##################### 
// Define the name of the backup directory 
define('BACKUP_DIR', './myBackups') ; 
// Define Database Credentials 
define('HOST', 'localhost') ; 
define('USER', 'root') ; 
define('PASSWORD', 'password') ; 
define('DB_NAME', 'database_name') ; 
$files = scandir(BACKUP_DIR); 
if(count($files) > 2) { 
    for ($i=2; $i < count($files); $i++) { 
    unlink(BACKUP_DIR."/".$files[$i]); 
    } 
} 
/* 
Define the filename for the sql file 
If you plan to upload the file to Amazon's S3 service , use only lower-case letters 
*/ 
$fileName = 'mysqlbackup--' . date('d-m-Y') . '@'.date('h.i.s').'.sql' ; 
// Set execution time limit 
if(function_exists('max_execution_time')) { 
if(ini_get('max_execution_time') > 0)  set_time_limit(0) ; 
} 
########################### 
//END OF CONFIGURATIONS// 
########################### 

// Check if directory is already created and has the proper permissions 
if (!file_exists(BACKUP_DIR)) mkdir(BACKUP_DIR , 0700) ; 
if (!is_writable(BACKUP_DIR)) chmod(BACKUP_DIR , 0700) ; 

// Create an ".htaccess" file , it will restrict direct accss to the backup-directory . 
//$content = 'deny from all' ; 
//$file = new SplFileObject(BACKUP_DIR . '/.htaccess', "w") ; 
//$file->fwrite($content) ; 

$mysqli = new mysqli(HOST , USER , PASSWORD , DB_NAME) ; 
if (mysqli_connect_errno()) 
{ 
    printf("Connect failed: %s", mysqli_connect_error()); 
    exit(); 
} 
// Introduction information // 
$return = ""; 
$return .= "--\n"; 
$return .= "-- A Mysql Backup System \n"; 
$return .= "--\n"; 
$return .= '-- Export created: ' . date("Y/m/d") . ' on ' . date("h:i") . "\n\n\n"; 
$return = "--\n"; 
$return .= "-- Database : " . DB_NAME . "\n"; 
$return .= "--\n"; 
$return .= "-- --------------------------------------------------\n"; 
$return .= "-- ---------------------------------------------------\n"; 
$return .= 'SET AUTOCOMMIT = 0 ;' ."\n" ; 
$return .= 'SET FOREIGN_KEY_CHECKS=0 ;' ."\n" ; 
$tables = array() ; 
// Exploring what tables this database has 
$result = $mysqli->query('SHOW TABLES') ; 
// Cycle through "$result" and put content into an array 
while ($row = $result->fetch_row()) 
    $tables[] = $row[0] ; 
// Cycle through each table 
foreach($tables as $table) 
{ 
    // Get content of each table 
    $result = $mysqli->query('SELECT * FROM '. $table) ; 
    // Get number of fields (columns) of each table 
    $num_fields = $mysqli->field_count ; 
    // Add table information 
    $return .= "--\n" ; 
    $return .= '-- Tabel structure for table `' . $table . '`' . "\n" ; 
    $return .= "--\n" ; 
    $return.= 'DROP TABLE IF EXISTS `'.$table.'`;' . "\n" ; 
    // Get the table-shema 
    $shema = $mysqli->query('SHOW CREATE TABLE '.$table) ; 
    // Extract table shema 
    $tableshema = $shema->fetch_row() ; 
    // Append table-shema into code 
    $return.= $tableshema[1].";" . "\n\n" ; 
    // Cycle through each table-row 
    while($rowdata = $result->fetch_row()) 
    { 
    // Prepare code that will insert data into table 
    $return .= 'INSERT INTO `'.$table .'` VALUES (' ; 
    // Extract data of each row 
    for($i=0; $i<$num_fields; $i++) 
     $return .= '"'.$rowdata[$i] . "\"," ; 
    // Let's remove the last comma 
    $return = substr("$return", 0, -1) ; 
    $return .= ");" ."\n" ; 
    } 
    $return .= "\n\n" ; 
} 
// Close the connection 
$mysqli->close() ; 
$return .= 'SET FOREIGN_KEY_CHECKS = 1 ; ' . "\n" ; 
$return .= 'COMMIT ; ' . "\n" ; 
$return .= 'SET AUTOCOMMIT = 1 ; ' . "\n" ; 
//$file = file_put_contents($fileName , $return) ; 
$zip = new ZipArchive() ; 
$resOpen = $zip->open(BACKUP_DIR . '/' .$fileName.".zip" , ZIPARCHIVE::CREATE) ; 
if($resOpen) 
    $zip->addFromString($fileName , "$return") ; 
$zip->close() ; 
$fileSize = get_file_size_unit(filesize(BACKUP_DIR . "/". $fileName . '.zip')) ; 
$message = <<<msg 
    <h2>BACKUP ready,</h2> 
    the archive has the name of : <b> $fileName </b> and it's file-size is : $fileSize . 
    <br /><a href=\"myBackups/{$fileName}.zip\"><b>Click here to Download</b></a> 
msg; 
echo $message ; 
// Function to append proper Unit after file-size . 
function get_file_size_unit($file_size){ 
    switch (true) { 
     case ($file_size/1024 < 1) : 
      return intval($file_size) ." Bytes" ; 
      break; 
     case ($file_size/1024 >= 1 && $file_size/(1024*1024) < 1) : 
      return intval($file_size/1024) ." KB" ; 
      break; 
     default: 
     return intval($file_size/(1024*1024)) ." MB" ; 
    } 
} 

RESTORING

我想這是容易移交數據庫上傳給客戶。我從this comment瞭解到。謝謝,Henrik


其他答案和評論:

順便說一句,感謝所有的意見從,

Rocket HazmatAres DragunaMihaibearbrandelizerMike Brantlolka_bolka(哈哈哈不錯!),Bill Karwin(同樣不錯),尤其是Henrik

而且,謝謝大家的回答通過

LuzanSerpesHenrikBill KarwinAdam FischercarysunHerman Nz

所有的評論和答案在一個或其他情況下是有用和有價值的。

謝謝


1

如果您不使用php,這會更容易。我不喜歡用命令的exec,但...

exec("mysqldump -u USER -p PASSWORD --databases accounts information data > /YOURHOME/dumpfile.sql"); 

我會壓縮該文件:

exec("tar czvf /YOURHOME/dumpfile.sql.tar.gz /YOURHOME/dumpfile.sql"); 

而旁邊呼應的文件或做你想要什麼。

我建議你寫一個bash腳本來完成我以前寫的東西。它可以將轉儲發送到另一臺服務器或任何你想要的。使用PHP這有點奇怪。

+2

+1但爲什麼要使用一個文件的tar?只需使用gzip壓縮成.sql.gz。 – 2014-10-30 17:13:23

+0

你說得對。我習慣使用tar來處理這類東西。有時它是一個文件,有時它不止一個。但是,是的,gzip會是一個更好的解決方案 – Serpes 2014-10-31 07:52:42

0

我會建議使用dibi數據庫層。您可以在這裏下載:https://github.com/dg/dibi

不僅僅是爲使用:

dibi::connect(); dibi::loadFile('dump.sql'); 

//Can be read as a compressed file: 

dibi::loadFile('compress.zlib://dump.sql.gz'); 
0

備份

可以生成與shell命令mysqldump一個SQL轉儲文件。

mysqldump -u USER -p PASSWORD DATABASE > dump.sql 

如果使用該示例,則需要用大寫字母替換單詞。

恢復

從SQL文件的恢復可以通過使用mysql shell命令來完成。在PHP

mysql -u USER -p PASSWORD < dump.sql 

呼叫shell命令

PHP中的shell命令可以用函數exec()被稱爲:

exec("mysqldump -u USER -p PASSWORD DATABASE > dump.sql"); // backup 
exec("mysql -u USER -p PASSWORD < dump.sql");    // restore 

安全方面

您應該只允許信任的用戶從SQL文件恢復。如果你只有一個mysql用戶訪問所有的數據庫,那麼直接從sql文件恢復的安全性比使用phpmyadmin的安全性要好得多。使用具有管理mysql用戶能力的託管軟件包是一個很好的解決方案。否則,你必須在從這個文件恢復之前驗證上傳的sql文件。

在下面,你會發現三條關於如何驗證上傳文件的建議。所有的建議建立在假定您使用已在服務器上生成的sql文件的基礎上。

  1. 在下載時創建數字簽名並在上傳時驗證簽名。當然,你必須將數字簽名和sql一起上傳。

  2. 將下載的sql的哈希值存儲在服務器上,並在上傳時檢查該哈希值的存在性。使用一個ID爲SQL文件可能會有所幫助。

  3. 將整個sql文件保存在服務器上,只允許從這些文件中恢復。上傳不再需要了。

0

試試這個下載:

<form method="POST" action=""> 
    <b>Path to export </b> 
    <br /> 
    <input name="txtpath" id="txtpath" type="text" size="71"> 
    <br /> 
    <span class="buram">ex: public_html/dbbackup/</span>database.sql 
    <br /> 
    <br /> 
    <input type="submit" name="cmddownld" id="cmddownld" value="Backup"> 
    </form> 
    <br /> 
    <br /> 
<?php 
    $mysqldbname ="database"; 
    $usrname ="username"; 
    $mypassz ="password"; 
    $remhost ="localhost"; 
    $exportpath = strip_tags($_POST["txtpath"]); 
    //ex: $exportpath ="public_html/dbbackup/dbsample.sql"; 
    if (isset($_POST["cmddownld"])){ 
     if (empty($_POST["txtpath"])){ 
      echo "Unclear path!"; 
      } 
     else{ 
      $cmdrun="mysqldump --opt -h" .$remhost ." -u" .$usrname ." -p" .$mypassz ." " .$mysqldbname ." > ~/" .$exportpath; 
      exec($cmdrun,$outpath,$worked); 
      switch($worked){ 
      case 0: 
      echo "Database <b>" .$mysqldbname ."</b> successfully exported to <b>~/" .$exportpath ."</b>"; 
      break; 
      case 1: 
      echo "Error occured: <b>" .$mysqldbname ."</b> to <b>~/" .$exportpath ."</b>"; 
      break; 
      case 2: 
      echo "There must be a mistake with your db login"; 
      break; 
      } 
     } 
    } 
    ?> 
0

我不認爲每個用戶都可以在那裏他的項目跑on.As你已經擁有了MySQL的服務器上運行的「EXEC」功能帳戶以及運行php網站的許可。爲什麼不嘗試在web服務器上安裝phpmyadmin呢?它可以滿足你各種功能。它也用php編寫。

1

要導出數據庫使用

function export_tables($host,$user,$pass,$name, $tables=false, $backup_name=false) 
{ 
$link = mysqli_connect($host,$user,$pass,$name); 
// Check connection 
if (mysqli_connect_errno()) { echo "Failed to connect to MySQL: " . mysqli_connect_error(); } 

mysqli_select_db($link,$name); 
mysqli_query($link,"SET NAMES 'utf8'"); 

//get all of the tables 
if($tables === false) 
{ 
    $tables = array(); 
    $result = mysqli_query($link,'SHOW TABLES'); 
    while($row = mysqli_fetch_row($result)) 
    { 
     $tables[] = $row[0]; 
    } 
} 
else 
{ 
    $tables = is_array($tables) ? $tables : explode(',',$tables); 
} 
$return=''; 
//cycle through 
foreach($tables as $table) 
{ 
    $result = mysqli_query($link,'SELECT * FROM '.$table); 
    $num_fields = mysqli_num_fields($result); 

    $row2 = mysqli_fetch_row(mysqli_query($link, 'SHOW CREATE TABLE '.$table)); 
    $return.= "\n\n".$row2[1].";\n\n"; 

    for ($i = 0; $i < $num_fields; $i++) 
    { 
     $st_counter= 0; 
     while($row = mysqli_fetch_row($result)) 
     { 
      //create new command if when starts and after 100 command cycle 
      if ($st_counter%100 == 0 || $st_counter == 0) { 
       $return.= "\nINSERT INTO ".$table." VALUES"; 
      } 


      $return.="\n("; 
      for($j=0; $j<$num_fields; $j++) 
      { 
       $row[$j] = addslashes($row[$j]); 
       $row[$j] = str_replace("\n","\\n",$row[$j]); 
       if (isset($row[$j])) { $return.= '"'.$row[$j].'"' ; } else { $return.= '""'; } 
       if ($j<($num_fields-1)) { $return.= ','; } 
      } 
      $return.=")"; 


      //create new command if when starts and after 100 command cycle (but detect this 1 cycle earlier !) 
      if (($st_counter+1)%100 == 0 && $st_counter != 0) { $return.= ";"; } 
      else            { $return.= ","; } 
      //+++++++ 
      $st_counter = $st_counter +1 ; 
     } 
     //as we cant detect WHILE loop end, so, just detect, if last command ends with comma(,) then replace it with semicolon(;) 
     if (substr($return, -1) == ',') {$return = substr($return, 0, -1). ';'; } 
    } 
    $return.="\n\n\n"; 
} 

//save file 
$backup_name = $backup_name ? $backup_name : $name."___(".date('H-i-s')."_".date('d-m-Y').")__rand".rand(1,11111111).'.sql'; 
file_put_contents($backup_name,$return); 
die('SUCCESS. Download BACKUP file: <a target="_blank" href="'.$backup_name.'">'.$backup_name.'</a> <br/><br/>After download, <a target="_blank" href="?delete_filee='.$backup_name.'">Delete it!</a> '); 

} 

if (!empty($_GET['delete_filee'])){ chdir(dirname(__file__));  
if (unlink($_GET['delete_filee'])) {die('file_deleted');} 
else        {die("file doesnt exist");} 
} 

,並使用

export_tables("localhost","username","password","db_name"); 

導入數據的基礎上使用

function import_tables($host,$user,$pass,$dbname,$sql_file, $clear_or_not=false) 
{ 
if (!file_exists($sql_file)) { 
    die('Input the SQL filename correctly! <button onclick="window.history.back();">Click Back</button>');} 

// Connect to MySQL server 
    //$link = mysqli_connect($host,$user,$pass,$name); 
    //mysqli_select_db($link,$mysqli); 
$mysqli = new mysqli($host, $user, $pass, $dbname); 
// Check connection 
if (mysqli_connect_errno()) { echo "Failed to connect to MySQL: " . mysqli_connect_error(); } 

if($clear_or_not) 
{ 
    $zzzzzz = $mysqli->query('SET foreign_key_checks = 0'); 
    if ($result = $mysqli->query("SHOW TABLES")) 
    { 
     while($row = $result->fetch_array(MYSQLI_NUM)) 
     { 
      $mysqli->query('DROP TABLE IF EXISTS '.$row[0]); 
     } 
    } 
    $zzzzzz = $mysqli->query('SET foreign_key_checks = 1'); 
} 

$mysqli->query("SET NAMES 'utf8'"); 
// Temporary variable, used to store current query 
$templine = ''; 
// Read in entire file 
$lines = file($sql_file); 
// Loop through each line 
foreach ($lines as $line) 
{ 
    // Skip it if it's a comment 
    if (substr($line, 0, 2) == '--' || $line == '') 
     continue; 
    // Add this line to the current segment 
    $templine .= $line; 
    // If it has a semicolon at the end, it's the end of the query 
    if (substr(trim($line), -1, 1) == ';') 
    { 
     // Perform the query 
     $mysqli->query($templine) or print('Error performing query \'<strong>' . $templine . '\': ' . $mysqli->error . '<br /><br />'); 
     // Reset temp variable to empty 
     $templine = ''; 
    } 
} 
echo 'Tables imported successfully. <button onclick="window.history.back();">Go Back</button>'; 
} 

,並執行它使用執行:

import_tables("localhost","username","pasword","db_name","my_filename.sql", true); //this will delete all exiting tables, and writes the imported database 
import_tables("localhost","username","pasword","db_name","my_filename.sql", false); //dont delete the exiting tables, just add those, which doesnt exist 

Source:

+0

我以前見過這個代碼。它不處理NULL。它不會正確分隔表名或列名。它不處理字符集。最糟糕的是,這段代碼會將其所有輸出附加到一個*單個字符串*中,這將超出PHP的內存限制,除非您的數據庫非常小。這是一個非常糟糕的解決方案。 – 2014-11-11 15:39:32

相關問題