Зеркальная папка с удаленного сервера на чистом PHP

Я хочу синхронизировать папку на одном компьютере с папкой на другом. Это для плагина развертывания WordPress, поэтому я не могу полагаться на rsync или другие команды, присутствующие на любой машине. PHP и веб-сервер будут доступны на обеих машинах, и в идеале они будут работать через HTTP.

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

Я бы предпочел использовать существующее решение, если оно существует. Есть идеи?

3 ответа

Решение

Я создал простой набор классов для реализации этого: https://github.com/outlandishideas/sync

На сервере, например, example.com/remote.php:

const SECRET = '5ecR3t'; //make this long and complicated
const PATH = '/path/to/source'; //sync all files and folders below this path

$server = new \Outlandish\Sync\Server(SECRET, PATH);
$server->run(); //process the request

На клиенте:

const SECRET = '5ecR3t'; //this must match the secret key on the server
const PATH = '/path/to/destination'; //target for files synced from server

$client = new \Outlandish\Sync\Client(SECRET, PATH);
$client->run('http://example.com/remote.php'); //connect to server and start sync

Лучше всего проверить, когда скрипт запускался в последний раз, а затем загрузить папку с ftp_* функции.

<?php
    $username = 'root'; // and this
    $password = 'password'; // this also
    $host     = 'my-remote-server.com'; // and this

    $remote_backup = 'backups/'; // folder on remote server to upload to
    $backup_folder = 'to_backup/'; // folder to backup
    $temp_folder   = 'temp_files/'; // a folder on the local server i can write to

    $last_run = file_get_contents("{$temp_folder}last_run.txt"); // You'll probably want to get this from a database instead

    if($last_run <= strtotime('-1 day'))
    {
        file_put_contents("{$temp_folder}last_run.txt", time()); // Update the last time this was ran

        $file = time() . '_backup.zip'; // what the file will be called both remotely and locally
        $ftp = ftp_connect($host); // connect to the ftp server
        ftp_login($ftp, $username, $password); // login to the ftp server

        $zip = new ZipArchive; // create a new instance of ZipArchive
        $zip->open($temp_folder . $file, ZIPARCHIVE::CREATE); // Create a new archive

        foreach(glob($backup_folder . '*') as $file) // Loop through all files in the local backup directory
        {
            $zip->addFile($file); // add that file
        }

        ftp_chdir($ftp, $remote_backup); // cd into the remote backup folder
        $upload = ftp_nb_put($ftp, $remote_backup . $file, $temp_folder . $file); // non-blocking put, uploads the local backup onto the remote server

        while($upload === FTP_MOREDATA)
        {
            // do something else while we're waiting for the non-blocking upload to finish
        }

        ftp_close($ftp); // closes the connection
    }

Он должен быть неблокирующим (хорошо - загрузка на удаленный сервер), поэтому, если у вас не так много файлов для архивации, будет неплохо включить их в index page например. Обработки ошибок нет, поэтому вы можете добавить ее в. Она также не удаляет локальную резервную копию, вы можете ее обработать.

В PHP я бы не рекомендовал это по нескольким причинам.

У меня есть именно то, что вам нужно в качестве приложения Python.

Это приложение создано для запуска в качестве сервиса, вы просто запускаете его и забываете об этом:)

Приложение: https://gist.github.com/8f62786582c6933395eb

Оболочка: https://gist.github.com/e08a99937c6f5deac4ab

Примечание: файл оболочки должен называться fsyncd, а не fsyncd.sh:)

Версия PHP выше:

https://gist.github.com/3963cbc58793ff7e9773

Примечание. Необходимо запустить его на обоих сайтах, настроить каждый из них для подключения к другому и настроить их на выполнение crons. Желательно не по WP кронам.

У меня есть путь к каталогу, который будет синхронизирован, определен здесь:

define("PATH_DATA", PATH_ROOT . "data" . DIRECTORY_SEPARATOR);

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

Основным является:

  1. найдите способ получить два сервера, способных общаться друг с другом. Я использовал подход сокет-сервер / клиент. Вы могли бы сделать процессор HTTP _POST (сервер) и создатель HTTP _POST (клиент).

  2. Ведите запись времени последней синхронизации.

  3. Через определенные промежутки времени читайте папку и записывайте любые файлы, измененные с момента последней синхронизации.

  4. Отправьте список файлов, которые будут обновлены с их измененной отметкой времени, на другой сервер.

  5. Он должен сравнить ваш список с его записями и сказать, какие файлы у него отсутствуют.

  6. Отправь эти файлы.

  7. Получатель запишет файлы и установит дату изменения для даты на другом сервере. (это важно, чтобы избежать бесконечных циклов)

Удачи.

Другие вопросы по тегам