Written by Roman Pronskiy on Oct 25, 2023 | About | Blog

Turn Any PHP Script into a Native Single-File Binary

For years, I've dreamed of being able to create PHP CLI scripts that can be easily distributed without requiring users to have PHP installed on their machines.

But a scripting language needs an interpreter, they said. Not anymore! PHP still can't be compiled for real, there is a trick you can use.

TL;DR

  • There is a project crazywhalecc/static-php-cli that allows you to compile PHP statically.
  • Under the hood it uses dixyes/phpmicro – it is a special static PHP binary which you can “glue” to any PHP script.
  • What remains is to build the application in PHAR and attach a statically-compiled interpreter binary to it.

Show me the code!

Here's a minimal PoC.

First, let’s download a pre-built phpmicro binary from the static-php-cli website. Since I’m on macOS, I’m using the following link:

curl -O https://dl.static-php.dev/static-php-cli/common/php-8.2.10-micro-macos-aarch64.tar.gz

tar -xvf php-8.2.10-micro-macos-aarch64.tar.gz

Now let’s create a simple application in index.php:

<?php

echo "hello world";

And we are ready to glue it with a PHP binary:

cat ./micro.sfx index.php > indexbin && chmod 0755 ./indexbin

And voilà! Run it:

./indexbin

PoC is nice, but will this work for real CLI applications?

Yes, but there may be challenges.

For a real CLI app, you would most likely need to pack the app in a PHAR file. For this, you'd typically use box-project/box.

I successfully created a basic "hello world" application with this method. You can find it in this repo: github.com/pronskiy/phin

However, when I attempted to integrate something more substantial like symfony/console, I encountered an error:

zend_mm_heap corrupted
Abort trap: 6

It looks fixable, but I haven't looked into exactly what causes it yet.

There will probably be other difficulties with more complex applications.

What about platform support? Linux / macOS / Windows ?

In the PoC above, I just download the phpmicro archive from here: https://dl.static-php.dev/static-php-cli/common/

But for real-world applications, you would want to build it on a CI for all platforms at once.

Micro-php is compatible with the popular Linux, macOS, and Windows platforms. Yet, as of now, GitHub Actions doesn't offer free builds for the ARM architecture, like macOS on M1/M2. But alternative CI/CD providers are available, or you could opt for a paid solution.

On a side note, pooling resources in a single repository to fund micro-php builds might be a viable solution. ;-).

Future prospects of this method?

Ideally, all of this can be organized as a ready-made GitHub Action, which you simply add to your repository, and for each release of your CLI-app you will get binaries for all platforms. Users would be able to download and use your CLI binaries without additional dependencies.

Static-php-cli is used in FrankenPHP. Notably, Kevin Dunglas, the author of FrankenPHP, actively contributes to static-php-cli.