PHP en EGPHP
Todo lo que construimos empieza con PHP.
Nuestro equipo lleva veinticinco años escribiendo y ejecutando PHP, desde PHP 4. Los servidores, el panel de control y los sitios que cuidamos parten de aquí.
Veinticinco años, versión a versión
No leímos sobre estas versiones. Actualizamos sitios reales a través de cada una de ellas, y cada fila de abajo es un cambio que tuvimos que resolver en un servidor en producción.
-
PHP 4 2000
Sesiones y búfer de salida, integrados
Llegó el Zend Engine, y las sesiones y el búfer de salida pasaron a formar parte del lenguaje en lugar de ser complementos. Toda una generación de los primeros sitios dinámicos se escribió sobre él.
Zend Enginesession_start()ob_start()
Lo que supuso para nosotrosDonde empezó nuestro equipo: sitios escritos a mano en servidores compartidos, con register_globals todavía activado.
-
PHP 5.0 2004
Un modelo de objetos de verdad
Zend Engine 2 trajo clases con visibilidad, interfaces y excepciones, objetos pasados por manejador en lugar de copiados, y las extensiones MySQLi y SimpleXML.
privateinterfacetry / catchmysqli
Lo que supuso para nosotrosEl código podía organizarse en clases compartidas por todo un equipo, y la base de datos estrenó un driver moderno.
-
PHP 5.3 2009
Espacios de nombres y closures
Espacios de nombres, funciones anónimas y enlace estático en tiempo de ejecución: la base sobre la que después se construyeron Composer y el ecosistema de paquetes compartidos.
namespacefunction () use ()static::
Lo que supuso para nosotrosPor fin, bibliotecas de distintos autores podían convivir en un mismo proyecto sin que sus nombres chocaran.
-
PHP 5.4 2012
Traits, arrays cortos y una limpieza Rompió código antiguo
Traits, la sintaxis corta de arrays [] y un servidor de desarrollo integrado, mientras que register_globals, las magic quotes y el safe mode se eliminaron para siempre.
trait[ ]php -S
Lo que supuso para nosotrosLos sitios antiguos que dependían de register_globals dejaron de funcionar, y actualizarlos obligaba a arreglarlos primero.
-
PHP 5.5 2013
OPcache de serie
OPcache pasó a incluirse en el propio PHP y mantenía en memoria los scripts compilados, junto con los generadores y password_hash().
opcacheyieldpassword_hash()
Lo que supuso para nosotrosCódigo compilado guardado en memoria en lugar de releerlo en cada petición. Sigue siendo el primer ajuste que revisamos en cualquier servidor PHP.
-
PHP 6 nunca publicada
La versión que nunca salió
PHP 6 se diseñó en torno a cadenas Unicode nativas y se abandonó. La siguiente versión se numeró 7 para que no se confundiera con los libros y planes escritos para la 6.
-
PHP 7.0 2015
El salto de velocidad Rompió código antiguo
Un motor reconstruido que, según el proyecto PHP, era hasta el doble de rápido que la 5.6 y consumía menos memoria, además de declaraciones de tipos escalares y de retorno, ?? y <=>.
int $id: string??<=>
Lo que supuso para nosotrosSe eliminaron las antiguas funciones mysql_*, un motivo frecuente por el que un sitio antiguo se rompía con esta actualización.
-
PHP 7.4 2019
Propiedades tipadas y precarga
Propiedades tipadas, funciones flecha, el operador ??=, la precarga de OPcache y FFI.
public int $idfn ($x) =>??=
Lo que supuso para nosotrosLa última versión 7.x, y en la que muchas aplicaciones antiguas se quedaron más tiempo; por eso seguimos sacando sitios de ella.
-
PHP 8.0 2020
JIT, atributos y argumentos con nombre Rompió código antiguo
Un compilador JIT, atributos, argumentos con nombre, tipos de unión, match, el operador nullsafe ?-> y la promoción de propiedades en el constructor.
#[Attribute]match?->JIT
Lo que supuso para nosotrosMuchas advertencias pasaron a ser errores y cambiaron las comparaciones entre cadenas y números, así que un código que funcionaba sin problemas en 7.4 podía detenerse en 8.0.
-
PHP 8.1 2021
Enums, readonly y fibers
Enums nativos, propiedades readonly, fibers, el tipo de retorno never y la sintaxis de callables de primera clase.
enumreadonlyFibernever
Lo que supuso para nosotrosLos fibers abrieron el camino a bibliotecas PHP asíncronas sin cambiar cómo se ejecuta una petición normal.
-
PHP 8.2 2022
Clases readonly y un aviso para el código antiguo
Clases readonly, tipos DNF, true, false y null como tipos independientes, y una nueva extensión Random.
readonly class(A&B)|nullRandom\Randomizer
Lo que supuso para nosotrosLas propiedades dinámicas quedaron obsoletas, y los plugins antiguos llenaron los registros de avisos hasta que se actualizaron.
-
PHP 8.3 2023
Constantes tipadas y #[\Override]
Constantes de clase tipadas, el atributo #[\Override], json_validate() y el acceso dinámico a constantes de clase.
const string#[\Override]json_validate()
Lo que supuso para nosotrosUna versión más tranquila, lo que la convierte en un paso sencillo para los sitios que ya están en 8.2.
-
PHP 8.4 2024
Hooks de propiedades
Hooks de propiedades, visibilidad asimétrica, objetos lazy, un analizador DOM compatible con HTML5 y new MyClass()->method() sin los paréntesis adicionales.
get { }public private(set)Dom\HTMLDocument
Lo que supuso para nosotrosLos getters y setters que antes necesitaban un método cada uno ahora pertenecen a la propia propiedad, así que hay menos código que mantener.
-
PHP 8.5 2025
El operador pipe Actual
El operador pipe |>, una extensión URI integrada, clone with, el atributo #[\NoDiscard], array_first() y array_last(), y un backtrace en los errores fatales.
|>Uri\Rfc3986\Uriclone($o, [ ])
Lo que supuso para nosotrosLa línea de versiones actual, y con la que empezamos los sitios nuevos cuando su código lo admite.
Los años son los de la primera versión de cada una, según el propio historial de versiones del proyecto PHP.
Sigue una petición a través de la pila
Una página de un sitio PHP atraviesa cinco capas al entrar y vuelve a subir por esas mismas cinco al salir. Nos encargamos de todas ellas, y cada una tiene su propia página.
-
El visitante
Un navegador pide una página por HTTPS. El certificado, el firewall y las reglas que protegen el servidor deciden si la petición entra o no.
-
El servidor web
Nginx o LiteSpeed recibe la conexión, sirve por sí mismo las imágenes y los archivos, y pasa solo el trabajo de PHP al pool que tiene detrás.
-
El entorno de ejecución de PHP
Pools de PHP-FPM, uno por sitio, cada uno con la versión de PHP que necesita su código, con OPcache en caliente y procesos dimensionados para el tráfico.
-
Tu código
Un framework o una plataforma ya hecha convierte la petición en una página: tu propia aplicación Laravel, o WordPress, Magento, Moodle y los demás.
-
Los datos
MySQL o MariaDB guarda los registros, y Redis mantiene en memoria lo que se pide una y otra vez.
El propio servidor
Nuestros propios servidores, gestionados por el mismo equipo, con nuestro propio panel de control encima.
Pasar a un PHP más nuevo sin una mañana de sustos
Cada sitio tiene su propio pool, así que un servidor puede ejecutar varias versiones de PHP a la vez y cada sitio da el paso cuando su código está listo, no cuando lo está el servidor.
Anotamos lo que ejecuta cada sitio
Su versión de PHP, sus extensiones y los plugins o paquetes que lo frenan.
Una copia prueba la nueva versión
El sitio se copia y se ejecuta en la siguiente versión de PHP, y su registro de errores se lee línea por línea.
Arreglamos lo que se rompe
Las funciones eliminadas, las llamadas obsoletas y los plugins sin actualización se corrigen o se sustituyen.
Un sitio cada vez
Cada sitio pasa a su nuevo pool por separado, y puede volver atrás al instante si se pasó algo por alto.
| Sitio | PHP | Pool | Estado |
|---|---|---|---|
| shop.example.com | 8.4 | fpm-shop | en vivo |
| blog.example.com | 8.3 | fpm-blog | en vivo |
| crm.example.com | 7.4 → 8.3 | fpm-crm | en una copia |
| learn.example.com | 8.3 | fpm-learn | en vivo |

Tráenos tu PHP
Un sitio antiguo que necesita un PHP más nuevo, una plataforma que instalar o un servidor donde ejecutarlo todo. Cada trabajo se presupuesta tras una breve conversación.