2015-10-19 9 views
8

これは私にとって新しいものです。このMySQLデータベースのPHPスクリプトをDavid Walshで使用すると、実行時に空のSQLファイルが取得されます。PHPスクリプトは空のSQLファイルを作成します

<?php 
backup_tables('localhost','username','password','blog'); 

/* backup the db OR just a table */ 
function backup_tables($host,$user,$pass,$name,$tables = '*') 
{ 
    $return = ''; 
    $link = mysql_connect($host,$user,$pass); 
    mysql_select_db($name,$link); 

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

    //cycle through 
    foreach($tables as $table) 
    { 
     $result = mysql_query('SELECT * FROM '.$table); 
     $num_fields = mysql_num_fields($result); 

     $return.= 'DROP TABLE '.$table.';'; 
     $row2 = mysql_fetch_row(mysql_query('SHOW CREATE TABLE '.$table)); 
     $return.= "\n\n".$row2[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 file 
    $handle = fopen('db-backup-'.time().'-'.(md5(implode(',',$tables))).'.sql','w+'); 
    fwrite($handle,$return); 
    fclose($handle); 
    mysql_close($link); 
} 
?> 

Iコードを理解できるように、私はブログを上に機能backup_tables()にあるDB名を入力しました。

なぜスクリプトは空のSQLファイルを作成しますか?

+1

何がこのコードのフォームを除いていますか? // あなたの目標は何ですか? –

+0

@ maytham-ɯɐɥıλɐɯ:スケジュールされたURLを実行して、DB全体の夜間バックアップを実行する予定です。 – lol5433

+0

あなたのデータベースはどこにありますか、それはローカルであるか、ホストされていますか、それをどこにバックアップしたいのですか(distanation)ローカルか何か他のところ –

答えて

1

、私は私の研究を行なったし、どのような方法は、興味深い質問を見つけました。

phpコードでmysqlをバックアップするソリューションのほとんどは、古くなっており、今日の環境には問題があります。したがって、一度更新されて有用なものがあれば、私は興味がありました。私の計画は、私が1つを見つけることができなかったなら、私は1つを開発したいと思った。

しかし、解決策が見つかりました。私はテーブルをエクスポートして再インポートすることでそれをテストしました。そして、あなたがそれを好きになると思います。

コードに行く前に、私は次のような発言、次ている:あなたは以下の通りですデビッド・ウォルシュに関して

  1. をコードし、チュートリアルでは、廃止されたMySQLを使用して、2008年からです。以下のコードはおそらくMySQLiを使用しています。
  2. コードを実行すると、ダウンロード可能なバックアップファイルが提供されます。ファイルは、サーバー、クラウドストレージ(Dropboxなど)などの安全なリモート宛先に渡すことができます。
  3. 定期的にバックアップ機能を実行するには、お使いのOS、環境、戦略、およびその方法をどのようにしたいかによって異なります。ほとんどの場合、CRONは毎晩1回、またはそのようなものを実行するようにスケジュールするためのソリューションです。チュートリアルやそのオンラインに関する有益な情報があります。
  4. ほとんどのホストプロバイダがリモートmysqlアクセスをブロックしているので、この機能はローカルホスト上でのみバックアップされます(この機能はリモートのmysqlテーブルのバックアップを取ることができません)。
  5. 最初は、rootユーザー名を使用しても問題ありませんが、それが機能するときは、バックアップを取るテーブルへのユーザー名とパスワード固有のアクセス権を作成することをお勧めします。

注:コードはコードの所有者に対し、このpageで発見され、私はちょうどそれはOPのために動作させるために、コードの余分な行を追加しました。

非常に重要な注意:あなたが共有ホスティングしている場合 ので、あなたがあなたの実行時間を延長する必要があり、特別に、通常、時間がかかることがあり、そのようなコードを実行して、サーバーのリソース&容量とデータベースのサイズに応じて、 300秒(5分)、バックアップは低負荷時に行う必要があります。 最悪の場合、コードでその部分が防止されている場合は、ホストプロバイダに実行時間を延長するよう依頼する必要があります。

作業コード

<?php 

define("MAX_EXECUTION_TIME", 100); // seconds 

$timeline = time() + MAX_EXECUTION_TIME; 

EXPORT_TABLES('localhost', 'root', '', 'blog'); 

function EXPORT_TABLES($host, $user, $pass, $name, $tables = false, $backup_name = false) 
{ 
    $mysqli = new mysqli($host, $user, $pass, $name); 
    $mysqli->select_db($name); 
    $mysqli->query("SET NAMES 'utf8'"); 
    $queryTables = $mysqli->query('SHOW TABLES'); 
    while ($row = $queryTables->fetch_row()) 
    { 
     $target_tables[] = $row[0]; 
    } 
    if ($tables !== false) 
    { 
     $target_tables = array_intersect($target_tables, $tables); 
    } 
    try 
    { 
     foreach ($target_tables as $table) 
     { 
      $result = $mysqli->query('SELECT * FROM ' . $table); 
      $fields_amount = $result->field_count; 
      $rows_num = $mysqli->affected_rows; 
      $res = $mysqli->query('SHOW CREATE TABLE ' . $table); 
      $TableMLine = $res->fetch_row(); 
      $content = (!isset($content) ? '' : $content) . "\n\n" . $TableMLine[1] . ";\n\n"; 
      for ($i = 0, $st_counter = 0; $i < $fields_amount; $i ++, $st_counter = 0) 
      { 
       while ($row = $result->fetch_row()) 
       { //when started (and every after 100 command cycle): 
        if ($st_counter % 100 == 0 || $st_counter == 0) 
        { 
         $content .= "\nINSERT INTO " . $table . " VALUES"; 
        } 
        $content .= "\n("; 
        for ($j = 0; $j < $fields_amount; $j ++) 
        { 
         $row[$j] = str_replace("\n", "\\n", addslashes($row[$j])); 
         if (isset($row[$j])) 
         { 
          $content .= '"' . $row[$j] . '"'; 
         } else 
         { 
          $content .= '""'; 
         } 
         if ($j < ($fields_amount - 1)) 
         { 
          $content .= ','; 
         } 
        } 
        $content .= ")"; 
        //every after 100 command cycle [or at last line] ....p.s. but should be inserted 1 cycle eariler 
        if ((($st_counter + 1) % 100 == 0 && $st_counter != 0) || $st_counter + 1 == $rows_num) 
        { 
         $content .= ";"; 
        } else 
        { 
         $content .= ","; 
        } 
        $st_counter = $st_counter + 1; 
       } 
      } 
      $content .= "\n\n\n"; 
     } 
    } catch (Exception $e) 
    { 
     echo 'Caught exception: ', $e->getMessage(), "\n"; 
    } 
    $backup_name = $backup_name ? $backup_name : $name . "___(" . date('H-i-s') . "_" . date('d-m-Y') . ")__rand" . rand(1, 11111111) . ".sql"; 
    header('Content-Type: application/octet-stream'); 
    header("Content-Transfer-Encoding: Binary"); 
    header("Content-disposition: attachment; filename=\"" . $backup_name . "\""); 
    echo $content; 
    exit; 
} 

?> 
+1

ありがとうございました。私は私のDBでそれをテストし、それは私に数分後に500 Server Errorを与えました。それはサイズのためですか?データベースには680個のテーブルがあります。 – lol5433

+0

あなたは歓迎です、私はそれが動作するかどうかを確認するために小さなデータベースで始めることをお勧めしますか?その後、私たちはいくつかのコンソーシアムを取ることができます。 –

+0

11台のテーブルを使ってローカルデータベースと完全に連携しました。 – lol5433

2

。= 'DROP行の前のどこかで$ returnが定義されていません。私はそのような未定義の変数を含むエラーがあった。 foreach()の上に$ return = ''を追加します。

+0

お返事ありがとうございますが、私は恐怖をしませんでした。同じ結果です。 – lol5433

+2

投稿にコメントできない場合は、どうすれば評判に参加できますか? –

+0

[50人のコメントキャップの理由はあります](http://meta.stackexchange.com/questions/214173/why-do-i-need-50-reputation-to-comment-what-c​​an-i-do -instead) – Machavity

4

私はこのスクリプトを試しましたが、いくつかのエラーといくつかの減価償却に関する警告がありましたが、私のために働いていました。

ファイルを保存するには、スクリプトが存在するディレクトリに書き込み権限があることを確認します。

chmod 0777 /home/site/dir 

は、右のこの行の前に次のコード

$return = ''; 

を追加し、Undefined variable: return通知を防ぐために

$link = mysql_connect($host,$user,$pass); 

そして - 私は、これは明白なようだ知っている - しかし、あなたが接続していることを確認してくださいまたは適切なデータベース名に入力ミスがないことを確認してください。

backup_tables('localhost','myUsername','myPassword','myDatabase'); 

最後に、データベースにテーブルがあることを確認してください。私は何が起こったのかを見るためにデータベースにテーブルを置かずに走った。そしてそれは空の文書を吐き出した。ちょうどあなたが説明したように。 :)

+0

@ Cyb3これを試したかどうかは分かりませんが、現在どのようなエラーが出ていますか、これを使用する際の問題は何ですか? – davejal

1

テーブル名でスクリプトを実行すると、正しく動作します。 $ return = ''を追加する必要があります。途中で26行目に。 backup_tables('localhost','root','arcd','unilicadb', 'fa_university');

ワイルドカードでbackup_tables('localhost','root','arcd','unilicadb', '*');を実行すると、大規模なデータベースがある場合に備えてメモリエラーが発生する可能性があります。

「致命的なエラー:134217728バイトの許可メモリサイズが使い果たさ(34399640バイトを割り当てしようとした)」timgavinの答えに追加するにはerror_reporting(E_ALL);

2

を追加

てみてください、あなたはまた、単に、このスクリプトに圧縮を追加することができますトップ

$compression = true; 

を追加し、下 を変更

$handle = fopen('db-backup-'.time().'-'.(md5(implode(',',$tables))).'.sql','w+'); 
fwrite($handle,$return); 
fclose($handle); 
mysql_close($link); 

から

if ($compression) { 
    $zp = gzopen($BACKUP_PATH . 'db-backup-'.time().'-'.(md5(implode(',',$tables))).'.sql.gz', "w9"); 
    gzwrite($zp, $return); 
    gzclose($zp); 
} else { 
    $handle = fopen($BACKUP_PATH . 'db-backup-'.time().'-'.(md5(implode(',',$tables))).'.sql','w+'); 
    fwrite($handle,$return); 
    fclose($handle); 
} 

に別のオプションは、his blogにmohd_anasによって説明され、またgithub

5

mysqldumpであり、これを行うためのより良い方法、あります。これは、テーブルのバックアップを作成するために構築され、それははるかに速く、PHPよりもです。あなたは自分の端末で次のコマンドを実行する必要があります。

mysqldump -h localhost -u root -p --result-file ~/backup.sql my_database 

バックアップするだけでいくつかのテーブルをしたい場合は、あなたがこれを行うことができます:

mysqldump -h localhost -u root -p --result-file ~/backup.sql my_database table_a table_b 

あなたが使用することができ、より多くのオプションがあります。ので、私はそれらを表示されませんが、あなたはここでそれらについて読むことができます。

https://dev.mysql.com/doc/refman/5.1/en/mysqldump.html

をあなたはちょうどを通してそれを実行することができるよりも、これを行うためにPHPが必要な場合またはいくつかの他の類似の方法:私は最初からあなたの質問に、次のされています

exec("mysqldump -h $host -u $user -p$pass --result-file ~/$file $database $tables"); 
+0

はい、ありがとう、私はこれをすでに知っています。しかし、私はこれだけのためにPHPを使用するように制限されています...私はむしろこれのためのシェルスクリプトでcronjobを使用したいと思います。 – lol5433

+0

@ Cyb3外部入力がなく、PHPに制限されている場合は、PHPからコマンドを実行してください。 – Alfabravo

1
backup_tables('localhost','root','','dbname'); 

/* backup the db OR just a table */ 
function backup_tables($host,$user,$pass,$name,$tables = '*') 
{ 
    $return = ''; 
    $link = mysqli_connect($host,$user,$pass, $name); 
    //get all of the tables 
    if($tables == '*') 
    { 
     $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); 
    } 

    //cycle through 
    foreach($tables as $table) 
    { 
     $result = mysqli_query($link, 'SELECT * FROM '.$table); 
     $num_fields = mysqli_num_fields($result); 

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

     for ($i = 0; $i < $num_fields; $i++) 
     { 
      while($row = mysqli_fetch_row($result)) 
      { 
       $return.= 'INSERT INTO '.$table.' VALUES('; 
       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.= ");\n"; 
      } 
     } 
     $return.="\n\n\n"; 
    } 

    //save file 
    $handle = fopen('db-backup-'.time().'-'.(md5(implode(',',$tables))).'.sql','w+'); 
    fwrite($handle,$return); 
    fclose($handle); 
    mysqli_close($link); 
} 
関連する問題