PHP 8.x · Rust loader · Web + CLI · Linux / Unix
BinaryPHP encrypts your commercial PHP source with AES-256-GCM, derives a unique key per file, and enforces domain-locked or MAC-locked, time-limited licenses—all decoded transparently by a tiny Rust loader extension. Quarterly key rotation with permanent backward compatibility — cracking costs far exceed legitimate license fees.
# Upload at binaryphp.com/encode/ and fill in the license:
Domains: acmestore.com, *.acmestore.com
Expires: 2027-12-31
Plugin: acme-pro
# Input → plugin.php (your source, ~40 KB)
# Output → plugin.php (sealed, ~41 KB binary content)
# Same filename, same .php extension — drop-in replacement, no caller changes.
# The loader recognizes it by a 5-byte "BPHP2" magic header, not extension.
# Master key stays on our server; only the sealed output goes back to you.
The moment a paying customer downloads your .zip, every line of PHP you wrote is theirs to copy, fork, and resell.
Disabling a license check takes minutes when the source is right there. Without code-level protection, your license is a checkbox, not a wall.
Once your customer downloads it, your source sits on shared hosts, VPSs, and CI runners you'll never see—exposed, indexed, and one tar -xzf away.
Drop a .php file or a plugin .zip into our web encoder. Pick the licensed domain(s), MAC address(es), and expiration. The master encryption key never leaves our server—you don't have to safeguard anything.
Download the sealed .bphp (or rezipped plugin). Each file has its own per-file salt and HKDF-SHA256-derived key. Tampering invalidates the GCM tag and refuses to run.
Your customer adds extension=binaryphp.so to php.ini. The loader hooks PHP's compile pipeline, decrypts in memory, validates the license against SERVER_NAME / HTTP_HOST (web) or the machine's MAC (CLI), and hands plaintext to the Zend Engine.
NIST-standard authenticated encryption. Tampering with a single byte invalidates the GCM tag and the file refuses to run.
Every encoded file has its own 16-byte salt and a unique HKDF-SHA256-derived key. Each file is sealed independently.
Mark functions with #[binaryphp\Protected] and they get compiled to our own bytecode — not PHP, not Zend opcode. Runtime is interpreted by the loader; the algorithm never exists as PHP source on the customer's disk.
List multiple hostnames or wildcard suffixes (*.example.com) per license. License passes if any matches.
For CLI tools, cron jobs, or any non-HTTP context: bind the license to the customer's machine via MAC address (read from /sys/class/net).
Issue time-limited builds for trials, subscriptions, or release windows. The loader checks the system clock against the embedded timestamp.
Loads via extension= in php.ini. Works under PHP-FPM, mod_php, CLI, FrankenPHP. No SAPI changes.
Single ~2.0 MB stripped .so (includes the bytecode VM + cranelift JIT). Sub-millisecond decrypt overhead per included file.
Plain .php files compile normally—the loader only intercepts files starting with the BinaryPHP magic header.
The loader hooks zend_compile_file, so decrypt happens
once per file per process. Once compiled, the runtime cost is
identical to plain PHP. With OPcache enabled, decrypt
happens once per cache invalidation cycle.
for + % + accumulate) · shorter is faster · baseline = plain PHP
| Workload | Plain PHP | binaryphp-rs (.bphp · full file encrypt) |
binaryphp-vm (#[Protected] · bytecode VM) |
|---|---|---|---|
1 M-iter hot loop in a function (for + % + accumulate) |
88.61 ms ± 0.95 |
89.48 ms ± 3.08 |
~115 ms (JIT) · interpreter 197.56 ms |
| Cold include — small file (~220 B) | 56.05 ms ± 1.62 |
56.46 ms ± 1.34 |
~bphp (stub only — VM idle until called) |
| Cold include — 10 KB file (200 functions) | 57.14 ms ± 1.33 |
57.09 ms ± 1.57 |
~bphp (same: VM cost is per-call, not per-load) |
| Steady-state with OPcache | identical |
identical |
per-call cost only |
| Plain ≈ binaryphp-rs (within noise). binaryphp-vm: ~1.3× hot-loop overhead with cranelift JIT (tier-up after 8 calls; int-only fast-path) — the trade-off for bytecode-level protection that survives even a leaked master key. | |||
Measured 2026-05-05 with hyperfine, 30 runs per row, on
Debian 12 (kernel 6.5) + PHP 8.2.30 + Rust 1.95.0,
Intel Xeon E5-2680 v4 @ 2.40 GHz (binaryphp.so 548 KB,
release+LTO). Per-include decrypt cost scales as
file_size / ~1 GB/s on AES-NI hardware, plus ~50 µs fixed
overhead for HKDF + license check. VM cost scales linearly with the
number of bytecode ops executed.
Compiler peepholes ($x++, $x += k,
$x = $x + e, slot-vs-slot int compare, $x * imm,
x % imm) cut the hot-loop overhead from ~5× to ~2.5× by
collapsing common LoadVar / StoreVar stack churn into single ops.
VM language coverage:
OOP (classes, extends, abstract,
interface, trait + use,
static, class constants, $this,
parent::, self::, magic __construct /
__get / __set / __call);
closures (function () use (…)) + arrow fns (fn () => expr);
try / catch / finally / throw;
match, === / !==, ??,
?:, <=>, instanceof;
lazy / coroutine generators (yield with frame snapshot & resume —
infinite generators work, only consumed values are computed);
full for / while / foreach / switch / break / continue;
spread ...$args; references &$x on params and
builtins like array_push / sort;
global; heredoc + nowdoc;
~50 built-in functions (strlen, count,
trim, explode, implode,
sprintf, md5, sha1,
base64_encode/decode, array_*, …);
encoder support for #[Protected] on individual class methods
(with full $this->prop read/write that round-trips back to PHP);
cranelift AOT JIT for hot int-only loops.
.bphp
(binaryphp-rs) — the runtime delta is unmeasurable. Reach for
#[Protected] (binaryphp-vm) only on your most
sensitive functions — license checks, key derivation, anti-tamper
routines — where you accept ~2.5× cost on those specific functions in
exchange for "even with the master key, the body is opaque bytecode."
With OPcache enabled, repeat-request overhead for plain code paths
remains indistinguishable from plain PHP.
Monthly or annual via Stripe. Annual = 20% off.
.php or .zip.zip up to 100 MBThe Free tier uses the exact same encoding engine as paid tiers. Same AES-256-GCM, same bytecode VM, same protection strength. The only difference is usage limits (file size, API access, batch rate).
Free, redistributable. Anyone running a BinaryPHP-encoded plugin needs this on their server.
# 1. Drop the .so into PHP's extension directory
$ sudo cp binaryphp.so /usr/lib/php/20220829/
# 2. Enable the extension
$ echo 'extension=binaryphp.so' | sudo tee /etc/php/8.2/mods-available/binaryphp.ini
$ sudo phpenmod binaryphp
# 3. Restart PHP-FPM (or your SAPI)
$ sudo systemctl restart php8.2-fpm
Verify the loader is active:
$ php -r 'echo binaryphp_version();'
0.9.2
$ php -r 'echo binaryphp_hostname();'
your-domain-or-hostname
$ php -r 'print_r(binaryphp_macs());'
Array ( [0] => aa:bb:cc:dd:ee:ff )
Or hit any phpinfo() page in a browser — you'll see a dedicated BinaryPHP block listing the loader version, master generation, supported file formats, and bytecode VM status. Same info, easier for non-CLI environments (cPanel, Plesk, shared hosts):
BinaryPHP support → enabled
Loader version → 0.9.2
Master gen → 2 (rotated 2026-05-06)
File formats → BPHP2/3/4 · HBPH1/2/3 · BVMC1/2/3
Bytecode VM → v3 obfuscation + cranelift JIT
Pick the loader for your PHP minor version (each .so is built against that exact ABI — they're not interchangeable):
Run php -v on your server to find your exact PHP version. macOS / aarch64 / FreeBSD not yet supported.
No CLI install, no master key to safeguard. Open the encoder, upload, set the license, download the sealed file.
.php → .php)Free tier accepts .php or .zip up to 1 MB. Pro up to 100 MB; Ultra up to 300 MB with multipart.
Honestly: no offline-runnable DRM can guarantee "permanently unbreakable". ionCube, Zend Guard, and SourceGuardian have all been studied and broken at various points.
So BinaryPHP's goal isn't a mythical "absolute security" — it's:
Make cracking cost far exceed the price of a legitimate license.
Cracking BinaryPHP isn't simply "decrypting a file." An attacker typically also has to:
Even when they succeed, what they get is rarely the original source — it's:
And BinaryPHP keeps moving:
so older cracking tools quickly stop working.
That's the core philosophy:
Not making cracking "impossible" — making it "not worth it."
If your code runs inside a web server, use domain binding. The loader checks $_SERVER['SERVER_NAME'] first (set by nginx/Apache config—cannot be spoofed by the client) and falls back to HTTP_HOST. If your code runs as a CLI tool (cron jobs, internal scripts), use MAC address binding—the loader reads from /sys/class/net/*/address. You can also include both in a single license; the loader passes if either matches.
No. The decrypt happens at compile_file time—once per file per PHP process. Once compiled into Zend opcodes, your code runs at identical speed to plain PHP. Our 50M-iteration loop benchmark shows runtimes within statistical noise (~30% normal jitter). With OPcache (standard on production servers), even the cold-start decrypt is amortized across all subsequent requests. See the Performance section above for measured numbers.
With the SaaS encoder: no. The master key never leaves our infrastructure. You upload plaintext, we encode, you download ciphertext. With the upcoming source-available CLI: yes, the key would be embedded in your encoder build. SaaS is the safer default for most plugin developers.
BinaryPHP is a 2026 ground-up implementation built on modern crypto (AES-256-GCM, HKDF-SHA256) plus our own bytecode VM that protects the core logic of #[Protected] functions. The toolchain is delivered as SaaS — your master encryption key never leaves our infrastructure, you don't have to safeguard or rotate anything, and the file format is documented and stable within major versions.
Only if their host has the BinaryPHP loader installed. The loader is free and redistributable — you can ask your customers to install it (one-line php.ini entry) or bundle it with your installer. We're working on cPanel / Plesk integrations to make this even more frictionless.
Three independent layers, all enforced by the loader:
#[binaryphp\Protected]. Those function bodies are compiled to our own bytecode (not PHP, not Zend opcode) and interpreted by the loader at runtime. They never exist as PHP source on the customer's machine.For your most sensitive algorithms, keep them on a server-side API; for everything else, BinaryPHP gives you defense in depth without re-architecting your codebase.
Yes. BinaryPHP intercepts PHP's compile pipeline, so anything that does include / require works transparently—Composer autoload, framework routers, plugin systems, custom dispatchers. Tested against PHP 8.1–8.4.
Compatible. OPcache caches the compiled opcodes after our loader has decrypted and compiled. Your encoded file gets decrypted once per OPcache invalidation cycle, then runs at native speed.
Documented and stable: a 52-byte header ("BPHP2" magic + version + 16-byte salt + 12-byte IV + 16-byte GCM tag) followed by ciphertext. The decrypted plaintext is a 4-byte length-prefixed license JSON followed by your PHP source. We commit to format compatibility within major versions.
All billing is handled by Stripe. You can choose:
30-day refund on subscriptions. Stripe accepts all major cards plus most regional payment methods.
Architecturally, no. We never execute uploaded PHP — we only tokenize and encrypt it. The encoder runs token_get_all() (PHP's lexer, not the executor) on your file, splits HTML from PHP code, AES-encrypts each PHP block, and writes the output. There is no eval, no include, no shell call against your code's contents.
For zip uploads we additionally enforce four hardenings before extracting:
../, absolute paths, drive letters)Each job runs in an isolated temporary directory that is wiped after the response is sent. You can upload literal malware — we'll just encrypt it and hand it back.
Designed for ISVs reselling encoded PHP plugins. After your customer purchases your software:
POSTs our REST API with the customer's domain / MAC + your encoding parameters + a webhook URL.POST the result download URL to your webhook.Encoded files live on R2 for 72 hours, then auto-delete. Source uploads we receive are deleted within 24 hours.
Disposable email service
“We started out testing BinaryPHP on the free tier and were genuinely impressed. We’ve since moved to Pro and now compile the entire site — PHPMailer included — through it. Seriously powerful, and we haven’t felt any speed penalty at all.”
Sign in with Google — free tier active immediately, no credit card.