Автоматичне копіювання бази даних MySQL на PHP

437

Від автора: база даних є сховищем найважливішої інформації практично будь-якого хорошого сайту, тому ще на етапі розробки сайту необхідно вирішити, як виконувати резервне копіювання інформації, яка зберігається в базі даних. Так як не виконуючи цю операцію, одного разу можна втратити весь контент сайту, і це може статися зовсім не з Вашої вини, а, приміром, з технічних причин на сервері. Тому в даному уроці ми з Вами розглянемо створення невеликого скрипта, який буде виконувати автоматичне копіювання вмісту Вашої бази даних.

Автоматичне копіювання бази даних MySQL на PHPАвтоматичне копіювання бази даних MySQL на PHP

Налаштування для роботи скрипта

Отже, у нас є порожній файл index.php на локальному комп’ютері – і це буде основний файл майбутнього сценарію. Насамперед, давайте створимо файл config.php для зберігання налаштувань, з ось таким вмістом:

Налаштуваннями будуть служити звичайні константи PHP, і це чотири налаштування для підключення до бази даних (шлях до сервера, ім’я користувача, пароль для користувача, ім’я бази даних). Далі, створюємо константу для зберігання шляху до папки, в яку будуть зберігатися резервні копії. А також створимо ще одну допоміжну налаштування, в якій збережемо кількість записів, які одночасно будуть записуватися в текстовий файл. Після цього давайте підключимо даний файл index.php:

header(“Content-Type:text/html;charset=UTF-8”);

Підключення до бази даних

В цьому файлі будуть зібрані всі необхідні функції по створенню скрипта автоматичного копіювання вмісту бази даних. Тому створимо файл і додамо в нього першу функцію:

function connect_db() {
$db = mysqli_connect(HOST,USER,PASSWORD,DB);
if(mysqli_connect_error($db)) {
exit(‘NO connection’);
}
return $db;
}

Як Ви бачите, дана функція забезпечує підключення до бази даних, використовуючи параметри конфігураційного файлу, і повертає дискриптор відкритого з’єднання (змінна $db). Відразу хочу відзначити, що для роботи з базою даних ми будемо використовувати розширення мови PHP mysqli, так як розширення mysql вже істотно застаріло. Тепер цей файл необхідно підключити у файлі index.php і викликати на виконання функцію connect_db():

include “functions.php”;
$db = connect_db();

Отримання списку таблиць бази даних

Перед тим як почати писати логіку роботи скрипта, давайте подивимося на фрагмент дампу бази даних, створеного скриптом phpMyAdmin. Нагадаю, для того, що б створити резервну копію бази даних, за допомогою phpMyAdmin, необхідно вибрати потрібну базу даних і клацнути по вкладці Експорт (Export):

Автоматичне копіювання бази даних MySQL на PHP

Далі якщо вибрати швидкий спосіб експорту – буде створений текстовий файл з розширенням sql, приблизно ось такого змісту (подивимося тільки фрагмент):

— phpMyAdmin SQL Dump
— version 3.5.1
— http://www.phpmyadmin.net

— Хост: 127.0.0.1
Час створення: 26 Окт 2013, 22:47
— Версія сервера: 5.5.25
— Версія PHP: 5.3.13
SET SQL_MODE=”NO_AUTO_VALUE_ON_ZERO”;
SET time_zone = “+00:00”;
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;

— База даних: `my_bd`

— ——————————————————–

— Структура таблиці `category`

CREATE TABLE IF NOT EXISTS `category` (
`id_category` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name_category` varchar(255) NOT NULL,
PRIMARY KEY (`id_category`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=58 ;

— Дамп даних таблиці `category`

INSERT INTO `category` (`id_category`, `name_category`) VALUES
(1, ‘Opel’),
(2, ‘Mazda’),
(3, ‘Ford’),
(5, ‘Fiat’),
(56, ‘fsdfsdfsdf’),
(57, ‘fsdfsdfsdf’);
— ——————————————————–

Тобто, як Ви бачите, цей фал містить набір SQL запитів, для відновлення цілісності інформації бази даних. А саме: створення необхідних таблиць, наповнення їх даними. Тому наш скрипт повинен створювати аналогічний файл. Тепер, нам необхідно дізнатися, які таблиці містяться у вибраній базі даних. Для цього створимо функцію get_tables() у файлі functions.php:

function get_tables($db) {
$sql = “SHOW TABLES”;
$result = mysqli_query($db,$sql);
if(!$result) {
exit(mysqli_error($db);
}
$tables = array();
for($i = 0; $i < mysqli_num_rows($result); $i++) {
$row = mysqli_fetch_row($result);
$tables[] = $row[0];
}
return $tables;
}

Дана функція приймає параметром дискриптор відкритого з’єднання з базою даних. І виконує простий SQL запит (SHOW TABLES), тим самим, отримуючи список всіх таблиць вибраної бази даних. Далі в циклі проходимо по результуючій таблиці ($result) і формуємо масив $tables – масив, у кожній клітинці якого, містяться назви таблиць. Тепер у файлі index.php викличемо на виконання тільки що створену функцію get_tables():

$tables = get_tables($db);

І подивимося в браузері, що у нас вийшло (при цьому роздрукуємо масив $tables за допомогою функції print_r()):

Автоматичне копіювання бази даних MySQL на PHP

Як Ви бачите, ми з Вами отримали масив всіх таблиць, що містяться у вибраній базі даних. Тепер для кожної з цих таблиць, необхідно створити SQL запити, які будуть їх створювати та заповнювати вмістом.

Функція створення дампу бази даних

Отже, приступаємо до безпосереднього створення дампу бази даних. Для цього створюємо у файлі functions.php функцію get_dump():

function get_dump($db,$tables) {
}

Зверніть увагу – функція приймає два параметри – дискриптор відкритого з’єднання з базою даних і масив таблиць, що зберігаються в базі даних. Так як дамп бази даних це звичайний текстовий файл, тому давайте створимо такий файл і відкриємо його для запису за допомогою функції fopen() і запишемо в нього кілька рядків:

$fp = fopen(DIR_SQL.time().”_dump.sql”,”w”);
$text = “– SQL Dump
— my_ version: 1.234

— База даних: `”.DB.”`

— —————————————————
— —————————————————
“;
fwrite($fp,$text);

Режим роботи функції fopen() вибираємо w, тобто режим, при якому функція відкриває файл тільки для запису, поміщає вказівник на початок файлу і обрізає файл нульової довжини. Якщо файл не існує — пробує його створити. Ім’я файлу формуємо наступним чином: DIR_SQL.time().»_dump.sql», тобто вказуємо папку, де будуть складатися дампи бази даних, потім отримуємо поточну мітку часу, використовуючи функцію time() і додаємо суфікс _dump. Ну і не забуваємо про розширення .sql.

Далі створимо змінну $text, яка буде використовуватися нами для зберігання тимчасових фрагментів майбутнього SQL запиту. І запишемо у файл перші кілька рядків. Це будуть коментарі (нагадаю, що коментарі на мові SQL позначаються —), що включають в себе різну довільну інформацію – на Ваш розсуд. Я додав назва, номер версії скрипта та ім’я бази даних, резервну копію якої ми створюємо. Тепер необхідно в циклі пройтися по масиву $tables та для кожної таблиці створити необхідні SQL запити, з її створення і відновлення даних:

foreach($tables as $item) {
}

І подальше кодування ведемо в циклі. Для початку, збережемо в файлі ще кілька рядків, що відокремлюють одну таблицю від іншої і вказують на назву таблиці.

$text =”

— Структура таблиці – “.$item.”

“;
fwrite($fp,$text);

Як Ви бачите – це знову ж коментарі. Тепер нам необхідно створити запит щодо створення поточної таблиці, але перед цим давайте додамо спочатку запит, щодо видалення цієї ж таблиці, якщо вона вже існує, а вже потім будемо її створювати:

$text = “”;
$text= “DROP TABLE IF EXISTS `”.$item.”`;”;

Тобто, обнуляем змінну $text і додаємо в неї рядок із запитом з видалення таблиці. Назва поточної таблиці міститься у змінній $item. Хочу підкреслити, що в кінці рядка з запитом, необхідно поставити крапку з комою.

Далі, нам потрібно створити таблицю, але як же дізнатися всі параметри поточної таблиці (кількість полів, атрибути, типи даних полів тощо)? Для цього необхідно виконати ще один простий SQL запит:

$sql = “SHOW CREATE TABLE “.$item;
$result = mysqli_query($db, $sql);
if(!$result) {
exit(mysqli_error($db);
}
$row = mysqli_fetch_row($result);

Даний запит поверне нам рядок, в якій буде міститися SQL запит щодо створення вибраної таблиці, що включає в себе всі необхідні параметри та атрибути. Його ми збережемо у змінній $row. Далі додамо значення даної змінної до змінної $text і запишемо у файл:

$text= “\n”.$row[1].”;”;
fwrite($fp,$text);
$text = “”;

Тепер давайте додамо черговий роздільник в файл (коментар), що вказує на те, що далі йде блок зі вставкою даних у таблицю:

$text=


— Dump BD – tables :”.$item.”

“;

Далі необхідно створити SQL запит вставлення даних у базу даних. Так як нам необхідно заповнити всі поля таблиці, ми використовуємо наступний синтаксис, даного запиту:

INSERT INTO `category` VALUES (“1”, “Opel”),(id,opel);

Тому додаємо частину даного запиту в змінну $text і записуємо в файл:

$text= “\nINSERT INTO `”.$item.”` VALUES”;
fwrite($fp,$text);

Тепер нам потрібно отримати дані таблиць і закінчити даний запит. Для цього виконуємо стандартний SQL запит:

$sql2 = “SELECT * FROM “.$item.”`”;
$result2 = mysqli_query($db,$sql2);
if(!$result2) {
exit(mysqli_error($db);
}
$text = “”;

Далі необхідно в циклі отримати дані з результуючої таблиці і додати в запит, який надалі і запишеться у файл. Тому додаємо наступний код:

for($i = 0; $i FOR_WRITE) {
fwrite($fp,$text);
$text = “”;
}
}

Отже, для початку, в змінну $row отримуємо масив даних по кожній окремій запису в таблиці. Потім в залежності від того на якій ітерації ми зараз знаходимося, в змінну $text додаємо чи « («або «,(«. Так як відповідно до SQL запитом типу INSERT дані необхідно передавати в круглих дужках і розділяти їх комою. Тому якщо поточна ітерація – перша – ми відкриваємо круглу дужку, а при наступних ітераціях, відкриває перед круглою дужкою необхідно вказувати кому.

Далі формуємо цикл foreach, в якому проходимо по масиву $row і додаємо дані в змінну $text, розділяючи їх комою. Після циклу опрацюємо змінну $text, функція rtrim(), тобто видалити зайву кому в кінці значення змінної $text. Далі додаємо в цю змінну закриває круглу дужку.

Потім якщо кількість ітерацій перевищило значення зберігаються в константі FOR_WRITE – виконаємо запис змінної текст в файл. І відразу ж очищаємо змінну $text. Далі додамо наступний код:

$text= “;\n”;
fwrite($fp,$text);

Тобто, додаємо символ крапки з комою, як закінчення SQL запиту і робимо запис значення змінної $text в файл. І в кінці не забуваємо закрити файл:

fclose($fp);

Тепер давайте наведу повний код функції get_dump():

function get_dump($db,$tables) {
if(is_array($tables)) {
$fp = fopen(DIR_SQL.time().”_dump.sql”,”w”);
$text = “– SQL Dump
— my_ version: 1.234

— База даних: `”.DB.”`

— —————————————————
— —————————————————
“;
fwrite($fp,$text);
foreach($tables as $item) {
$text =”

— Структура таблиці – “.$item.”

“;
fwrite($fp,$text);
$text = “”;
$text= “DROP TABLE IF EXISTS `”.$item.”`;”;
$sql = “SHOW CREATE TABLE “.$item;
$result = mysqli_query($db, $sql);
if(!$result) {
exit(mysqli_error($db);
}
$row = mysqli_fetch_row($result);
$text= “\n”.$row[1].”;”;
fwrite($fp,$text);
$text = “”;
$text=


— Dump BD – tables :”.$item.”

“;
$text= “\nINSERT INTO `”.$item.”` VALUES”;
fwrite($fp,$text);
$sql2 = “SELECT * FROM “.$item.”`”;
$result2 = mysqli_query($db,$sql2);
if(!$result2) {
exit(mysqli_error($db);
}
$text = “”;
for($i = 0; $i FOR_WRITE) {
fwrite($fp,$text);
$text = “”;
}
}
$text= “;\n”;
fwrite($fp,$text);
}
fclose($fp);
}
}

Ось ми з Вами і закінчили скрипт автоматичного резервного копіювання інформації з бази даних. Звичайно, його ще можна допрацьовувати, але думаю, для Вас це вже не складе праці. Так як принцип створення дампу бази даних засобами PHP, ми з Вами розглянули в даній уроці.

Всього Вам доброго і вдалого кодування! І побачимося в наступних уроках!