Real PHP, running bare-metal on microcontrollers.
php-baremetal runs the official PHP interpreter on the ESP32 family of microcontrollers. It is not a
reimplementation, a language subset, or a transpiler: the upstream Zend engine from php.net is
cross-compiled for the chip and executes your index.php opcode by opcode, the same way it would
behind a web server. The source tree is vendored unchanged; the only modifications are separate
patches applied at build time, for the handful of places where a bare-metal RTOS differs from a Unix
host. Hand the same script to this engine or to a desktop php and you get the same output, because
underneath it is the same interpreter.
The project is two pieces: php-esp32, the firmware that is the PHP port itself, and phpflash, a single command-line tool that scaffolds, builds, flashes and monitors a project without touching ESP-IDF by hand.
The engine
- The complete, unmodified Zend engine and standard library — namespaces, classes, interfaces,
traits, enums, closures, generators,
match, exceptions, typed properties and attributes, plus strings, arrays, math, JSON, PCRE, hashing, SPL, Reflection and the CSPRNG. - Native code, not emulation: PHP's C is built with the chip's own cross-compiler and runs on the
board's CPU through the official
embedSAPI.
Hardware and versions
- Two chip families today — ESP32-P4 (dual-core RISC-V, up to 32 MB PSRAM) and ESP32-S3 (dual-core Xtensa) — with more of the ESP32 line planned; a new family is a directory, not an engine change.
- PHP 8.3, 8.4 and 8.5 coexist in the tree and are selectable per project; more releases slot in beside them as they are ported.
Extensions
ext/date(the realDateTimeand timezone database),mbstring(with optional oniguruma formb_ereg),filter,ctype,tokenizer,session, and PDO with SQLite.- OpenSSL in two builds: a compact mbedTLS-backed subset, or the full OpenSSL 3.0 (RSA, EC, X.509) with an HTTPS client on a networked board.
- Zend OPcache ported (no JIT, statically linked): compiled bytecode is cached to the card or into PSRAM, so a request stops recompiling the framework every time.
Applications
- Composer works with unmodified packages from Packagist — up to a standalone Eloquent ORM reading and writing a SQLite database.
- A web-server model turns each HTTP request into a full request/response cycle with
$_SERVER,$_GET,$_POST, cookies and sessions; stock Laravel and Symfony serve pages over HTTP on the ESP32-P4.
Hardware and project I/O
- A
setup()/loop()sketch model (Arduino-style) and a built-in GPIO extension for driving pins directly from PHP. - Custom C extensions per project: drop native code under
firmware/exts/(scaffold it withphpflash ext new) and it compiles into the firmware — no fork required. - Build-time environment: a project
.envis baked into the firmware and read as$_ENV/getenv(). - Reboot-persistent store: a
store_*key-value API, backed by the chip's NVS, keeps values across resets.
Storage and build
- Run the source from a microSD (swap the card to change the program, no rebuild) or embedded in the flash image (no card needed).
- The flash partition layout is generated per build, sized to what the project actually uses.
Tooling
- One binary —
phpflash— for the whole workflow:init,build,flash,monitor, plusdiscoverto identify a connected board. It reads the available boards, extensions and modes from the firmware you have installed, so it only ever offers real choices.
Install the tool (Linux; the flash-tool repo covers other platforms and building from source):
BASE=https://github.com/php-baremetal/flash-tool/releases/latest/download
curl -LO "$BASE/phpflash-linux-amd64" # or phpflash-linux-arm64
curl -LO "$BASE/SHA256SUMS"
sha256sum --ignore-missing -c SHA256SUMS # verify the download
chmod +x phpflash-linux-amd64
sudo mv phpflash-linux-amd64 /usr/local/bin/phpflashThen scaffold, build and flash a project:
phpflash system-setup # once: install ESP-IDF and php-esp32
phpflash init my-project # scaffold a project (board, PHP version, extensions, mode)
cd my-project
phpflash build
phpflash flash
phpflash monitor # watch the serial outputinit reads php-esp32 and walks through the choices, then writes a php-esp32.config.toml and a
project-src/ holding your code. Edit project-src/index.php, run phpflash build && phpflash flash,
and your PHP is running on the chip.
| Repository | Contents |
|---|---|
| php-esp32 | the firmware — the PHP port, boards, extensions and examples |
| flash-tool | phpflash, the command-line tool |