Ship PHP as .phpx. Run it without ever writing the source back to disk.
PHPX is a small command-line tool. You encrypt a .php file with a passphrase. The result is a .phpx file you can copy, double-click, or call from a script. When it runs, PHPX decrypts the payload in memory, then includes it. No temp file. No leftover .php.
It is vanilla PHP — not a new language, not a packed EXE, not a bundled runtime. If the machine has PHP 8.0+ and openssl, it can run PHPX.
You have a PHP script you want to carry around or hand to someone else, and you do not want the plaintext sitting next to it on disk.
Typical uses:
- A portable utility you keep on a USB drive or a shared folder
- A helper you open from Explorer / a file manager
- A script you invoke like any other CLI tool, with its own flags
PHPX is not a DRM system and not a way to hide code from the person who runs it. The same passphrase that runs a file can decrypt it. Treat a .phpx like a locked box: useful against casual snooping, useless against someone who has the key and a debugger.
You need php on your PATH (8.0+, openssl). From this repo:
php phpx.php encrypt app.php --key=secret
php phpx.php app.phpxWindows also has phpx.cmd. Linux has phpx.sh. After install (below), the command is just phpx.
Double-click phpx.cmd or phpx.sh (no arguments) to open an Install / Uninstall menu. Double-click a .phpx file to run it. Re-run phpx install after upgrading so file associations point at the current shim.
The passphrase prompt does not echo. In a pipe or CI, always pass --key.
| Command | What it does |
|---|---|
phpx encrypt file.php |
Write file.phpx (overwrites an existing artifact) |
phpx decrypt file.phpx |
Write file.php (refuses if that .php already exists) |
phpx run file.phpx [args…] |
Decrypt in memory and execute |
phpx file.phpx [args…] |
Same as run, for double-click / file association |
phpx install / uninstall |
OS integration (no administrator) |
phpx --help / --version |
Usage and version |
--key and --php belong to PHPX and must appear before the file. Everything after a .phpx path is the script’s own argv:
phpx connect.phpx --host 127.12.1.2Inside connect.phpx, $argv is:
['connect.phpx', '--host', '127.12.1.2']So phpx connect.phpx --help is your --help, not PHPX’s.
PHPX writes prompts, “Wrote …”, and errors to STDERR. STDOUT is reserved for the payload.
php phpx.php installNo administrator rights.
Windows — .phpx files open through phpx.cmd, Explorer gets Encrypt / Decrypt items, and the folder is added to your user PATH.
Linux — creates ~/.local/bin/phpx as a symlink to phpx.sh (the shim finds phpx.php next to the real script, not next to the symlink).
uninstall reverses that.
- PHPX reads the
.phpxfile (AES-256-CBC, passphrase-derived key). - It rewrites
__FILE__/__DIR__so they point at the.phpx, not at a fake path. - It
chdirs to that file’s directory and sets$argvas if you had runphp file.phpx …. - It includes the source from memory and then forgets it.
If you open a .phpx by double-click and the script dies, PHPX pauses so the window does not vanish. Explorer encrypt/decrypt also pauses when finished. A successful double-click run closes normally. phpx run never pauses.
PHPX does not ship PHP. It picks an interpreter in this order:
--php=/path/to/php- The
PHPX_PHPenvironment variable PHP_BINARY(the process already running PHPX)phponPATH
--php pointing at a different binary re-execs once, then continues.
- PHP 8.0 or newer
- The openssl extension
- The tokenizer extension if you want
__FILE__/__DIR__rewritten (without it, scripts can still usePHPX_FILEandPHPX_DIR) - Windows: Windows PowerShell 5.1 for the hidden passphrase prompt
- Linux:
sttyfor the hidden passphrase prompt
php tests/run.phpNo extra test framework.