PHPackages                             jakubboucek/psync - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [DevOps &amp; Deployment](/categories/devops)
4. /
5. jakubboucek/psync

ActiveLibrary[DevOps &amp; Deployment](/categories/devops)

jakubboucek/psync
=================

A tool for automated deploy/download of PHP applications source code between local PC and dummy webhosting.

02↑2900%PHP

Since Jun 13Pushed todayCompare

[ Source](https://github.com/jakubboucek/psync)[ Packagist](https://packagist.org/packages/jakubboucek/psync)[ RSS](/packages/jakubboucek-psync/feed)WikiDiscussions master Synced today

READMEChangelogDependenciesVersions (1)Used By (0)

PHP sync (rsync for PHP) tool for dummy webhostings
===================================================

[](#php-sync-rsync-for-php-tool-for-dummy-webhostings)

*A tool for automated deploy/download of PHP applications source code between local PC and dummy webhosting.*

There is nothing worse than babysitting a PHP application on a hosting that, in this day and age, still speaks nothing but FTP. No SSH, no rsync, no Git deploy — just a lonely FTP port and your patience. You drag files in Total Commander, never quite sure what is *actually* on the server, and if you ever need to pull a changed file back *down* to compare it… good luck. (Editing straight on the server and then trying to keep things in sync is, of course, even worse ;-)

**psync** is rsync for exactly these dummy webhostings. You upload one small PHP file (the *agent*) over FTP once, and from then on you drive it over HTTP from your machine. Unlike one-way FTP deployers, psync is **bidirectional**: it can `compare` both sides, `upload` your local changes, and `download` whatever got changed on the server — even for applications with tens of thousands of files, and while politely respecting the tiny time/memory/upload limits of cheap shared hosting.

- **Client:** PHP 8.4+ (installed as `composer global`)
- **Agent (server):** PHP 7.4+, no Composer dependencies (just `ext-sodium`)

How it works
------------

[](#how-it-works)

1. **Install once.** `psync install` generates an **Ed25519** key pair and renders the agent — a single self-contained PHP file containing only the **public** key. You upload it via FTP to the directory that should become the remote root. The **private** key goes into your local config and nowhere else, so even a leaked agent file lets nobody forge a request. The agent gets a **randomized filename**(`psync-agent-.php`) so its URL can't be scanned for, and it carries a header comment that tells anyone who later stumbles on it that it is a maintenance tool — not a backdoor — and is safe to delete.
2. **Every call is a signed HTTP request.** The client signs each request with the private key; the agent verifies it with the public key, plus a timestamp and nonce against replay. It therefore works even over plain HTTP, which many of these hostings still serve.
3. **Comparison is two-phase**, the way rsync stays fast. First a quick listing of name + size + mtime on both sides. Only for files of equal size but different mtime does the agent compute an `md5` — in batches sized to fit the server's limits. A local state cache remembers the verdict, so a file whose only difference is a wobbly FTP mtime is not re-hashed on every run.
4. **Transfers are streamed and safe.** Files move in a compact binary framing (optionally gzipped), never loaded whole into memory. Each file is written **atomically** (temp file + rename) and stamped with the source's mtime. Deletion is opt-in (`--delete`) and shielded by a protect-list.
5. **It survives crashes.** Because shared hosting loves to kill a request mid-flight, every operation is idempotent and **resumable** — if it dies, just run it again and the finished files are skipped.

Installation
------------

[](#installation)

```
composer global require jakubboucek/psync
```

Configuration
-------------

[](#configuration)

`psync install` generates `.psync.php`. Fill in `url` and `mapping.local`:

```
