/**
* @著者やぬえ
* @copyright Copyright (c) 2012 yanue.net
* @バージョン 1.1
※作成時期:2012年5月21日
更新日: 2012 年 10 月 6 日
更新手順: 1. SQL をインポートするときに SQL ファイル内のコメント「--」を削除することで、SQL 内の単一引用符と二重引用符がインポートできない問題が解決されます
2. 単一行を読み取った後、SQL を直接実行します。これにより、効率を向上させるために SQL ステートメントを配列に再結合し、配列から SQL を読み取ってインポートする必要がなくなります
* 注: ボリューム ファイルは _v1.sql (20120522021241_all_v1.sql) で終わります
* 機能: mysql データベースのボリュームバックアップを実現、バックアップ用のテーブルを選択、単一 SQL ファイルとボリューム SQL インポートを実現
* 使用方法:
*
* ------1. データベースのバックアップ(エクスポート) ---------------------------------- -- ------------------------
//それらは、ホスト、ユーザー名、パスワード、データベース名、データベースエンコーディングです
$db = 新しい DBManage ( 'localhost', 'root', 'root', 'test', 'utf8' );
// パラメータ: バックアップするテーブル (オプション)、バックアップ ディレクトリ (オプション、デフォルトはバックアップ)、ボリューム サイズ (オプション、デフォルトは 2000、つまり 2M)
$db->バックアップ ();
* ------2. データベースのリカバリ(インポート) ---------------------------------- -- ------------------------
//それらは、ホスト、ユーザー名、パスワード、データベース名、データベースエンコーディングです
$db = 新しい DBManage ( 'localhost', 'root', 'root', 'test', 'utf8' );
//パラメータ: SQLファイル
$db->restore ('./backup/20120516211738_all_v1.sql');
*------------------------------------------------ - ------------------------
*/
クラス DbManage {
var $db; // データベース接続
var $database; // 使用されるデータベース
var $sqldir; // データベースのバックアップ フォルダー
// 改行文字
プライベート $ds = "n";
// SQLを格納する変数
パブリック $sqlContent = "";
//各 SQL ステートメントの終了文字
パブリック $sqlEnd = ";";
/**
*初始化
*
* @param 文字列 $host
* @param string $ユーザー名
* @param string $password
* @param 文字列 $database
* @param 文字列 $charset
*/
関数 __construct($host = 'localhost', $username = 'root', $password = '', $database = 'test', $charset = 'utf8') {
$this->host = $host;
$this->ユーザー名 = $ユーザー名;
$this->password = $password;
$this->database = $database;
$this->charset = $charset;
set_time_limit(0);//時間制限なし
@ob_end_flush();
// データベースに接続します
$this->db = @mysql_connect ( $this->host, $this->username, $this->password ) または die( '
Mysql 接続エラー: '.mysql_error().'
');
//使用するデータベースを選択します
mysql_select_db ( $this->database, $this->db ) または die('
Mysql 接続エラー:' .mysql_error().'
');
// データベースのエンコード方法
mysql_query ( 'SET NAMES ' . $this->charset, $this->db );
}
/*
* * 新しいクエリデータベーステーブルを追加しました
*/
関数 getTables() {
$res = mysql_query ( "SHOW TABLES" );
$tables = 配列 ();
while ( $row = mysql_fetch_array ( $res ) ) {
$tables [] = $row [0];
}
$tables を返します。
}
/*
*
*------------------------------------------データベースバックアップ開始---- -------------------------------------------------- ----
*/
/**
* データベースのバックアップ
* パラメーター: バックアップするテーブル (オプション)、バックアップ ディレクトリ (オプション、デフォルトはバックアップ)、ボリューム サイズ (オプション、デフォルトは 2000、つまり 2M)
*
* @param $string $dir
* @param int $size
* @param $string $テーブル名
*/
関数バックアップ($tablename = '', $dir, $size) {
$dir = $dir : './backup/';
//ディレクトリを作成します
if (! is_dir ( $dir )) {
mkdir ( $dir, 0777, true ) または die ( 'フォルダーの作成に失敗しました' );
}
$サイズ = $サイズ ? : 2048;
$sql = '';
// 特定のテーブルのみをバックアップします
if (! emptyempty ( $tablename )) {
If(@mysql_num_rows(mysql_query("SHOW TABLES LIKE '".$tablename."'")) == 1) {
$this->_showMsg('Table-
' . $tablename .'-存在しません、確認してください!',true);
死ぬ();
$this->_showMsg('テーブル
' . $tablename.'');
// ダンプ情報を挿入します
$sql = $this->_retrieve ();
//テーブル構造情報を挿入
$sql .= $this->_insert_table_struct ( $tablename );
// データを挿入
$data = mysql_query ( "select * from " . $tablename );
// ファイル名の最初の部分
$filename = date ( 'YmdHis' )
。
// フィールドの数
$num_fields = mysql_num_fields ( $data );
$p = 1;
// 各レコードをループします
while ( $record = mysql_fetch_array ( $data ) ) {
// シングルレコード
$sql .= $this->_insert_record ( $tablename, $num_fields, $record );
// ボリュームサイズより大きい場合はファイルを書き込みます
If (strlen ( $sql ) >= $size * 1024) {
$file = $ファイル名 .$p
If ($this->_write_file ($sql, $file, $dir)) {
$this->_showMsg("Table-
" . $tablename . "- Volume-
" . $p . "-データのバックアップが完了しました、バックアップ ファイル[
" .$dir . $file ." ]");
} else {
$this->_showMsg("バックアップ テーブル -
" . $tablename . "- 失敗しました",true);
falseを返します。
$p ++;
// $ SQL 変数を空にリセットし、変数のサイズを再計算します
$sql = "";
// 時間内にデータをクリアします
unset($data,$record);
// SQL のサイズだけではサイズをスコアリングするのに十分ではありません
if ($sql != "") {
$ファイル名 .= "_v" .sql;
if ($this->_write_file ( $sql, $filename, $dir )) {
$this->_showMsg( "テーブル-
" . $tablename . "-ボリューム-
" . $p . "-データのバックアップが完了しました、バックアップ ファイル[
" .$dir . $filename ." ]");
} それ以外 {
$this->_showMsg("バックアップ ボリューム-
" . $p . "-失敗
");
false を返します。
$this->_showMsg("おめでとうございます!
バックアップが成功しました");
} else {
$this->_showMsg('バックアップ中');
// すべてのテーブルをバックアップします
If ($tables = mysql_query ( "show table status from " . $this->database )) {
$ This-& gt; _Showmsg ("データベース構造の読み取りに成功しました!");
$this->_showMsg("データベース構造の読み取りに失敗しました!");
終了 (0);
// ダンプ情報を挿入します
$sql .= $this->_retrieve ();
// ファイル名の最初の部分
$filename = date ( 'YmdHis' )
;
// すべてのテーブルを検索します
$tables = mysql_query ( 'SHOW TABLES' );
$p = 1;
// すべてのテーブルをループします
while ( $table = mysql_fetch_array ( $tables ) ) {
$tablename = $table [0];
$sql .= $this->_insert_table_struct ( $tablename );
$data = mysql_query ( "select * from " . $tablename );
$num_fields = mysql_num_fields ( $data );
// 各レコードをループします
while ( $record = mysql_fetch_array ( $data ) ) {
// シングルレコード
$sql .= $this->_insert_record ( $tablename, $num_fields, $record );
// ボリュームサイズより大きい場合はファイルを書き込みます
If (strlen ( $sql ) >= $size * 1000) {
$file = $ファイル名 .$p
// ファイルを書き込む 文
If ($this->_write_file ($sql, $file, $dir)) {
$this->_showMsg("-ボリューム-
" . $p . "-データのバックアップが完了しました。バックアップ ファイル[
".$dir.$ファイル。" ]");
$this->_showMsg("ボリューム-
" . $p . "-バックアップに失敗しました!",true);
falseを返します
// 次のサブロール个
$p ++;
// $sql 変数を空にリセットし、変数のサイズを再計算します
$sql = "";
// SQL のサイズだけではサイズをスコアリングするのに十分ではありません
if ($sql != "") {
$ファイル名 .= "_v" .sql";
if ($this->_write_file ( $sql, $filename, $dir )) {
$this->_showMsg("-ボリューム-
" . $p . "-データのバックアップが完了しました。バックアップ ファイル[
".$dir.$ファイル名。" ]");
} それ以外 {
$this->_showMsg("ボリューム-
" . $p . "-バックアップに失敗しました",true);
false を返します。
$this->_showMsg("おめでとうございます!
バックアップが成功しました");
}
}
// 時間内に情報を出力します
プライベート関数 _showMsg($msg,$err=false){
$err = $err ? "
エラー:" ;
echo "
".$msg."
";
フラッシュ();
}
/**
* 基本的なデータベースのバックアップ情報を挿入します
*
* @return 文字列
*/
プライベート関数 _retrieve() {
$value = '';
$value .= '--'
$value .= '-- MySQL データベース ダンプ'
$value .= '-- DbManage クラス、Power By yanue によって作成されました ' 。
$value .= '-- http://yanue.net '
$value .= '--'
$value .= '-- ホスト: ' . $this->ds;
$value .= '-- 日付: ' . date ( 'Y' ) . ' month ' . ' day' .私' ) $this->ds;
$value .= '-- MySQL バージョン: ' . mysql_get_server_info ()
$value .= '-- PHP バージョン: ' . phpversion ()
$value .= $this->ds;
$value .= '--'
$value .= '-- データベース: `' . $this->ds;
$value .= '--' . $this->ds;
$value .= '-------------------------------------------- -- ----------';
$value .= $this->ds . $this->ds;
$value を返します。
}
/**
* テーブル構造を挿入します
*
* @param 不明なタイプ $table
* @return 文字列
*/
プライベート関数 _insert_table_structor($table) {
$sql = '';
$sql .= "--" . $this->ds;$sql .= "--テーブル構造" .$this->ds;
$sql .= "--" . $this->ds;
// テーブルが存在する場合は削除します
$sql .= "DROP TABLE IF EXISTS `" . $this->sqlEnd
// 詳細なテーブル情報を取得します
$res = mysql_query ( 'SHOW CREATE TABLE `' . $table . '`' );
$row = mysql_fetch_array ( $res );
$sql .= $row [1];
$sql .= $this->sqlEnd .
//
を追加します
$sql .= $this->ds;
$sql .= "--" .$this->ds;
$sql .= "-- テーブル内のデータを転送します " .this->ds;
$sql .= "--" .$this->ds;
$sql .= $this->ds;
戻り $sql;
}
/**
* 単一レコードを挿入します
*
* @param string $table
* @param int $num_fields
* @param 配列 $record
* @return 文字列
*/
プライベート関数 _insert_record($table, $num_fields, $record) {
// カンマ区切りの SQL フィールド
$挿入 = '';
$comma = ""
;
$insert .= "INSERT INTO `" . $table . "` VALUES(";
)
// 各サブセクションのコンテンツをループします
for($i = 0; $i
$insert .= ($comma . "'" . mysql_escape_string ( $record [$i] ) . "'");
$comma = ",";
}
$insert .= ");" .
戻り $insert;
}
/**
*ファイルに書き込む
*
* @param 文字列 $sql
* @param string $ファイル名
* @param 文字列 $dir
* @return ブール値
*/
プライベート関数 _write_file($sql, $filename, $dir) {
$dir = $dir : './backup/';
//ディレクトリを作成します
if (! is_dir ( $dir )) {
mkdir ( $dir, 0777, true );
}
$re = true;
If (! @$fp = fopen ( $dir . $filename, "w+" )) {
$re = false;
$this->_showMsg("SQL ファイルを開けませんでした!",true);
}
If (! @fwrite ( $fp, $sql )) {
$re = false;
$this->_showMsg("SQL ファイルの書き込みに失敗しました。ファイルが書き込み可能かどうかを確認してください",true);
}
if (! @fclose ( $fp )) {
$re = false;
$this->_showMsg("SQL ファイルを閉じることができませんでした!",true);
}
$re を返します。
}
/*
*
* ---------------------------- 上: データベースのエクスポート ----------- 分割線 ---- ------次: データベースのインポート--------------------------------
*/
/**
* バックアップデータをインポートします
* 説明: ボリューム ファイル形式 20120516211738_all_v1.sql
* パラメータ: ファイルパス (必須)
*
* @param 文字列 $sqlfile
*/
関数復元($sqlfile) {
// ファイルが存在するかどうかを確認します
if (! file_exists ( $sqlfile )) {
$this->_showMsg("SQL ファイルが存在しません。確認してください。",true);
終了 ();
}
$this->lock ( $this->database );
// データベースの保存場所を取得します
$sqlpath = パス情報 ($sqlfile);
$this->sqldir = $sqlpath ['dirname'];
// サブボリュームが含まれているかどうかを確認し、20120516211738_all_v1.sql を _v から分離します。存在する場合は、サブボリュームがあることを意味します
$volume = 爆発 ( "_v", $sqlfile );
$volume_path = $volume [0];
$this->_showMsg("プログラムが終了しないように、ブラウザを更新して閉じないでください。注意しないと、データベース構造が破損します。");
$this->_showMsg("バックアップ データをインポート中です。お待ちください!");
if (emptyempty ( $volume [1] )) {
$this->_showMsg ( "SQL のインポート:
" . $sqlfile . '');
If ($this->_import ( $sqlfile )) {
$this->_showMsg( "データベースは正常にインポートされました!");
$this->_showMsg('データベースのインポートに失敗しました!', true);
終了 ();
} else {
// スクロールがある場合、現在の 1 ポイント ボリュームが表示され、残りのスクロールが実行されます。
$volume_id =explode ( ".sq", $volume [1] );
// 現在のボリュームは $volume_id です
$volume_id = intval ( $volume_id [0] );
while ( $volume_id ) {
$tmpfile = $volume_path .$volume_id
// 他のボリュームが存在するため、実行を続行します
If (file_exists ( $tmpfile )) {
// インポートメソッドを実行します
$this->msg .= "ボリューム $volume_id:
'';
If ($this->_import ($tmpfile)) {
} else {
$volume_id = $volume_id :1;
exit ( "ボリュームのインポート:
" . $tmpfile . '失敗! データベース構造が破損している可能性があります! ボリューム 1 からインポートしてみてください' );
} それ以外 {
$ This-& gt; msg. = "このサブバックアップは正常に導入されました! & Lt; br /& gt;";
$volume_id ++;
}if (emptyempty ( $volume [1] )) {
$this->_showMsg ( "SQL のインポート:
" . $sqlfile . '');
If ($this->_import ( $sqlfile )) {
$this->_showMsg( "データベースは正常にインポートされました!");
$this->_showMsg('データベースのインポートに失敗しました!',true);
終了 ();
} else {
// スクロールがある場合、current は現在のロール数となり、残りのスクロールが実行されます。
$volume_id =explode ( ".sq", $volume [1] );
// 現在のボリュームは $volume_id です
$volume_id = intval ( $volume_id [0] );
while ( $volume_id ) {
$tmpfile = $volume_path .$volume_id
// 他のボリュームが存在するため、実行を続行します
If (file_exists ( $tmpfile )) {
// インポートメソッドを実行します
$this->msg .= "ボリューム $volume_id:
'';
If ($this->_import ($tmpfile)) {
} else {
$volume_id = $volume_id :1;
exit ( "ボリュームのインポート:
" . $tmpfile . '失敗! データベース構造が破損している可能性があります! ボリューム 1 からインポートしてみてください' );
} それ以外 {$ this> msg。= "このボリュームのすべてのバックアップは正常にインポートされました!< br />";
$volume_id ++;
}
}
/**
* SQLをデータベースにインポートします(通常のインポート)
*
* @param 文字列 $sqlfile
* @return ブール値
*/
プライベート関数 _import($sqlfile) {
// SQL ファイルに含まれる SQL ステートメントの配列
$sqls = 配列
;
$f = fopen ( $sqlfile, "rb" );
//テーブルバッファ変数を作成します
$create_table = '';
while ( ! feof ( $f ) ) {
// SQLの各行を読み取ります
$line = fgets ( $f );
// このステップでは、作成されたテーブルを完全な SQL ステートメントに合成します
// 末尾に ';' (つまり、完全な SQL ステートメント、ここに insert ステートメント) が含まれておらず、'ENGINE=' (つまり、テーブルを作成する最後の文) が含まれていない場合
If (! preg_match ( '/;/', $line ) || preg_match ( '/ENGINE=/', $line )) {
// この SQL ステートメントと作成されたテーブル SQL 接続を保存します
$create_table .= $line;
// テーブル作成の最後の文が含まれている場合
If (preg_match ( '/ENGINE=/', $create_table)) {
// SQL文を実行してテーブルを作成します
// 現在のテーブルをクリアし、次のテーブルを作成する準備をします
$create_table = '';
// 今回はスキップします
続けてください。
// SQL ステートメントを実行します
$this->_insert_into($line);
}
fclose ( $f );
true を返します
}
// 単一の SQL ステートメントを挿入します
プライベート関数 _insert_into($sql){
If (! mysql_query ( トリム ( $sql ) )) {
$this->msg .= mysql_error ();
false を返します
}
}
/*
* -----------------------------データベースインポート終了--------------- - -----------------
*/
//データベース接続を閉じる
プライベート関数 close() {
mysql_close ($this->db);
}
// バックアップまたはインポート中のエラーを避けるためにデータベースをロックします
プライベート関数 lock($tablename, $op = "WRITE") {
If (mysql_query ( "lock tables " . $tablename . " " . $op ))
true を返します。
その他
false を返します
}
// ロックを解除します
プライベート関数unlock() {
if (mysql_query ( "テーブルのロックを解除" ))
true を返します。
その他
false を返します
}
// 破壊
関数 __destruct() {
If($this->db){
mysql_query ( "テーブルのロックを解除", $this->db );
mysql_close ($this->db);
}
}
}
?>
この記事で説明した内容が皆様の PHP プログラミング設計に役立つことを願っています。