Todavía recuerdo la semana en que migramos a un cliente de agencia a PHP 7.2 y cada llamada a each() de un módulo rancio de CMS empezó a soltar avisos. En algún punto de aquel muro de repetición había un webhook de pagos genuinamente roto, y tardamos dos días en verlo porque el canal de errores se había convertido en papel pintado. Aquella semana me enseñó la postura que quiero defender hoy: un aviso de deprecación que aparece en los logs de producción no es un problema de PHP, es un problema de enrutado. El mensaje iba dirigido a un desarrollador, y tu proceso se lo entregó a quien estuviera de guardia.
La excusa para desempolvar esa vieja historia: internals ha cerrado la votación de la gran ronda de limpieza para PHP 8.6, unas 35 RFCs de deprecación individuales, y la gran mayoría salió aprobada. Para dejar claro qué significa eso en la práctica: nada deja de ejecutarse en 8.6. Las llamadas señaladas siguen devolviendo sus valores, solo dejan una nota, y la eliminación real es trabajo para una futura versión mayor. Esto es el lenguaje comportándose exactamente como siempre decimos que queremos que se comporten las plataformas, con años de aviso previo en lugar de una sorpresa.
Entonces, ¿por qué un warning tan educado sigue haciendo daño a los equipos? Por el sitio donde elegimos leerlo. Un E_DEPRECATED es un mensaje de los mantenedores de PHP a la única persona que puede abrir el fichero y cambiar la línea. Cuando lo dejas fluir a través de Monolog hacia tu agregación de logs, entregas ese mensaje al por mayor, a las tres de la mañana, a un operador que no puede hacer nada con él. Pagas dos veces: una en almacenamiento e ingesta por información que es completamente determinista y reproducible en cualquier portátil, y otra en atención, porque el único warning que de verdad importa esa noche queda enterrado bajo diez mil idénticos.
Mi conclusión es tajante: las deprecaciones del código que me pertenece nunca deberían sobrevivir lo suficiente como para llegar a un servidor. Ejecuto la suite de tests en la nueva versión de PHP y la configuro para que cualquier deprecación disparada desde mis propios namespaces haga fallar la ejecución. A partir de ahí es trabajo ordinario de rojo a verde, y buena parte es mecánico. Rector te reescribe automáticamente la mayoría de estos patrones, con el límite obvio de que solo opera sobre código tuyo, no sobre nada que viva bajo vendor/.
Ahora la concesión honesta, porque la versión dura de mi propia política tiene una debilidad real. Si tu pipeline se pone en rojo con cualquier deprecación venga de donde venga, el día que un paquete del que dependes se quede atrás respecto a 8.6, tus builds fallan durante todo el tiempo que necesite ese mantenedor, que pueden ser meses y está totalmente fuera de tus manos. Los equipos bajo presión de entrega no van a tolerar un pipeline permanentemente rojo. Alguien apagará la barrera, y entonces tendrás menos protección que antes de empezar. Los críticos de las barreras estrictas de deprecación tienen razón exactamente en este modo de fallo, y fingir lo contrario sería deshonesto.
Por eso acabo en un baseline en lugar de una prohibición, el mismo truco que PHPStan hizo respetable. Cuando ejecutes por primera vez contra 8.6, haz una foto de cada deprecación que se origine en código de vendor y acepta esa lista como deuda conocida. La barrera entonces solo falla ante el crecimiento: una deprecación nueva, o una que empieza a dispararse desde un sitio nuevo. Cada composer update es una oportunidad de encoger el fichero, y encogerlo sienta bien de una manera que mirar dashboards de logs nunca conseguirá. Mientras tanto, producción deja de registrar E_DEPRECATED por completo. No pierdes nada silenciándolo ahí, porque a diferencia de un timeout o una condición de carrera, una deprecación no lleva ningún contexto de runtime que merezca observarse.
Nada de esto dice que tengas que migrar este trimestre. PHP 8.5 seguirá mantenido durante años, y una deprecación no tiene fecha límite hasta que la eliminación se publica de verdad. Aun así, yo levantaría pronto una rama desechable contra 8.6, simplemente porque el inventario cuesta una tarde ahora y una revisión de incidente después. La única pregunta que no he terminado de resolver para mí es la cola terca: una deprecación de vendor donde upstream no responde y no existe ninguna release alternativa. ¿La dejas en el baseline indefinidamente, cargas con un composer patch, o lo tomas como la señal para sustituir el paquete? Me gustaría de verdad saber dónde traza tu equipo esa línea.
Comentarios
Aún no hay comentarios — escribe el primero.
Inicia la conversación
Sin cuenta ni contraseña — introduce tu correo y te enviamos un enlace de acceso de un solo uso. ¿Primera vez? Todo se configura automáticamente.
Tu valoración se aplicará automáticamente al iniciar sesión.
Revisa tu bandeja de entrada
Hemos enviado un enlace de acceso a …. Ábrelo en este dispositivo — esta pestaña te conectará automáticamente.
¿No llega nada? Mira en la carpeta de spam — y marca el correo como «No es spam» para que la próxima vez llegue directo.