<MyRusakov.ru />

Разработчик игр на Unreal Engine

Разработчик игр на Unreal Engine

Этот комплект с нуля всего за 7 месяцев сделает Вас Unreal-разработчиком. И при этом учиться достаточно 1 час в день.

Начнёте Вы с основ программирования, постепенно перейдя к C++. Затем очень подробно изучите Unreal Engine, и после научитесь программировать на C++ в Unreal Engine. В конце создадите крупный проект на C++ в Unreal Engine для своего портфолио.

Комплект содержит:

- 416 видеоуроков

- 95 часов видео

- 1024 задания для закрепления материала из уроков

- 3 финальных тестирования

- 4 сертификата

- 12 Бонусных курсов

Подробнее
Подписка

Подпишитесь на мой канал на YouTube, где я регулярно публикую новые видео.

YouTube Подписаться

Подписавшись по E-mail, Вы будете получать уведомления о новых статьях.

Подписка Подписаться

Добавляйтесь ко мне в друзья ВКонтакте! Отзывы о сайте и обо мне оставляйте в моей группе.

Мой аккаунт Мой аккаунт Моя группа
Опрос

Какая тема Вас интересует больше?

Автоматическое резервное копирование на PHP

Автоматическое резервное копирование на PHP

Резервное копирование - вещь крайне важная, которую нужно делать ежедневно, если не чаще. Не буду объяснять, зачем это нужно, это должно быть и так понятно. Вопрос только в том, как этот процесс автоматизировать, чтобы каждый день не тратить на это время. В итоге, я начал искать скрипт автоматического резервного копирования на PHP. Но, увы, ничего хорошего не попалось. Попадались только огромные программы с 1000 кнопками.

А ведь какие задачи у резервного копирования? Просто сохранять в архив все файлы и папки сайта, а также делать дамп базы данных, которые так же добавить в архив. Для создания такой функциональности 1000 кнопок не потребуется, поэтому я решил написать свой скрипт автоматического резервного копирования на PHP. Полный код данного скрипта приведён ниже:

<?php
  set_time_limit(0); // Убираем ограничение на максимальное время работы скрипта
  /* Массив с именами баз данных (имя базы данных можно посмотреть в phpMyAdmin) */
  $db_names = array();
  $db_names[] = "db1";
  $db_names[] = "db2";
 
  /* Массив с именами директорий, в которых лежат все файлы сайта */
  /* ВАЖНО: Все пути должны быть физическими и идти от корня сервера. Точный физический путь можно посмотреть через phpinfo() */
  $source_dirs = array();
  $source_dirs[] = "/home/mysite1.ru";
  $source_dirs[] = "/home/mysite2.ru";
 
  $offset_dirs = strlen("/home/"); // Служебная переменная, служащая для устранения лишних папок в архиве
 
  /* Параметры подключения к базе данных */
  $host = "localhost";
  $user = "root";
  $password = "";
 
  $dump_dir = "/home/backup"; // Директория, куда будут помещаться архивы
  $delay_delete = 35 * 24 * 3600; // Время в секундах, через которое архивы будут удаляться
  $filezip = "backup_".date("Y-m-d").".zip"; // Имя архива
 
  deleteOldArchive(); // Удаляем все старые архивы
 
  if (file_exists($dump_dir."/".$filezip)) exit; // Если архив с таким именем уже есть, то заканчиваем скрипт
 
  $db_files = array(); // Массив, куда будут помещаться файлы с дампом баз данных
 
  for ($i = 0; $i < count($db_names); $i++) {
    $filename = $db_names[$i].".sql"; // Имя файла с дампом базы данных
    $db_files[] = $dump_dir."/".$filename; // Помещаем файл в массив
    $fp = fopen($dump_dir."/".$filename, "a"); // Открываем файл
    $db = new mysqli($host, $user, $password, $db_names[$i]); // Соединяемся с базой данных
    $db->query("SET NAMES 'utf-8'"); // Устанавливаем кодировку соединения
    $result_set = $db->query("SHOW TABLES"); // Запрашиваем все таблицы из базы
    while (($table = $result_set->fetch_assoc()) != false) {
      /* Перебор всех таблиц в базе данных */
      $table = array_values($table);
      if ($fp) {
        $result_set_table = $db->query("SHOW CREATE TABLE `".$table[0]."`"); // Получаем запрос на создание таблицы
        $query = $result_set_table->fetch_assoc();
        $query = array_values($query);
        fwrite($fp, "\n".$query[1].";\n"); // Добавляем результат в файл
        $rows = "SELECT * FROM `".$table[0]."`";
        $result_set_rows = $db->query($rows); // Получаем список всех записей в таблице
        while (($row = $result_set_rows->fetch_assoc()) != false) {
          $query = "";
          /* Путём перебора всех записей добавляем запросы на их создание в файл */
          foreach ($row as $field) {
            if (is_null($field)) $field = "NULL";
            else $field = "'".$db->real_escape_string($field)."'"; // Экранируем значения
            if ($query == "") $query = $field;
            else $query .= ", ".$field;
          }
          $query = "INSERT INTO `".$table[0]."` VALUES (".$query.");";
          fwrite($fp, $query);
        }
      }
    }
    fclose($fp); // Закрываем файл
    $db->close(); // Закрываем соединение с базой данных и переходим к следующей
  }
 
  $zip = new ZipArchive(); // Создаём объект класса ZipArchive
  $allfiles = array(); // Массив со списком всех файлов, которые будут помещены в архив
  if ($zip->open($dump_dir."/".$filezip, ZipArchive::CREATE) === true) {
    for ($i = 0; $i < count($source_dirs); $i++) {
      /* Рекурсивный перебор всех директорий */
      if (is_dir($source_dirs[$i])) recoursiveDir($source_dirs[$i]);
      else $allfiles[] = $source_dirs[$i]; // Добавляем файл в итоговый массив
      foreach ($allfiles as $val){
        /* Добавляем в ZIP-архив все полученные файлы */
        $local = substr($val, $offset_dirs);
        $zip->addFile($val, $local);
      }
    }
    /* Добавляем в ZIP-архив все дампы баз данных */
    for ($i = 0; $i < count($db_files); $i++) {
      $local = substr($db_files[$i], strlen($dump_dir) + 1);
      $zip->addFile($db_files[$i], $local);
    }
    $zip->close();
  }
 
  for ($i = 0; $i < count($db_files); $i++) unlink($db_files[$i]); // Очищаем массив db_files
 
  /* Функция для рекурсивного перебора и сохранения всех файлов и папок в массив, который затем возвращается */
  function recoursiveDir($dir){
    global $allfiles;
    if ($files = glob($dir."/{,.}*", GLOB_BRACE)) {
      foreach($files as $file){
        $b_name = basename($file);
        if (($b_name == ".") || ($b_name == "..")) continue;
        if (is_dir($file)) recoursiveDir($file);
        else $allfiles[] = $file;
      }
    }
  }
 
  /* Функция для удаления всех старых архивов */
  function deleteOldArchive() {
    global $dump_dir;
    global $delay_delete;
    $ts = time();
    $files = glob($dump_dir."/*.zip");
    foreach ($files as $file)
      if ($ts - filemtime($file) > $delay_delete) unlink($file);
  }
?>

Именно этим скриптом пользуюсь я сам. Дальше, всё, что Вам нужно - это поставить его в cron, например, раз в сутки в 2 часа ночи. Тогда если что-то с Вашим сайтом случится, архив всегда можно будет выкачать с сервера и восстановить сайт из бэкапа.

Копирование материалов разрешается только с указанием автора (Михаил Русаков) и индексируемой прямой ссылкой на сайт (http://myrusakov.ru)!

Добавляйтесь ко мне в друзья ВКонтакте: http://vk.com/myrusakov.
Если Вы хотите дать оценку мне и моей работе, то напишите её в моей группе: http://vk.com/rusakovmy.

Если Вы не хотите пропустить новые материалы на сайте,
то Вы можете подписаться на обновления: Подписаться на обновления

Если у Вас остались какие-либо вопросы, либо у Вас есть желание высказаться по поводу этой статьи, то Вы можете оставить свой комментарий внизу страницы.

Порекомендуйте эту статью друзьям:

Если Вам понравился сайт, то разместите ссылку на него (у себя на сайте, на форуме, в контакте):

  1. Кнопка:

    Она выглядит вот так: Как создать свой сайт

  2. Текстовая ссылка:

    Она выглядит вот так: Как создать свой сайт

  3. BB-код ссылки для форумов (например, можете поставить её в подписи):

Комментарии (20):

lev_100rus lev_100rus 31.10.2013 01:14:14

Нехилый скрипт. Молодец, Михаил!

Ответить

owmen owmen 23.12.2013 18:27:25

Здравствуйте, Михаил. Чудесная работа, вот только есть вопрос. Скажите пожалуйста, в данном скрипте Вы создаете объекты классов, следовательно должны быть и сами классы, но в коде их нет. Их нужно дописывать самому? Если да, то это не совсем соответствует Вашей фразе - "Полный код данного скрипта приведён ниже:"...

Ответить

(Алекс) (Алекс) 08.06.2015 17:28:08

класс ZipArchive входит в состав языка PHP

Ответить

saint_byte saint_byte 27.08.2014 23:20:53

Если есть доступ к крону - не проше использовать mysqldump zip - команда 3 строки

Ответить

pelzar pelzar 29.10.2014 13:03:08

Михаил, Большое спасибо за скрипт. Очень пригодился. А можно как нибудь исключить архивирование одной папки? У меня есть папка images, которая весит несколько гигов, и которую бекапить нет необходимости. Заранее спасибо за ответ.

Ответить

yarkov_aleksei yarkov_aleksei 22.12.2014 16:54:07

Переписал ваш скрипт в класс. Так гораздо удобнее мне кажется. Код здесь: http://pastebin.com/K0S3UzFB И добавил возможность указывать файлы и папки, которые не нужно включать в архив.

Ответить

drew-ip drew-ip 19.01.2016 17:29:56

Попробовал ваш скрипт, в отличии от того что на сайте- ругнулся только на "PHP Fatal error: Class 'ZipArchive' not found in", подскажите, как сделать что бы не зип, а tar.gz, вроде с этим работает

Ответить

yarkov_aleksei yarkov_aleksei 19.01.2016 17:34:34

У вас расширение для работы с архивами не установлено на сервере.

Ответить

drew-ip drew-ip 19.01.2016 17:37:39

Да я не спорю, но я то там не установлю сам, а хостер не особо хороший, а можно сделать как то, что бы бэкап складывался в папку, но не архивировался, а я потом буду забирать с компьютера и уже на компе будет архивировать? Хотя вот в панеле управления в файловом менеджере я могу запаковать и в зип и в тар

Ответить

yarkov_aleksei yarkov_aleksei 19.01.2016 17:47:21

Можно. Попозже помогу

Ответить

drew-ip drew-ip 19.01.2016 17:49:44

Спасибо большое, даже, если облегчит- мне нужно забирать только базы данных с сервера, файлы я и так забираю кобианом по расписанию, а вот базы данных никак не выходит

Ответить

drew-ip drew-ip 19.01.2016 18:36:42

Вообщем то с зипом я разобрался, оказывается его можно было включить в панель управления, ошибка с ним ушла, но вышла ошибки, которые сыпали и оригинальный скрипт, и куда копать ума совсем не приложу: PHP Warning: fopen(/backups/USER_444.sql): failed to open stream: No such file or directory in /home/USER/domains/DOMEN.RU/public_html/cron.php on line 107 PHP Warning: fclose() expects parameter 1 to be resource, boolean given in /home/USER/domains/DOMEN.RU/public_html/cron.php on line 135 PHP Notice: ZipArchive::addFile(): Empty string as filename in /home/USER/domains/DOMEN.RU/public_html/cron.php on line 61 PHP Warning: unlink(/backups/USER_444.sql): No such file or directory in /home/USER/domains/DOMEN.RU/public_html/cron.php on line 68

Ответить

yarkov_aleksei yarkov_aleksei 19.01.2016 21:52:59

Ну а файл такой есть? /backups/USER_444.sql И что за крон у вас странный?

Ответить

drew-ip drew-ip 20.01.2016 03:48:23

Нет, такого файла нет. А чем, простите, странен крон? Это он мне на почту присылает в таком виде отчёт. Вообще непонятно, то ли скрипт не может достучаться до sql базы, то ли не может её скопировать в папку backups... Как вот этот момент проверить

Ответить

garfild304 garfild304 13.04.2018 14:14:35

привет глянул код...а куда вписывать исключения что бы не бэкапил?

Ответить

yarkov_aleksei yarkov_aleksei 13.04.2018 19:37:56

Серьезно? Сколько лет прошло уже ))) Я РНР как страшный сон забыл и на Node.js переехал ))

Ответить

www3 www3 07.11.2016 10:43:39

Михаил, подскажите пожалуйста - как исключить из создаваемого скриптом архива одну или несколько папок? Метод с "Служебная переменная, служащая для устранения лишних папок в архиве" НЕ РАБОТАЕТ. Указывал и просто название папки, и её физический путь - ничего не получается.

Ответить

aldo26 aldo26 11.11.2016 23:28:00

Михаил, для новичка обьясните, как поставить скрипт в cron. никогда с cron не работал.

Ответить

ovpmusic ovpmusic 18.01.2017 22:16:34

Михаил, подскажите, пожалуйста, можно ли изменять степень сжатия архива? Просто мне попался скрипт и я попробовал создать архив сайта им и в итоге архив получился на 30 Мб меньше по размеру, по сравнению с тем архивом, который был создан с использованием вашего скрипта. Хотя мне ваш скрипт нравится больше. Он меньше и по содержанию и по размеру, да и работает шустрее. Спасибо.

Ответить

alex alex alex alex 30.08.2023 18:25:17

я взял тоже, пригодится на будущее..спасибо

Ответить

Для добавления комментариев надо войти в систему.
Если Вы ещё не зарегистрированы на сайте, то сначала зарегистрируйтесь.