Резервное копирование веб-сайта в PHP?

Кто-нибудь знает чистое PHP-решение, которое может резервировать удаленные веб-сайты с помощью FTP?

Должен иметь:

  • Рекурсивные резервные копии FTP
  • Возможно выполнение задания cron
  • Простота настройки (простое добавление нескольких сайтов)
  • Локальное хранилище резервных файлов достаточно

Было бы неплохо:

  • Резервные сайты хранятся в виде zip файлов
  • Хороший интерфейс для управления вещами
  • Предоставляет уведомление о завершении или неудаче резервного копирования
  • Поддерживает ли инкрементное резервное копирование
  • Резервное копирование базы данных MySQL

Мне нужно, чтобы это было основано на PHP, потому что оно будет использоваться в пакетах хостинга, которые не позволяют использовать стандартные инструменты GNU/Linux.

Ответы

Ответ 1

Я сделал что-то подобное в работе cron PHP script раньше. Не уверен, что это лучший способ, но он, безусловно, работает.

$backup_file = '/home/example/sql_backup/mo_'.date('Y-m-d').'.sql.gz';
$command = '/usr/bin/mysqldump -c -h'.DB_HOST.' -u'.DB_USER.' -p'.DB_PASS.' --default-character-set=latin1 -N '.DB_NAME.' | gzip > '.$backup_file;
exec($command);

Затем вы можете выполнить sftp на удаленном сервере.

Аналогичным образом вы можете делать файлы с помощью exec() и linux zipping.

Ответ 2

Я закодировал это для обработки резервных копий FTP, не уверен, соответствует ли он вашим конкретным потребностям tho:

class Backup
{
    public $ftp = null;
    public $files = array();

    public function FTP($host, $user = null, $pass = null, $port = 21, $path = '/')
    {
        if ((extension_loaded('ftp') === true) && (extension_loaded('zip') === true))
        {
            $this->ftp = ftp_connect($host, $port, 5);

            if (is_resource($this->ftp) === true)
            {
                if (ftp_login($this->ftp, $user, $pass) === true)
                {
                    $zip = new ZipArchive();

                    if (is_object($zip) === true)
                    {
                        ftp_pasv($this->ftp, true);

                        if ($zip->open(sprintf('./%s_%s.zip', $host, date('YmdHis', time())), ZIPARCHIVE::CREATE) === true)
                        {
                            $this->FTP_Map($path);

                            while (($file = array_shift($this->files)) !== null)
                            {
                                if (preg_match('~/$~', $file) > 0)
                                {
                                    $zip->addEmptyDir(preg_replace('~^[\\/]+~', '', $file));
                                }

                                else
                                {
                                    $stream = tempnam(sys_get_temp_dir(), __CLASS__);

                                    if (is_file($stream) === true)
                                    {
                                        if (ftp_get($this->ftp, $stream, $file, FTP_BINARY, 0) === true)
                                        {
                                            $zip->addFromString(preg_replace('~^[\\/]+~', '', $file), file_get_contents($stream));
                                        }

                                        unlink($stream);
                                    }
                                }
                            }
                        }

                        $zip->close();
                    }
                }

                ftp_close($this->ftp);
            }
        }

        return false;
    }

    public function FTP_Map($path = '/')
    {
        if (is_resource($this->ftp) === true)
        {
            $files = ftp_nlist($this->ftp, ltrim($path, '/'));

            if (is_array($files) === true)
            {
                foreach ($files as $file)
                {
                    if (@ftp_chdir($this->ftp, $file) !== true)
                    {
                        $this->files[] = sprintf('/%s/%s', trim($path, '\\/'), trim($file, '\\/'));
                    }

                    else if (ftp_cdup($this->ftp) === true)
                    {
                        if (array_push($this->files, sprintf('/%s/%s/', trim($path, '\\/'), trim($file, '\\/'))) > 0)
                        {
                            $this->FTP_Map(sprintf('/%s/%s/', trim($path, '\\/'), trim($file, '\\/')));
                        }
                    }
                }

                return true;
            }
        }

        return false;
    }
}

Использование:

$Backup = new Backup();

$Backup->FTP('demo.wftpserver.com', 'demo-user', 'demo-user', 21, '/text/');

Для резервных копий MySQL, выполнил бы SELECT INTO OUTFILE?

Ответ 3

Я на самом деле написал статью с включенными сценариями о том, как я это сделал, используя PHP, Bash и некоторые другие части программного обеспечения с открытым исходным кодом для отправки предварительно отформатированных уведомлений по электронной почте о резервных копиях.

http://codeuniversity.com/scripts/scr1

Мои требования были довольно похожи, хотя FTP не задействован. Все это делается на местном уровне. Посмотрите. Возможно, вам будет удобно.

Ответ 4

Im использует myRepono, в дополнение к тому, что вы упомянули, если выполняет быстрые и автоматические резервные копии и очень стабильно и безопасно.

Ответ 5

Хотя ваш общий хостинг может не предоставлять много инструментов, он должен предоставить хотя бы некоторые из них, возможно, стоит спросить у вашего хоста, что они предоставляют или рекомендуют для резервного копирования. Вы хотите создать резервную копию для практически идентичного хоста. (по крайней мере, с точки зрения программного обеспечения)

Чтобы запустить rsync успешно, он должен быть запущен только на одном компьютере, другой не должен даже знать, что существует rysnc, также не имеет значения, какая из них работает (резервная копия или первичный хост).

У вас есть доступ к серверу для установки пакетов или модулей php? Если вы этого не сделаете, все ставки будут отключены, так как вероятность того, что ваша установка php не будет включать какие-либо необходимые пакеты, чтобы начать думать об попытке этого с php.

Я бы рекомендовал не php-решение, например rysnc или bash script. Хотя вы можете обернуть процесс в php-обертку, чтобы управлять им.