Зеркальная папка с удаленного сервера на чистом 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.
Основным является:
найдите способ получить два сервера, способных общаться друг с другом. Я использовал подход сокет-сервер / клиент. Вы могли бы сделать процессор HTTP _POST (сервер) и создатель HTTP _POST (клиент).
Ведите запись времени последней синхронизации.
Через определенные промежутки времени читайте папку и записывайте любые файлы, измененные с момента последней синхронизации.
Отправьте список файлов, которые будут обновлены с их измененной отметкой времени, на другой сервер.
Он должен сравнить ваш список с его записями и сказать, какие файлы у него отсутствуют.
Отправь эти файлы.
Получатель запишет файлы и установит дату изменения для даты на другом сервере. (это важно, чтобы избежать бесконечных циклов)
Удачи.