Backup şi restore MySQL cu PHP


O webaplicaţie realizată de mine, la care, ca administrator, lucram doar eu – alţii doar la “exploatare”, în front-end -, va fi acum replicată şi pentru alţii. M-am trezit astfel în postura că multe lucruri a trebuit să le rescriu cu gândul că cei ce vor folosi această webaplicaţie nu se pricep neapărat (de fapt unii chiar deloc) la MySQL. Dacă pentru mine e simplu de exemplu din HeidiSQL (mamă! nu mă satur de el, e extraordinar), sau chiar din phpMyAdmin să fac copii de siguranţă şi să le import în altă parte, pentru alţii ar fi chineză.

imagine

Drept urmare am săpat pe net şi am dat de exact scripturile necesare. Mai întâi o precizare – sunt şi soluţii gen Sypex Dumper şi altele, dar m-a interesat să am ceva în webaplicaţia mea, care să facă doar ce doresc, nu zeci de chestii din care îmi trebuie 1-2. După cum vedeţi mai sus, am acum două pagini pentru cele două operaţii. Şi să o luăm cu începutul. Pentru ca să fac backup la baza de date MySQL m-am folosit de scriptul lui David Walsh. Îmi permit să îl copiez aici cu câteva explicaţii în română.

function backup_tables($host,$user,$pass,$name,$tables = '*'){
	$link = mysql_connect($host,$user,$pass);
	mysql_select_db($name,$link);
    //extragerea tabelelor
	if($tables == '*'){
        //toate
		$tables = array();
		$result = mysql_query('SHOW TABLES');
		while($row = mysql_fetch_row($result))
			$tables[] = $row[0];
	}
	else
        //cele puse ca parametru
		$tables = is_array($tables) ? $tables : explode(',',$tables);
	//parcurgem tabela cu tabela
	foreach($tables as $table){
		$result = mysql_query('SELECT * FROM '.$table);
		$num_fields = mysql_num_fields($result);
		//comenzile pentru stergerea si recrearea tabelei
		$return.= 'DROP TABLE '.$table.';';
		$row2 = mysql_fetch_row(mysql_query('SHOW CREATE TABLE '.$table));
		$return.= "\n\n".$row2[1].";\n\n";
		//comenzile pentru popularea tabelei
		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";
	}
	//salvarea in fisier
	$handle = fopen('db-backup-'.time().'-'.(md5(implode(',',$tables))).'.sql','w+');
	fwrite($handle,$return);
	fclose($handle);
}

Acum cei care vor mai folosi webaplicaţia vor putea să se “joace” în voie, pentru că, chiar dacă nu au undo la ceea ce fac, pot să facă backup şi apoi – după ce/dacă strică ceva – restore. După cum vedeţi din captura de mai jos, la codul de mai sus eu am adăugat la numele fişierelor data şi ora, pentru că mă ajută. Am făcut un script care parcurge directorul cu backupuri şi le afişează cel recent primul. Un click şi gata, ai revenit la situaţia din acel backup. (Avantajele sunt de fapt mai mari, căci aplicaţia rulează pe un server dar şi pe calculatoare cu WAMP şi e util acest backup&restore pentru “deplasarea” bazei de date.)

imagine

Codul pentru restore l-am găsit aici, doar că desigur l-am adaptat după cum am descris mai sus. Atenţie: am pus mai jos „esenţa”, care presupune conexiunea făcută. Dacă nu e făcută daţi ca mai sus parametrii.

function restore_tables($filename [şi tot ce mai trebuie]){
    [completaţi aici după nevoi]
    $templine = '';
    //citesc fisierul
    $lines = file($filename);
    //parcurg linie cu linie
    foreach ($lines as $line){
	   //sari daca e comentariu
        if (substr($line, 0, 2) == '--' || $line == '')
            continue;
        //altfel adauga linia la segmentul curent
        $templine .= $line;
        //daca are punct si virgula la final s-a terminat comanda MySQL
        if (substr(trim($line), -1, 1) == ';'){
            //executam comanda MySQL
            mysql_query($templine) or print('A dat eroare \'<strong>' . $templine . '\': ' . mysql_error() . '<br /><br />');
            //golim ca sa mergem mai departe cu ce a mai ramas
            $templine = '';
        }
    }
}

Problemă rezolvată. Personal sunt foarte încântat. Şi la fel vor fi şi cei care – chiar dacă acum nu au nevoie de aşa ceva – vor ajunge aici la un moment dat exclamând “exact de ce aveam nevoie!” Cât priveşte problemele de securitate, desigur e de ţinut cont şi de acest aspect. Directorul de backup numiţi-l cumva aiurea, puneţi un index.html gol acolo, şi apelaţi şi la .htaccess pentru reguli mai stricte de acces.


Apreciază articolul:

1 stea2 stea3 stea4 stea5 stea (3 evaluări, media: 5,00 din 5)
Loading...Loading...

6 comentarii

  1. Birkoff spune:

    Am citit de 2 ori articolul dar nu am gasit link de descarcare a aplicatiei sau un link de unde se poate testa… E pusa cumva pe google code sau source forge? Ce nume are?

  2. radu.capan spune:

    Îmi pare rău dacă nu m-am exprimat clar. Deci: am o webaplicaţie proprie, ce nu e publică (e de uz… eclezial). Acum webaplicaţia va fi folosită şi de alte Episcopii, şi pentru că o vor folosi şi alţii, mai fără experienţă, am avut nevoie de un modul pentru backup, respectiv restore. De aici problema, de aici soluţia, de aici articolul de faţă.
    Nu aplicaţia în sine o semnalez mai sus, ci cele două funcţii utile pentru backup şi pentru restore. Pornind de la ele, cine are nevoie (şi ştie PHP) îşi poate construi această funcţionalitate utilă după mine. Am exemplificat cu capturi din webaplicaţia mea doar ca să fie mai „palpabilă” ideea.

  3. Mascka spune:

    Foarte simpla, foarte usoara, foarte buna.
    Daca tot ai postat aceste doua scriptulete simple, ataseaza si pe cel de cel de sortare cronologica a backup-urilor, sa fie tacamul complet. :)

  4. softx1 spune:

    Mi-a placut. Asa sa o tii Radu.

  5. razvan spune:

    Foarte interesant. Chiar mi-am pus si eu problema cum pot face un script de back-up, dar a ramas ca idee pentru documentat candva… Cand o sa am timp si nevoie.

  6. dan spune:

    Scapa de ereg_replace-ul ala, vezi ca e deprecated.


Lasă un răspuns

Adresa ta de email nu va fi publicată. Câmpurile necesare sunt marcate *