TypePHP acaba de abrir una vía poco habitual para el ecosistema PHP: compilar código PHP por adelantado hasta convertirlo en código máquina nativo, sin ejecutar posteriormente las funciones compiladas como opcodes de Zend. El proyecto, desarrollado por el equipo de Swoole, utiliza PHP como lenguaje de entrada, genera C++17 y termina produciendo ejecutables, extensiones PHP o bibliotecas compartidas que pueden correr directamente sobre el procesador.
Las claves de TypePHP en 20 segundos
- TypePHP es un compilador Ahead-of-Time que convierte PHP en C++17 y después en código máquina.
- Puede generar ejecutables, extensiones PHP y bibliotecas compartidas.
- El propio compilador está escrito en PHP y puede compilarse a sí mismo.
- Sus benchmarks internos muestran mejoras de entre 6,5 y 8 veces en pruebas de PHP.
- Todavía no pretende ser compatible con cualquier aplicación PHP existente.
La propuesta resulta especialmente interesante porque no intenta sustituir PHP por otro lenguaje. El desarrollador continúa escribiendo PHP, aunque puede añadir información de tipos y estructuras específicas cuando quiere obtener mayor rendimiento.
Eso diferencia TypePHP de proyectos como TypeScript. Mientras TypeScript termina convirtiéndose nuevamente en JavaScript para ejecutarse dentro de un motor JavaScript, TypePHP lleva una parte del código hasta instrucciones nativas ejecutables por la CPU.
La comparación más cercana tampoco sería exactamente PHP JIT. OPcache, JIT y TypePHP actúan en fases distintas y con objetivos diferentes.
De PHP a C++17 y después a código máquina
PHP normalmente transforma el código fuente en opcodes que ejecuta Zend Engine. OPcache evita tener que repetir parte de ese trabajo almacenando el bytecode compilado, y el JIT introducido en PHP 8 puede transformar determinadas partes en código máquina durante la ejecución.
TypePHP adopta otra estrategia: realiza ese trabajo antes de ejecutar la aplicación.
De forma simplificada:
PHP
↓
Análisis y validación
↓
C++17
↓
Compilador nativo
↓
Código máquina
El flujo real incorpora además declaraciones .stub.php, posibles fuentes C o C++, cachés de objetos compilados y cabeceras precompiladas.
Según la documentación del proyecto, TypePHP puede producir actualmente varios tipos de salida:
| Modo | Resultado | Uso habitual |
|---|---|---|
bin | Ejecutable nativo | CLI, servicios y aplicaciones independientes |
ext | Extensión .so o .dll | Añadir código compilado a PHP |
lib | Biblioteca compartida | Reutilizar APIs compiladas |
| WASI | Componente WebAssembly | Entornos WASI y navegador |
El modo bin es probablemente el que mejor explica el cambio conceptual.
Una aplicación PHP compilada de esta forma puede arrancar mediante un ejecutable nativo sin tener que lanzar primero php desde la línea de comandos.
Eso no significa que desaparezca completamente el ecosistema PHP. Los binarios pueden seguir dependiendo de PHPX, libphp y otras bibliotecas configuradas durante la compilación.
TypePHP tampoco elimina Zend de todas las situaciones.
Las características dinámicas de PHP, las funciones internas, determinados objetos, reflection y otros elementos pueden interoperar con Zend mediante PHPX, la capa utilizada por el proyecto para conectar ambos mundos.
La diferencia está en que las funciones de usuario que TypePHP ha compilado ya no necesitan ejecutarse como una secuencia de opcodes de Zend.
Un compilador PHP escrito en PHP
Hay además una particularidad técnica llamativa: TypePHP está escrito completamente en PHP.
El propio compilador tpc puede compilar su código fuente utilizando TypePHP. Es lo que se conoce como un compilador self-hosting o autoalojado.
No es únicamente una curiosidad.
Que un compilador sea capaz de compilarse a sí mismo suele ser una prueba importante de madurez arquitectónica, porque obliga a que el propio lenguaje soportado sea suficiente para desarrollar una aplicación tan compleja como el compilador.
El proyecto explica que no utiliza código C o C++ como pegamento interno para implementar el compilador. C++ aparece como lenguaje intermedio generado durante el proceso de compilación.
Un proyecto básico puede instalar TypePHP mediante Composer:
composer require --dev swoole/typephpLenguaje del código: JavaScript (javascript)
Y después compilarse mediante:
vendor/bin/tpc.php project.yml
También puede descargarse el repositorio y ejecutarse directamente:
git clone https://github.com/swoole/typephp.git
cd typephp
composer install
php bin/tpc.php --helpLenguaje del código: PHP (php)
En Linux, el entorno de compilación necesita PHP 8.4 o 8.5, un compilador compatible con C++17, CMake 3.24 o posterior, Composer 2 y varias bibliotecas adicionales dependiendo de las funciones utilizadas.
En Debian y Ubuntu las dependencias básicas indicadas por el proyecto pueden instalarse con:
sudo apt install build-essential cmake pkg-config libgmp-dev libmpfr-dev
En Fedora, RHEL y distribuciones derivadas:
sudo dnf install gcc gcc-c++ cmake pkgconf-pkg-config gmp-devel mpfr-devel
Y en Arch Linux:
sudo pacman -S base-devel cmake pkgconf gmp mpfr
Linux x86-64 es actualmente la plataforma principal de desarrollo y pruebas completas, aunque TypePHP dispone también de objetivos para Linux ARM64, macOS ARM64, Windows x64 y WASI.
Los tipos nativos son donde TypePHP intenta ganar rendimiento
La compilación AOT por sí sola no explica todo el potencial de TypePHP.
Una parte importante está en el nuevo modelo de tipos.
PHP mantiene tradicionalmente una gran flexibilidad dinámica. Esa flexibilidad es cómoda para desarrollar, pero tiene un coste cuando se realizan millones de operaciones matemáticas o accesos a estructuras de datos.
TypePHP permite activar:
use native_types;Lenguaje del código: PHP (php)
A partir de ahí determinados tipos PHP pueden tener una representación nativa mucho más directa.
Por ejemplo:
| Tipo TypePHP | Representación aproximada en C++ |
|---|---|
int | int64_t |
float | double |
bool | bool |
Una función sencilla como:
<?php
use native_types;
function fib(int $n): int
{
if ($n == 1 || $n == 2) {
return 1;
}
return fib($n - 1) + fib($n - 2);
}Lenguaje del código: HTML, XML (xml)
puede transformarse en operaciones numéricas nativas en lugar de realizar cada cálculo mediante las estructuras dinámicas habituales de Zend.
El proyecto incorpora además tipos numéricos de alta precisión como bigInt, decimal y bigFloat, apoyados respectivamente en GMP, libmpdec y MPFR.
También incorpora contenedores tipados.
Entre ellos aparecen:
std::array
std::vector
std::map
std::ordered_mapLenguaje del código: CSS (css)
Por ejemplo:
<?php
use native_types;
function main(): void
{
$vector = std::vector(Type::Int);
$vector[] = 10;
$vector[] = 20;
$vector[] = 30;
$sum = 0;
foreach ($vector as $value) {
$sum += $value;
}
echo $sum . "\n";
}Lenguaje del código: HTML, XML (xml)
La ventaja potencial es importante para algoritmos que procesan grandes cantidades de datos.
En uno de los benchmarks publicados por el propio proyecto se comparó una carga intensiva de actualización de elementos utilizando arrays PHP, std::array de TypePHP y std::vector de C++.
| Implementación | Tiempo publicado |
|---|---|
| Array PHP con JIT | 67,6 segundos |
std::array con TypePHP AOT | 6,4 segundos |
std::vector en C++ | 6,2 segundos |
En esa prueba concreta, TypePHP quedó aproximadamente diez veces por delante del array PHP y muy cerca del código C++.
Hay que interpretar la cifra con prudencia. Se trata de un benchmark publicado por el propio proyecto, realizado sobre una carga muy favorable a la compilación estática y al uso de estructuras tipadas. No significa que una aplicación WordPress, Laravel o Symfony vaya a ejecutarse diez veces más rápido simplemente por utilizar TypePHP.
La propia documentación ofrece otra comparación utilizando bench.php y micro_bench.php, pruebas incluidas en el código fuente de PHP:
| Benchmark | PHP interpretado | TypePHP AOT -O3 | Diferencia |
|---|---|---|---|
bench.php | 5,034 s | 0,603 s | ~8× |
micro_bench.php | 13,045 s | 2,021 s | ~6,5× |
De nuevo son resultados del proyecto y no una garantía aplicable a cualquier aplicación.
En una web cuya mayor parte del tiempo se pierde esperando consultas SQL, Redis, almacenamiento, APIs externas o servicios remotos, acelerar una operación aritmética puede producir una mejora global mucho menor.
Es en trabajos intensivos de CPU donde TypePHP resulta conceptualmente más atractivo: tratamiento masivo de datos, cálculos numéricos, procesamiento por lotes, parsers, generación de informes o determinados servicios de larga ejecución.
TypePHP frente a PHP, OPcache y JIT
Las tecnologías tampoco deberían considerarse exactamente intercambiables.
| Tecnología | Cuándo compila | Resultado | Requiere Zend en ejecución |
|---|---|---|---|
| PHP tradicional | Al ejecutar | Opcodes | Sí |
| OPcache | Mantiene bytecode compilado | Opcodes cacheados | Sí |
| PHP JIT | Durante ejecución | Código máquina para ciertas rutas | Sí |
| TypePHP | Antes de ejecutar | Código nativo | Parcialmente, según funciones utilizadas |
OPcache continúa teniendo sentido para aplicaciones PHP convencionales.
El JIT también puede resultar útil para determinados workloads sin introducir un proceso de compilación AOT adicional.
TypePHP persigue algo diferente: permitir que partes del software puedan diseñarse desde el principio como código PHP compilado de forma estática.
Esto puede resultar particularmente interesante para extensiones.
En lugar de escribir una extensión PHP completa en C, TypePHP permite compilar código como una extensión cargable:
bin/tpc.php extension/ -m ext -o my_extension
También puede generarse una biblioteca compartida:
bin/tpc.php lib/ -m lib -o mylib
La posibilidad de mezclar PHP y C++ amplía este planteamiento. TypePHP permite declarar funciones implementadas en C++ mediante archivos .stub.php y llamarlas posteriormente desde código PHP compilado.
Esto crea una opción intermedia entre escribir toda la aplicación en PHP y trasladar las partes críticas a una extensión C desarrollada manualmente.
El principal límite: TypePHP todavía no es cualquier PHP
Aquí está la parte que puede perderse fácilmente al observar únicamente sus benchmarks.
TypePHP no promete compatibilidad total con PHP.
El proyecto reconoce explícitamente que implementa un subconjunto definido y probado del lenguaje.
Existen decisiones necesarias para poder realizar compilación AOT.
Por ejemplo, el ámbito global está orientado a declaraciones y el código ejecutable debe estar dentro de funciones o métodos. En modo binario tiene que existir una función main().
Un programa mínimo sería:
<?php
function main(): void
{
echo "Hello World!\n";
}Lenguaje del código: HTML, XML (xml)
Después:
bin/tpc.php hello.php
./hello
Algunas construcciones altamente dinámicas relacionadas con referencias, reflection, closures o declaraciones todavía pueden no ser compatibles.
El proyecto mantiene una documentación específica sobre características incompatibles, algo que cualquier equipo debería revisar antes de considerar una migración.
Esto hace que TypePHP sea mucho más fácil de probar en código nuevo o módulos computacionalmente intensivos que aplicarlo directamente sobre una gran aplicación PHP existente.
Tampoco sería prudente asumir que puede compilarse hoy un WordPress, Magento, Drupal, Laravel o Symfony completo sin cambios. El uso intensivo que estos proyectos hacen de comportamiento dinámico, reflection, generación de clases, paquetes y extensiones exige evaluar la compatibilidad caso por caso.
Hay además implicaciones para los administradores de sistemas.
El despliegue deja de ser únicamente:
PHP + aplicación
y puede incorporar:
binario + PHPX + libphp + bibliotecas nativas
según el modo utilizado.
La compatibilidad entre la versión de PHP, cabeceras, php-config, libphp, ZTS o NTS y las extensiones utilizadas también pasa a tener importancia.
La propia documentación advierte de problemas de ABI cuando se mezclan componentes construidos contra versiones diferentes de PHP.
¿Puede TypePHP proteger el código fuente?
El proyecto presenta otro beneficio: distribuir un binario en lugar de entregar los archivos PHP originales.
Eso dificulta considerablemente recuperar el código fuente original, aunque afirmar que un binario no puede descompilarse sería excesivo.
Los binarios nativos pueden analizarse mediante ingeniería inversa, desensambladores y decompiladores. Lo que desaparece es la facilidad de abrir directamente el .php y leer el código original.
Puede resultar útil para determinados productos comerciales, appliances o aplicaciones distribuidas a clientes, aunque la seguridad de un producto nunca debería depender únicamente de ocultar su implementación.
Una pieza más en la evolución del rendimiento de PHP
TypePHP llega después de varios cambios importantes en la ejecución de PHP.
OPcache redujo el coste de recompilar scripts constantemente. PHP 7 modificó profundamente Zend Engine y mejoró el rendimiento general. PHP 8 añadió JIT. Las versiones posteriores han seguido introduciendo mejoras en tipos, motor y lenguaje.
TypePHP plantea ahora un camino distinto: permitir que PHP salga parcialmente de su modelo tradicional de ejecución y se convierta en software compilado antes del despliegue.
Todavía es demasiado pronto para saber cuánto espacio encontrará esta aproximación dentro del ecosistema.
Su éxito dependerá de algo más que de conseguir buenos benchmarks. Tendrá que demostrar estabilidad, compatibilidad, herramientas de depuración, integraciones, mantenimiento a largo plazo y una experiencia suficientemente sencilla para justificar el nuevo proceso de build.
Pero la idea tiene una consecuencia interesante: PHP podría utilizarse para desarrollar componentes que hasta ahora habrían terminado escritos en C++, Rust o Go simplemente por razones de rendimiento.
Eso no implica que TypePHP vaya a sustituir esos lenguajes. Significa que, para algunas cargas, reescribir el código PHP podría dejar de ser la única opción cuando aparece un cuello de botella de CPU.
Preguntas frecuentes
¿Qué es TypePHP?
TypePHP es un compilador Ahead-of-Time desarrollado por el equipo de Swoole que transforma código PHP en C++17 y posteriormente en código máquina nativo. Puede generar ejecutables, extensiones PHP, bibliotecas compartidas y determinados objetivos WebAssembly.
¿TypePHP sustituye a OPcache o al JIT de PHP?
No necesariamente. OPcache y JIT trabajan dentro del modelo de ejecución tradicional de PHP, mientras que TypePHP compila el código antes de ejecutarlo. Son aproximaciones diferentes y pueden resultar apropiadas para cargas distintas.
¿Puede TypePHP compilar una aplicación Laravel o WordPress completa?
No debe darse por hecho. TypePHP admite actualmente un subconjunto definido de PHP y mantiene una lista de características incompatibles. Los frameworks y CMS que utilizan mucho comportamiento dinámico deberían probarse y evaluarse individualmente.
¿Es TypePHP diez veces más rápido que PHP?
No de forma general. El proyecto ha publicado una prueba específica donde uno de sus contenedores tipados fue aproximadamente diez veces más rápido que un array PHP con JIT, además de benchmarks lingüísticos con mejoras de alrededor de 6,5 a 8 veces. Los resultados reales dependen del código, CPU, compilador y carga de trabajo.
Fuentes:
- Swoole, documentación oficial de TypePHP AOT.
- Repositorio oficial
swoole/typephp, documentación técnica, requisitos, benchmarks y modelo de compatibilidad.







