2014-10-30 88 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

相关问题