Real PHP, running bare-metal on microcontrollers.
php-baremetal runs the official PHP interpreter on 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 same interpreter, on a $5 chip.
The PHP 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.
8.3–8.5
PHP versions
2
Chip families
0
Lines re-implemented
8–32 MB
PSRAM
A full PHP runtime, not a toy.
The complete Zend engine and standard library, real extensions, and the applications that ride on top — all cross-compiled to the chip's own CPU and run through the official embed SAPI.
The unmodified engine
Namespaces, classes, traits, enums, closures, generators, match, exceptions, typed properties and attributes — plus strings, arrays, JSON, PCRE, hashing, SPL, Reflection and the CSPRNG.
Native, not emulation
PHP's C is built with the chip's own cross-compiler and runs on the board's CPU through the official embed SAPI. No interpreter-on-an-interpreter.
Silicon-agnostic by design
Runs today on the ESP32-P4 (RISC-V) and ESP32-S3 (Xtensa) — but a new chip family is a directory, not an engine change. The port targets microcontrollers, not one vendor, so more silicon can follow.
Real extensions
date, mbstring, filter, ctype, session, PDO SQLite, full OpenSSL 3.0 with an HTTPS client, and Zend OPcache (no JIT, statically linked).
Composer & frameworks
Composer works with unmodified packages from Packagist. With the web-server model and OPcache, the ESP32-P4 serves stock Laravel and Symfony pages over HTTP.
Storage, your way
Run the source from a microSD (swap the card to change the program, no rebuild) or embedded in the flash image. The partition layout is generated per build.
State across requests
A reboot-persistent store_* (NVS) and a volatile in-RAM mem_*, so the shared-nothing web-server model can still hand data from one request to the next.
Extend it in C
Drop native code under firmware/exts/ and it compiles into the firmware — no fork required. A GPIO extension drives pins straight from PHP.
One tool for all of it
phpflash — a single static binary that scaffolds, builds, flashes and monitors a project, and identifies a connected board. It reads what the firmware can build, so it only ever offers real choices.
WiFi, from PHP
Scan for networks, join one, or bring up your own access point — straight from PHP. Even the radio-less ESP32-P4 gets WiFi through an on-board companion, so a board can create its own network and serve its pages over it, no router in sight.
Arduino-style, in the language you already know.
A setup()/loop() sketch drives the board; a built-in gpio extension talks to the pins. This is the whole program that blinks an LED.
<?php // runs once at boot function setup(): void { gpio_mode(2, GPIO_OUTPUT); } // runs forever, like an Arduino loop function loop(): void { gpio_write(2, 1); delay(500); gpio_write(2, 0); delay(500); }
Live on the board
A firmware sketch, or a real web server.
One line in the project config picks how PHP runs on the board. Drive hardware in an Arduino-style loop, or stand up an HTTP server that runs your script per request — the same engine, two execution models today, with a third on the way.
type = "init-loop"
Firmware sketch
setup() runs once at boot, then loop($tick) repeats forever — driven from C so the watchdog stays fed. The way to blink an LED, read a sensor, or drive a display.
type = "web-server"
HTTP web server
A built-in server runs your index.php per request and returns the response over HTTP. Stock Laravel and Symfony pages served straight off the chip, through a per-request SAPI with OPcache.
type = "event-driven"
Event-driven
Coming soonWake on a hardware event — a GPIO interrupt, a timer, an incoming packet — run a PHP handler, then go back to sleep. The low-power model for battery devices that stay idle most of the time.
The firmware and the tool.
php-baremetal is two repositories: the PHP port itself, and a single command-line tool that scaffolds, builds, flashes and monitors a project without touching ESP-IDF by hand.
Esp32 Firmware
php-esp32
php-esp32 is the firmware that brings real PHP to the ESP32 family. It cross-compiles the unmodified PHP/Zend engine from php.net for the microcontroller — not a subset, not a reimplementation — so your index.php executes bare-metal on the chip. It runs today on the ESP32‑P4 (RISC‑V) and ESP32‑S3 (Xtensa), in an Arduino-style init-loop or as an HTTP web server.
Latest
v0.18.x
Flash Tool
flash-tool
The command-line front end for php-esp32 - a single static binary that scaffolds, builds, flashes and monitors your bare-metal PHP project and identifies the connected board. It hard-codes no hardware: boards, chip families and build options are read from the firmware, so it grows with the port. ESP32 today.
Latest
v0.10.x
Flash your first board in minutes.
Install the tool, scaffold a project, write your index.php, and flash it. Your PHP is running on the chip.