TypePHP is an Ahead-Of-Time (AOT) compiler that translates PHP source code into C++ and then into native machine code. Unlike a bytecode cache or a VM, it does not interpret opcodes at runtime: it generates optimized native binaries that run directly on the CPU.
It keeps familiar PHP syntax and adds compile-time type information, so the compiler can emit fast, statically-typed C++ for hot paths. Dynamic PHP values, internal functions, reflection, and object metadata continue to interoperate with the Zend runtime through PHPX; user functions are not executed as Zend opcodes after they have been compiled.
TypePHP is written entirely in PHP and is fully self-hosting: the tpc
compiler binary is built by compiling the compiler's own PHP source code with
TypePHP. The bootstrap chain is pure PHP — no C or C++ glue in the compiler
itself.
TypePHP is under active development. It intentionally supports a defined, testable subset of PHP rather than claiming drop-in compatibility with every dynamic PHP program. Read Compatibility model and the incompatible-feature list before adopting it for an existing application.
PHP source + .stub.php declarations + optional C/C++ sources
│
▼
parse, validate, and collect declarations
│
▼
lower function bodies and constants to C++17
│
▼
native compiler + reusable object/PCH caches
│
▼
executable | PHP extension | shared library | WASI component
The prepare phase builds the complete symbol model without allocating runtime cache IDs. Constants and declaration defaults retain their AST until the convert phase, where they are lowered after all project symbols are known. This two-phase design keeps multi-file and self-hosted builds deterministic.
tpc compiles the compiler's own
source into a native binary.bin executable, a loadable
PHP ext extension, or a reusable lib shared library from the same codebase.int, float, and bool map directly to C++
scalar types (int64_t, double, bool) for orders-of-magnitude speedups
on numeric code.bigInt (GMP), decimal (libmpdec), and
bigFloat (MPFR), with typed operators and method APIs.std::array, std::vector, std::map, and
std::orderedMap with compile-time element types; up to 10× faster than
PHP arrays and on par with C++ std::vector.$s->upper(), $arr->contains(), $big->mul(2)); statically-known calls
are resolved directly at compile time.std::any(), std::object(),
std::ref(), std::expected(), std::unexpected(), plus toObject(),
toInt(), toString(), toArray() and friends.#[Immutable] read-only contracts and StdList / StdDict
array-shape metadata, checked at compile time with zero runtime cost.#[Getter], #[Setter], #[With],
#[Constructor], #[Printer], and #[Arrayable] generate type-safe methods
from property declarations.clone()-with, and (void) discard expressions.| TypePHP AOT | Opcode cache (OPcache) | JIT (PHP 8+) | |
|---|---|---|---|
| Compilation target | Native machine code | Bytecode | Machine code (trace) |
| Startup / warm-up | None (already compiled) | Per-process warm-up | JIT warm-up |
| Type-driven optimization | Compile-time, full-program | None | Limited, trace-based |
| Native executable output | Yes | No | No |
| Source code protection | Compiled to machine code | Bytecode (reversible) | Bytecode (reversible) |
| Deterministic performance | Yes | No | No |
Strengths over plain PHP:
libphp, and any configured
native libraries, which must be available in the deployment package.int, float, and bool
locals use native C++ storage. Use std::any() for an individual dynamic
value, or use varint_types when a file requires PHP integer widening.declare(strict_types=1) is unnecessary.php-configlibphp.so or libphp.dylib) for binary/shared-library
builds on Unix-like systems# Ubuntu/Debian
sudo apt install build-essential cmake pkg-config libgmp-dev libmpfr-dev
# RHEL/CentOS/Fedora
sudo dnf install gcc gcc-c++ cmake pkgconf-pkg-config gmp-devel mpfr-devel
# Arch Linux
sudo pacman -S base-devel cmake pkgconf gmp mpfr
GMP powers
bigIntand MPFR powersbigFloat. Thedecimaltype is backed by libmpdec, which is bundled with PHPX — no separate install required.
Linux x64 is the primary development and full-test CI platform. The compiler
also has Windows, macOS, ARM64, Android arm64-v8a, iPhoneOS arm64, and WASI
backends; availability of PHP embed, platform SDKs, toolchains, and third-party
libraries still determines which target can be built on a given host. Mobile
apps can implement their UI structure, application state, and business logic
in TypePHP while keeping only a thin platform-native UI bridge. See the
Android native app example and the
iOS/macOS native app example.
Linux, macOS, and Windows release assets are built separately with the latest
PHP 8.4 ZTS and PHP 8.5 ZTS releases; each filename identifies the complete
build PHP version and ZTS ABI. Linux and macOS users must select the build that
matches the host PHP. Each Windows x64 archive includes its matching PHP/PHPX
runtime and SDK, so users can directly choose the bundled PHP version they want.
Native NTS and 32-bit x86 packages are not provided. Linux and macOS archives
contain only the compiler, English and Chinese READMEs, and the license;
production Composer dependencies are embedded in tpc. Windows archives also
omit a separate vendor directory.
composer require --dev swoole/typephp
Then compile your project:
vendor/bin/tpc.php project.yml
When working inside the TypePHP source repository, use the local entry point instead:
bin/tpc.php project.yml
git clone https://github.com/swoole/typephp.git
cd typephp
composer install
php bin/tpc.php --help
PHPX_HOME may point to a separate PHPX checkout or installation. PHP_HOME
may point to the PHP embed prefix; it must contain bin/php-config, PHP headers,
and lib/libphp.so on Unix-like systems.
Binary mode uses the Embed SAPI and the host libphp by default. If that library
is missing, an interactive build offers to enable php-builder, which builds a
private static runtime from php-src. CLI and FPM targets always require
php-builder. See PHP builder.
Create hello.php:
<?php
function main(): void
{
echo "Hello World!\n";
var_dump(PHP_VERSION);
var_dump(php_uname());
}
Compile and run it:
bin/tpc.php hello.php
./hello
Example output (the exact PHP version and platform strings depend on the linked runtime):
Hello World!
string(5) "8.x.x"
string(16) "Linux ..."
Binary mode requires a global
main()function. It may be declared with no parameters, or asmain(int $argc, array $argv)to receive command-l
| 日期 | 榜单 | 排名 | 周期新增 | 总 STAR |
|---|