Az adatbázis biztonsági mentése phpMyAdmin nélkül

Az adatbázis biztonsági mentése phpMyAdmin nélkül

Az adatbázis biztonsági mentése phpMyAdmin nélkül

Számos esetben merült már fel ügyfelek körében, vagy a saját CMS rendszerem kapcsán a biztonsági mentés kérdése. Biztonsági okokból érdemes valamilyen rendszerességgel készíteni az adatbázisunk tartalmáról is biztonsági mentést. Ebben a leírásban azt mutatom be, hogy hogyan teheted ezt meg phpMyAdmin használata nélkül. Így kényelmesen bármikor egy kattintással elvégezheted a biztonsági mentést, akár a saját adminisztrációs felületedről is. Ráadásul eldöntheted, hogy a tárhelyedre mentsen, vagy szeretnéd a saját számítógépedre letölteni és még azt is beállíthatod, hogy mindezt betömörítve tegye, vagy sem.

Az előző leírásaimból fogok felhasználni néhány függvényt ehhez, melyek a "dump" nevű mappát fogják létrehozni, illetve menedzselni azt a folyamat alatt.

Először is szükségünk van egy adatbázis kapcsolatra, majd a kiválasztott adatbázis tábláit ki kell valamiképp listáznunk. Erre létezik egy egyszerű SQL utasítás.

PHP


$select_table = mysqli_query($GLOBALS['connect'], "SHOW TABLES FROM ".$database);
while ($data_table = mysqli_fetch_assoc($select_table))
	{
	$select_table_option = mysqli_query($GLOBALS['connect'], "SHOW TABLE STATUS WHERE Name = '".$data_table['Tables_in_'.$database]."'");
	$data_table_option = mysqli_fetch_assoc($select_table_option);
	}

Ezt követően kilistázzuk a választott adatbázisunk adattábláit és lekérdezzük ezeknek a tábláknak a főbb paramétereit. Ilyen paraméter például az oszlopainak a mérete, a típusa, hogy milyen kulcsokat használnak, illetve egyéb kiegészítő lehetőségeket, mint, hogy milyen karakterkódolást használ és, hogy a mező értéke lehet-e null.

PHP


$select_column = mysqli_query($GLOBALS['connect'], "SELECT column_name, data_type, column_type, character_set_name, collation_name, extra, column_key, column_default, is_nullable FROM information_schema.columns WHERE table_name = '".$data_table['Tables_in_'.$database]."' ORDER BY ordinal_position ASC");

A lekérdezés eredményét pedig gondosan leellenőrizzük, és ennek megfelelően eltároljuk különböző tömbökben, ami a későbbi feldolgozás alapját fogja szolgálni. Tehát ebben a lépésben minden adatot kiválogatunk és eltárolunk. A kódrészletből kiderül, hogy megvizsgáljuk a típust, a típusnak megfelelően beállítjuk a karakterkódolást. Megvizsgáljuk a kulcsokat és az extra tulajdonságokat.

PHP


while ($data_column = mysqli_fetch_assoc($select_column))
	{
	if (!filter_var($id))
		{
		$id = $data_column['column_name'];
		}
	$column_array[] = $data_column['column_name'];
	$type_array[] = $data_column['data_type'];
	$create_column .= '`'.$data_column['column_name'].'` '.$data_column['column_type'];
	if (!filter_var($character_set_name))
		{
		$character_set_name = $data_column['character_set_name'];
		}
	if (($data_column['data_type'] == 'varchar') || ($data_column['data_type'] == 'text'))
		{
		$create_column .= ' COLLATE '.$data_column['collation_name'];
		}
	if ($data_column['is_nullable'] == 'NO')
		{
		$create_column .= ' NOT NULL';
		}
	elseif (($data_column['is_nullable'] == 'YES') && ($data_column['column_default'] === NULL))
		{
		$create_column .= ' DEFAULT NULL';
		}
	if ($data_column['column_default'] !== NULL)
		{
		$create_column .= ' DEFAULT \''.$data_column['column_default'].'\'';
		}
	if (filter_var($data_column['extra']))
		{
		$create_column .= ' '.strtoupper($data_column['extra']);
		}
	if (filter_var($data_column['column_key']))
		{
		if ($data_column['column_key'] == 'PRI')
			{
			$primary_array[] = $data_column['column_name'];
			}
		elseif ($data_column['column_key'] == 'UNI')
			{
			$unique_array[] = $data_column['column_name'];
			}
		elseif ($data_column['column_key'] == 'MUL')
			{
			$key_array[] = $data_column['column_name'];
			}
		}
	$create_column .= ", \n\t";
	}

Ezt követően pedig összeállítjuk a tábláinkat létrehozó SQL utasításokat és letároljuk a "$dump_temp" változóban.

PHP


$i = 0;
if (filter_var_array($primary_array))
	{
	$count = count($primary_array) - 1;
	foreach ($primary_array as $key)
		{
		if ($i > 0)
			{
			$create_column .= ", \n\t";
			}
		$create_column .= 'PRIMARY KEY (`'.$key.'`)';
		$i++;
		}
	}
if (filter_var_array($unique_array))
	{
	foreach ($unique_array as $key)
		{
		if ($i > 0)
			{
			$create_column .= ", \n\t";
			}
		$create_column .= 'UNIQUE KEY `'.$key.'` (`'.$key.'`)';
		$i++;
		}
	}
if (filter_var_array($key_array))
	{
	foreach ($key_array as $key)
		{
		if ($i > 0)
			{
			$create_column .= ", \n\t";
			}
		$create_column .= 'KEY `'.$key.'` (`'.$key.'`)';
		$i++;
		}
	}

if (filter_var($dump_temp))
	{
	$dump_temp .= "\n";
	}

$dump_temp .= "CREATE TABLE IF NOT EXISTS `".$data_table['Tables_in_'.$database]."` (\n";
$dump_temp .= $create_column."\n";
$dump_temp .= ") ENGINE=".$data_table_option['Engine']." DEFAULT CHARSET=".$character_set_name." COLLATE=".$data_table_option['Collation']." AUTO_INCREMENT=".$data_table_option['Auto_increment'].";\n\n";

Eddig jól állunk, hiszen az adattábláinkat már létre tudjuk hozni. Ez viszont még kevés a teljes sikerhez, hiszen kellenek még a tábláinkban tárolt sorok is. Tehát lekérdezzük azokat is hiánytalanul és elkészítjük az eredményből az "INSERT" utasításokat.

PHP


$select_clone = mysqli_query($GLOBALS['connect'], "SELECT * FROM ".$data_table['Tables_in_'.$database]." ORDER BY ".$id." ASC");
while ($data_clone = mysqli_fetch_assoc($select_clone))
	{
	$i = 0;
	$value = '';
	foreach ($column_array as $column)
		{
		if ($i > 0)
			{
			$value .= ', ';
			}

		if ($type_array[$i] == 'int')
			{
			if ($data_clone[$column] === NULL)
				{
				$value .= 'NULL';
				}
			else
				{
				$value .= $data_clone[$column];
				}
			}
		else
			{
			if ($data_clone[$column] === NULL)
				{
				$value .= 'NULL';
				}
			else
				{
				$value .= "'".str_replace("'", "''", $data_clone[$column])."'";
				}
			}
		$i++;
		}

	$dump_temp .= "INSERT INTO ".$data_table['Tables_in_'.$database]." (".implode(', ', $column_array).") VALUES (".$value.");\n";
	}

Eddig jó, most hogyan tovább?

Remek! Most már a "$dump_temp" változónk tárolja az összes szükséges SQL utasítást, ahhoz hogy a biztonsági mentésünk sikeres legyen. Most már csak azt kell meghatároznunk, hogy milyen formában szeretnénk megkapni az eredményt. Erre több mód is lehetséges. Megkaphatjuk egy "SQL" fájl formájában ".sql" kiterjesztéssel, vagy mindezt a végén "ZIP"-be tömörítve. Ezen felül pedig érdemes azt is eldönteni, hogy a kapott fájlt a tárhelyen szeretnénk tárolni, vagy a saját számítógépünkön. Erre a feladatra szolgál az alábbi kódrészlet.

PHP


if (filter_var($dump_temp))
	{
	folder_open('dump');

	$dumpfname = get_friendly_url($database.'-database-dump-'.date('Y-m-d'), '.sql', 'get');
	file_put_contents(__DIR__.'/dump/'.$dumpfname, $dump_temp, LOCK_EX);

	if ($compression == 1)
		{
		$zipfname = get_friendly_url($database.'-database-dump-'.date('Y-m-d'), '.zip', 'get');

		$zip = new ZipArchive();
		if ($zip->open(__DIR__.'/dump/'.$zipfname,ZIPARCHIVE::CREATE))
			{
			$zip->addFile(__DIR__.'/dump/'.$dumpfname, $dumpfname);
			$zip->close();
			}

		if ($download == 1)
			{
			if (file_exists(__DIR__.'/dump/'.$zipfname))
				{
				header('Content-Description: File Transfer');
				header('Content-Type: application/octet-stream');
				header('Content-Disposition: attachment; filename='.basename($zipfname));
				flush();
				readfile(__DIR__.'/dump/'.$zipfname);
				unlink(__DIR__.'/dump/'.$dumpfname);
				unlink(__DIR__.'/dump/'.$zipfname);
				}
			}
		else
			{
			unlink(__DIR__.'/dump/'.$dumpfname);
			}
		}
	else
		{
		if ($download == 1)
			{
			if (file_exists(__DIR__.'/dump/'.$dumpfname))
				{
				header('Content-Description: File Transfer');
				header('Content-Type: application/octet-stream');
				header('Content-Disposition: attachment; filename='.basename($dumpfname));
				flush();
				readfile(__DIR__.'/dump/'.$dumpfname);
				unlink(__DIR__.'/dump/'.$dumpfname);
				}
			}
		}

	folder_close('dump');
	return TRUE;
	}

Most joggal merülhet fel benned az a kérdés, hogy rendben, de honnan tudom a "$compression" és a "$download" változók értékét? Az imént bemutatott kódrészletek egy nagy függvény kisebb részei voltak. Az "sql_dump" elnevezésű függvény 3 paramétert vár. Az adatbázis nevét, hogy szeretnénk-e tömörítést használni, illetve, hogy hol szeretnénk tárolni a kapott fájlt.

Így néz ki egyben

PHP


<?php
function sql_dump($database, $compression, $download)
	{
	$dump_temp = '';
	$select_table = mysqli_query($GLOBALS['connect'], "SHOW TABLES FROM ".$database);
	while ($data_table = mysqli_fetch_assoc($select_table))
		{
		$select_table_option = mysqli_query($GLOBALS['connect'], "SHOW TABLE STATUS WHERE Name = '".$data_table['Tables_in_'.$database]."'");
		$data_table_option = mysqli_fetch_assoc($select_table_option);

		$id = '';
		$character_set_name = '';
		$create_column = "\t";
		$column_array = array();
		$type_array = array();
		$primary_array = array();
		$unique_array = array();
		$key_array = array();
		$select_column = mysqli_query($GLOBALS['connect'], "SELECT column_name, data_type, column_type, character_set_name, collation_name, extra, column_key, column_default, is_nullable FROM information_schema.columns WHERE table_name = '".$data_table['Tables_in_'.$database]."' ORDER BY ordinal_position ASC");
		while ($data_column = mysqli_fetch_assoc($select_column))
			{
			if (!filter_var($id))
				{
				$id = $data_column['column_name'];
				}
			$column_array[] = $data_column['column_name'];
			$type_array[] = $data_column['data_type'];
			$create_column .= '`'.$data_column['column_name'].'` '.$data_column['column_type'];
			if (!filter_var($character_set_name))
				{
				$character_set_name = $data_column['character_set_name'];
				}
			if (($data_column['data_type'] == 'varchar') || ($data_column['data_type'] == 'text'))
				{
				$create_column .= ' COLLATE '.$data_column['collation_name'];
				}
			if ($data_column['is_nullable'] == 'NO')
				{
				$create_column .= ' NOT NULL';
				}
			elseif (($data_column['is_nullable'] == 'YES') && ($data_column['column_default'] === NULL))
				{
				$create_column .= ' DEFAULT NULL';
				}
			if ($data_column['column_default'] !== NULL)
				{
				$create_column .= ' DEFAULT \''.$data_column['column_default'].'\'';
				}
			if (filter_var($data_column['extra']))
				{
				$create_column .= ' '.strtoupper($data_column['extra']);
				}
			if (filter_var($data_column['column_key']))
				{
				if ($data_column['column_key'] == 'PRI')
					{
					$primary_array[] = $data_column['column_name'];
					}
				elseif ($data_column['column_key'] == 'UNI')
					{
					$unique_array[] = $data_column['column_name'];
					}
				elseif ($data_column['column_key'] == 'MUL')
					{
					$key_array[] = $data_column['column_name'];
					}
				}
			$create_column .= ", \n\t";
			}

		$i = 0;
		if (filter_var_array($primary_array))
			{
			$count = count($primary_array) - 1;
			foreach ($primary_array as $key)
				{
				if ($i > 0)
					{
					$create_column .= ", \n\t";
					}
				$create_column .= 'PRIMARY KEY (`'.$key.'`)';
				$i++;
				}
			}
		if (filter_var_array($unique_array))
			{
			foreach ($unique_array as $key)
				{
				if ($i > 0)
					{
					$create_column .= ", \n\t";
					}
				$create_column .= 'UNIQUE KEY `'.$key.'` (`'.$key.'`)';
				$i++;
				}
			}
		if (filter_var_array($key_array))
			{
			foreach ($key_array as $key)
				{
				if ($i > 0)
					{
					$create_column .= ", \n\t";
					}
				$create_column .= 'KEY `'.$key.'` (`'.$key.'`)';
				$i++;
				}
			}

		if (filter_var($dump_temp))
			{
			$dump_temp .= "\n";
			}

		$dump_temp .= "CREATE TABLE IF NOT EXISTS `".$data_table['Tables_in_'.$database]."` (\n";
		$dump_temp .= $create_column."\n";
		$dump_temp .= ") ENGINE=".$data_table_option['Engine']." DEFAULT CHARSET=".$character_set_name." COLLATE=".$data_table_option['Collation']." AUTO_INCREMENT=".$data_table_option['Auto_increment'].";\n\n";


		$select_clone = mysqli_query($GLOBALS['connect'], "SELECT * FROM ".$data_table['Tables_in_'.$database]." ORDER BY ".$id." ASC");
		while ($data_clone = mysqli_fetch_assoc($select_clone))
			{
			$i = 0;
			$value = '';
			foreach ($column_array as $column)
				{
				if ($i > 0)
					{
					$value .= ', ';
					}

				if ($type_array[$i] == 'int')
					{
					if ($data_clone[$column] === NULL)
						{
						$value .= 'NULL';
						}
					else
						{
						$value .= $data_clone[$column];
						}
					}
				else
					{
					if ($data_clone[$column] === NULL)
						{
						$value .= 'NULL';
						}
					else
						{
						$value .= "'".str_replace("'", "''", $data_clone[$column])."'";
						}
					}
				$i++;
				}

			$dump_temp .= "INSERT INTO ".$data_table['Tables_in_'.$database]." (".implode(', ', $column_array).") VALUES (".$value.");\n";
			}
		}

	if (filter_var($dump_temp))
		{
		folder_open('dump');

		$dumpfname = get_friendly_url($database.'-database-dump-'.date('Y-m-d'), '.sql', 'get');
		file_put_contents(__DIR__.'/dump/'.$dumpfname, $dump_temp, LOCK_EX);

		if ($compression == 1)
			{
			$zipfname = get_friendly_url($database.'-database-dump-'.date('Y-m-d'), '.zip', 'get');

			$zip = new ZipArchive();
			if ($zip->open(__DIR__.'/dump/'.$zipfname,ZIPARCHIVE::CREATE))
				{
				$zip->addFile(__DIR__.'/dump/'.$dumpfname, $dumpfname);
				$zip->close();
				}

			if ($download == 1)
				{
				if (file_exists(__DIR__.'/dump/'.$zipfname))
					{
					header('Content-Description: File Transfer');
					header('Content-Type: application/octet-stream');
					header('Content-Disposition: attachment; filename='.basename($zipfname));
					flush();
					readfile(__DIR__.'/dump/'.$zipfname);
					unlink(__DIR__.'/dump/'.$dumpfname);
					unlink(__DIR__.'/dump/'.$zipfname);
					}
				}
			else
				{
				unlink(__DIR__.'/dump/'.$dumpfname);
				}
			}
		else
			{
			if ($download == 1)
				{
				if (file_exists(__DIR__.'/dump/'.$dumpfname))
					{
					header('Content-Description: File Transfer');
					header('Content-Type: application/octet-stream');
					header('Content-Disposition: attachment; filename='.basename($dumpfname));
					flush();
					readfile(__DIR__.'/dump/'.$dumpfname);
					unlink(__DIR__.'/dump/'.$dumpfname);
					}
				}
			}

		folder_close('dump');
		return TRUE;
		}
	}



sql_dump('adatbazis_neve', 0, 0); //tömörítés nélkül, tárhelyen tárolva
sql_dump('adatbazis_neve', 1, 0); //tömörítéssel, tárhelyen tárolva
sql_dump('adatbazis_neve', 1, 1); //tömörítéssel, saját számítógépen tárolva
?>

Demo letöltése

Leírásaink azon kezdő és haladó programozóknak nyújtanak segítséget, akik már minimális szinten foglalkoztak weboldalkészítéssel. Ha szeretnél jobban elmélyülni a témában, vagy elsajátítani alapokat, még tovább fejlődni, akkor nézz körbe tanfolyam kínálatunkban, ahol a kezdőtől a profi szintig nyújtunk képzéseket a számodra.

Oszd meg barátaiddal is!

Facebook Twitter Linkedin

Elérhetőségeink

  • Címünk: 1139 Budapest, Frangepán utca 3. (1. emelet)

  • Ügyfélfogadás, beiratkozás: Hétfőtől - péntekig: 09:00-17:00

  • Telefonszámunk: 06 70 604 2060, vagy 06 1 4500 110

  • E-mail címünk:

Közösségünk