[{"data":1,"prerenderedAt":4503},["ShallowReactive",2],{"es-main-blog_es-\u002Fes\u002Fblog\u002Fapt-install-php-85-on-ubuntu-26\u002F":3,"es-alternative-blog_en-\u002Fblog\u002Fapt-install-php-85-on-ubuntu-26":2480,"blog_es-related-\u002Fes\u002Fblog\u002Fapt-install-php-85-on-ubuntu-26\u002F":4449},{"id":4,"title":5,"body":6,"date":2467,"description":2468,"extension":2469,"image":2470,"meta":2471,"navigation":793,"path":2472,"readingTime":2473,"schemaOrg":2470,"seo":2474,"stem":2475,"tags":2476,"toc":2478,"updatedAt":2470,"__hash__":2479},"blog_es\u002Fes\u002Fblog\u002F0005.apt-install-php-85-on-ubuntu-26.md","Instalar PHP 8.5 con apt en Ubuntu 26.04",{"type":7,"value":8,"toc":2450},"minimark",[9,19,35,68,84,89,98,178,192,200,204,213,253,256,374,378,406,417,438,448,452,463,485,499,505,532,536,539,544,577,584,588,638,656,660,681,804,808,838,885,894,909,913,927,955,959,968,1137,1155,1159,1169,1211,1226,1233,1239,1243,1249,1270,2317,2321,2324,2372,2381,2415,2433,2446],[10,11,12,13,18],"p",{},"Ayer subí cómo ",[14,15,17],"a",{"href":16},"\u002Fes\u002Fblog\u002Fapt-install-node-26-on-ubuntu-26\u002F","instalar Node.js 26 con apt"," para que el sistema operativo lo mantenga parcheado tras las actualizaciones de seguridad de octubre. Hoy le toca a PHP, por el mismo motivo: las brechas de seguridad no dan tregua, y PHP también ha tenido lo suyo.",[10,20,21,22,28,29,34],{},"El 24 de septiembre, ",[14,23,27],{"href":24,"rel":25},"https:\u002F\u002Fwww.php.net\u002FChangeLog-8.php#8.5.11",[26],"nofollow","PHP 8.5.11"," corrigió más de diez CVE en OpenSSL, FPM, SOAP, Phar y el wrapper de streams HTTP, entre ellos un desbordamiento de buffer en el heap y un fallo que se saltaba la verificación del hostname en TLS. El 21 de octubre, ",[14,30,33],{"href":31,"rel":32},"https:\u002F\u002Fwww.php.net\u002Farchive\u002F2026.php#2026-10-21-4",[26],"PHP 8.5.12"," fue más allá: una release de emergencia para dos vulnerabilidades críticas (CVE-2026-109618 y CVE-2026-109619, CVSS 9.2) que permiten ejecutar código en remoto sin autenticación. Según el propio php.net, \"actualizar es la única opción segura\". Las ramas 8.4, 8.3 y 8.2 recibieron las mismas correcciones.",[10,36,37,38,43,44,48,49,53,54,57,58,63,64,67],{},"Aquí viene la trampa: ",[14,39,42],{"href":40,"rel":41},"https:\u002F\u002Fdocumentation.ubuntu.com\u002Frelease-notes\u002F26.04\u002F",[26],"Ubuntu 26.04 LTS"," (",[45,46,47],"em",{},"Resolute Raccoon",") incluye PHP 8.5 en sus repositorios, pero congela la versión en el momento del lanzamiento y le aplica por encima los parches que considera importantes. Mientras escribo esto, ",[50,51,52],"code",{},"apt"," te instala PHP ",[50,55,56],{},"8.5.4"," con parches, y ",[14,59,62],{"href":60,"rel":61},"https:\u002F\u002Fwww.php.net\u002F",[26],"php.net"," ya va por la ",[50,65,66],{},"8.5.12",". Para ser justos, el equipo de seguridad de Ubuntu responde bien a lo urgente: publicó los parches de los RCE de octubre el mismo día que php.net. Pero la tanda de septiembre tardó 25 días en llegar, y las correcciones de bugs normales de upstream rara vez llegan.",[10,69,70,71,73,74,79,80,83],{},"Si quieres la versión completa de upstream, lo más sencillo sigue siendo que el propio sistema operativo se encargue. Instala PHP con ",[50,72,52],{}," desde el ",[14,75,78],{"href":76,"rel":77},"https:\u002F\u002Fdeb.sury.org\u002F",[26],"repositorio de Ondřej Surý",", los mismos paquetes que llevan más de una década dando vida a PHP en Debian y Ubuntu, y deja que ",[50,81,82],{},"sudo apt upgrade"," haga el resto.",[85,86,88],"h2",{"id":87},"fechas-de-soporte-de-un-vistazo","Fechas de soporte de un vistazo",[10,90,91,92,97],{},"Cada rama de PHP tiene dos años de soporte activo y otros dos solo con correcciones de seguridad. Así está el panorama según la ",[14,93,96],{"href":94,"rel":95},"https:\u002F\u002Fwww.php.net\u002Fsupported-versions.php",[26],"página oficial de versiones soportadas",":",[99,100,101,120],"table",{},[102,103,104],"thead",{},[105,106,107,111,114,117],"tr",{},[108,109,110],"th",{},"Versión",[108,112,113],{},"Publicada",[108,115,116],{},"Soporte activo hasta",[108,118,119],{},"Soporte de seguridad hasta",[121,122,123,138,152,165],"tbody",{},[105,124,125,129,132,135],{},[126,127,128],"td",{},"8.2",[126,130,131],{},"8 de diciembre de 2022",[126,133,134],{},"31 de diciembre de 2024",[126,136,137],{},"31 de diciembre de 2026",[105,139,140,143,146,149],{},[126,141,142],{},"8.3",[126,144,145],{},"23 de noviembre de 2023",[126,147,148],{},"31 de diciembre de 2025",[126,150,151],{},"31 de diciembre de 2027",[105,153,154,157,160,162],{},[126,155,156],{},"8.4",[126,158,159],{},"21 de noviembre de 2024",[126,161,137],{},[126,163,164],{},"31 de diciembre de 2028",[105,166,167,170,173,175],{},[126,168,169],{},"8.5",[126,171,172],{},"20 de noviembre de 2025",[126,174,151],{},[126,176,177],{},"31 de diciembre de 2029",[10,179,180,181,186,187,191],{},"Si sigues en PHP 8.2, te quedan menos de dos meses. ",[14,182,185],{"href":183,"rel":184},"https:\u002F\u002Fwiki.php.net\u002Ftodo\u002Fphp86",[26],"PHP 8.6"," está previsto para el 19 de noviembre de 2026, pero hoy PHP 8.5 es la apuesta segura para acompañar a una distribución LTS. Siempre puedes probar la 8.6 en paralelo (lo vemos ",[14,188,190],{"href":189},"#y-otras-versiones-de-php","más abajo",").",[10,193,194,195,199],{},"En cuanto al sistema operativo, ",[14,196,42],{"href":197,"rel":198},"https:\u002F\u002Fubuntu.com\u002Fabout\u002Frelease-cycle",[26]," salió en abril de 2026 y tiene mantenimiento de seguridad estándar hasta mayo de 2031, ampliable hasta 2036 con Ubuntu Pro. Así que esta instalación te va a durar una buena temporada.",[85,201,203],{"id":202},"novedades-de-php-85","Novedades de PHP 8.5",[10,205,206,207,212],{},"Si vienes de PHP 8.4 o anterior, hay motivos para actualizar más allá de la seguridad. El ",[14,208,211],{"href":209,"rel":210},"https:\u002F\u002Fwww.php.net\u002Freleases\u002F8.5\u002Fes.php",[26],"anuncio oficial"," tiene la lista completa, pero mis novedades favoritas son:",[214,215,216,220,230,237,243],"ul",{},[217,218,219],"li",{},"El operador pipe, para encadenar callables de izquierda a derecha sin variables temporales.",[217,221,222,225,226,229],{},[50,223,224],{},"clone()"," con propiedades, que resuelve en una sola línea el patrón \"with-er\" de las clases ",[50,227,228],{},"readonly",".",[217,231,232,233,236],{},"El atributo ",[50,234,235],{},"#[\\NoDiscard]",", que avisa cuando alguien ignora un valor de retorno que importa.",[217,238,239,240,229],{},"Una extensión URI nativa, con parseo de URL compatible con RFC 3986 y WHATWG, sin más sorpresas con ",[50,241,242],{},"parse_url()",[217,244,245,248,249,252],{},[50,246,247],{},"array_first()"," y ",[50,250,251],{},"array_last()",". Por fin.",[10,254,255],{},"Así queda el operador pipe convirtiendo un título en un slug:",[257,258,263],"pre",{"className":259,"code":260,"language":261,"meta":262,"style":262},"language-php shiki shiki-themes catppuccin-latte catppuccin-mocha","$slug = $title\n    |> trim(...)\n    |> (fn (string $str): string => str_replace(' ', '-', $str))\n    |> strtolower(...);\n","php","",[50,264,265,281,301,359],{"__ignoreMap":262},[266,267,270,274,278],"span",{"class":268,"line":269},"line",1,[266,271,273],{"class":272},"s0aCy","$slug ",[266,275,277],{"class":276},"sjJjI","=",[266,279,280],{"class":272}," $title\n",[266,282,284,287,291,295,298],{"class":268,"line":283},2,[266,285,286],{"class":276},"    |>",[266,288,290],{"class":289},"sMmZK"," trim",[266,292,294],{"class":293},"sxyLT","(",[266,296,297],{"class":276},"...",[266,299,300],{"class":293},")\n",[266,302,304,306,308,312,314,317,321,325,328,330,333,336,339,341,345,348,351,353,356],{"class":268,"line":303},3,[266,305,286],{"class":276},[266,307,43],{"class":293},[266,309,311],{"class":310},"sAS4m","fn",[266,313,43],{"class":293},[266,315,316],{"class":310},"string",[266,318,320],{"class":319},"seXix"," $",[266,322,324],{"class":323},"s2f33","str",[266,326,327],{"class":293},")",[266,329,97],{"class":276},[266,331,332],{"class":310}," string",[266,334,335],{"class":293}," =>",[266,337,338],{"class":289}," str_replace",[266,340,294],{"class":293},[266,342,344],{"class":343},"sgueU","' '",[266,346,347],{"class":293},",",[266,349,350],{"class":343}," '-'",[266,352,347],{"class":293},[266,354,355],{"class":272}," $str",[266,357,358],{"class":293},"))\n",[266,360,362,364,367,369,371],{"class":268,"line":361},4,[266,363,286],{"class":276},[266,365,366],{"class":289}," strtolower",[266,368,294],{"class":293},[266,370,297],{"class":276},[266,372,373],{"class":293},");\n",[85,375,377],{"id":376},"qué-ha-cambiado-adiós-ppa-hola-packagessuryorg","Qué ha cambiado: adiós PPA, hola packages.sury.org",[10,379,380,381,384,385,390,391,396,397,400,401,405],{},"Si ya has instalado PHP en Ubuntu alguna vez, seguramente usaste ",[50,382,383],{},"add-apt-repository ppa:ondrej\u002Fphp",". Eso ya no es lo recomendable: Ondřej Surý está trasladando sus paquetes de Ubuntu desde ",[14,386,389],{"href":387,"rel":388},"https:\u002F\u002Flaunchpad.net\u002F~ondrej\u002F+archive\u002Fubuntu\u002Fphp",[26],"Launchpad"," a ",[14,392,395],{"href":393,"rel":394},"https:\u002F\u002Fpackages.sury.org\u002Fphp\u002F",[26],"packages.sury.org",", el servidor que ya alojaba los de Debian. Los paquetes de ",[50,398,399],{},"resolute"," para Ubuntu 26.04 se publican ",[402,403,404],"strong",{},"solo"," ahí.",[10,407,408,409,412,413,416],{},"Si todavía tienes el PPA configurado, puede que este verano ",[50,410,411],{},"apt update"," se quejara de que el repositorio había cambiado su valor 'Label', un error que hacía fallar ",[50,414,415],{},"apt-get update"," en scripts hasta aceptar el cambio. De momento el PPA sigue recibiendo actualizaciones para Ubuntu 22.04 y 24.04, pero se está fusionando con packages.sury.org. Y si tienes los dos configurados, apt sigue prefiriendo los paquetes del PPA, así que elimínalo antes de seguir los pasos de abajo:",[257,418,422],{"className":419,"code":420,"language":421,"meta":262,"style":262},"language-bash shiki shiki-themes catppuccin-latte catppuccin-mocha","sudo add-apt-repository --remove ppa:ondrej\u002Fphp\n","bash",[50,423,424],{"__ignoreMap":262},[266,425,426,429,432,435],{"class":268,"line":269},[266,427,428],{"class":289},"sudo",[266,430,431],{"class":343}," add-apt-repository",[266,433,434],{"class":343}," --remove",[266,436,437],{"class":343}," ppa:ondrej\u002Fphp\n",[10,439,440,441,444,445,229],{},"El nuevo método también mejora la gestión de la clave de firma. En lugar de descargar un fichero ",[50,442,443],{},".gpg"," a pelo, instalas el paquete oficial ",[50,446,447],{},"debsuryorg-archive-keyring",[85,449,451],{"id":450},"la-vía-fácil","La vía fácil",[10,453,454,455,457,458,229],{},"Como de costumbre, puedes instalarlo todo con un solo comando. El script añade el repositorio de Sury, instala PHP 8.5 con las extensiones más habituales, lo configura como ",[50,456,261],{}," por defecto y, opcionalmente, instala ",[14,459,462],{"href":460,"rel":461},"https:\u002F\u002Fgetcomposer.org\u002F",[26],"Composer",[257,464,466],{"className":419,"code":465,"language":421,"meta":262,"style":262},"curl -fsSL https:\u002F\u002Fangelblanco.dev\u002Fscripts\u002Fubuntu-install-php-85.sh | bash\n",[50,467,468],{"__ignoreMap":262},[266,469,470,473,476,479,482],{"class":268,"line":269},[266,471,472],{"class":289},"curl",[266,474,475],{"class":343}," -fsSL",[266,477,478],{"class":343}," https:\u002F\u002Fangelblanco.dev\u002Fscripts\u002Fubuntu-install-php-85.sh",[266,480,481],{"class":276}," |",[266,483,484],{"class":289}," bash\n",[10,486,487,488,492,493,495,496,498],{},"El script te pide confirmación en cada paso importante. Como siempre, lee ",[14,489,491],{"href":490},"#el-script","el script"," antes de pasárselo a ",[50,494,421],{},". Fiarse de URL aleatorias con ",[50,497,428],{}," es una forma estupenda de aprender a gestionar incidentes.",[10,500,501,502,504],{},"Si no tienes ",[50,503,472],{}," instalado:",[257,506,508],{"className":419,"code":507,"language":421,"meta":262,"style":262},"sudo apt update\nsudo apt install curl\n",[50,509,510,520],{"__ignoreMap":262},[266,511,512,514,517],{"class":268,"line":269},[266,513,428],{"class":289},[266,515,516],{"class":343}," apt",[266,518,519],{"class":343}," update\n",[266,521,522,524,526,529],{"class":268,"line":283},[266,523,428],{"class":289},[266,525,516],{"class":343},[266,527,528],{"class":343}," install",[266,530,531],{"class":343}," curl\n",[85,533,535],{"id":534},"la-guía-paso-a-paso","La guía paso a paso",[10,537,538],{},"Esto es lo que hace el script, por si prefieres ir paso a paso.",[540,541,543],"h3",{"id":542},"_1-instalar-los-requisitos-previos","1. Instalar los requisitos previos",[257,545,547],{"className":419,"code":546,"language":421,"meta":262,"style":262},"sudo apt update\nsudo apt install -y ca-certificates curl unzip\n",[50,548,549,557],{"__ignoreMap":262},[266,550,551,553,555],{"class":268,"line":269},[266,552,428],{"class":289},[266,554,516],{"class":343},[266,556,519],{"class":343},[266,558,559,561,563,565,568,571,574],{"class":268,"line":283},[266,560,428],{"class":289},[266,562,516],{"class":343},[266,564,528],{"class":343},[266,566,567],{"class":343}," -y",[266,569,570],{"class":343}," ca-certificates",[266,572,573],{"class":343}," curl",[266,575,576],{"class":343}," unzip\n",[10,578,579,580,583],{},"PHP no necesita ",[50,581,582],{},"unzip",", pero Composer lo usa para descomprimir paquetes mucho más rápido que con su alternativa en PHP.",[540,585,587],{"id":586},"_2-instalar-la-clave-de-firma-de-sury","2. Instalar la clave de firma de Sury",[257,589,591],{"className":419,"code":590,"language":421,"meta":262,"style":262},"curl -fsSLo \u002Ftmp\u002Fdebsuryorg-archive-keyring.deb https:\u002F\u002Fpackages.sury.org\u002Fdebsuryorg-archive-keyring.deb \\\n  && sudo dpkg -i \u002Ftmp\u002Fdebsuryorg-archive-keyring.deb \\\n  && rm \u002Ftmp\u002Fdebsuryorg-archive-keyring.deb\n",[50,592,593,610,628],{"__ignoreMap":262},[266,594,595,597,600,603,606],{"class":268,"line":269},[266,596,472],{"class":289},[266,598,599],{"class":343}," -fsSLo",[266,601,602],{"class":343}," \u002Ftmp\u002Fdebsuryorg-archive-keyring.deb",[266,604,605],{"class":343}," https:\u002F\u002Fpackages.sury.org\u002Fdebsuryorg-archive-keyring.deb",[266,607,609],{"class":608},"sNVtu"," \\\n",[266,611,612,615,618,621,624,626],{"class":268,"line":283},[266,613,614],{"class":293},"  &&",[266,616,617],{"class":289}," sudo",[266,619,620],{"class":343}," dpkg",[266,622,623],{"class":343}," -i",[266,625,602],{"class":343},[266,627,609],{"class":608},[266,629,630,632,635],{"class":268,"line":303},[266,631,614],{"class":293},[266,633,634],{"class":289}," rm",[266,636,637],{"class":343}," \u002Ftmp\u002Fdebsuryorg-archive-keyring.deb\n",[10,639,640,641,644,645,648,649,652,653,229],{},"Esto deja la clave en ",[50,642,643],{},"\u002Fusr\u002Fshare\u002Fkeyrings\u002Fdebsuryorg-archive-keyring.gpg"," (y, de momento, una copia global en ",[50,646,647],{},"\u002Fetc\u002Fapt\u002Ftrusted.gpg.d\u002F","). En Debian el repositorio también publica el paquete del keyring, así que las renovaciones llegan con ",[50,650,651],{},"apt upgrade",". En las suites de Ubuntu todavía no está, así que si algún día se renueva la clave, vuelve a descargar e instalar el ",[50,654,655],{},".deb",[540,657,659],{"id":658},"_3-añadir-el-repositorio-de-sury","3. Añadir el repositorio de Sury",[10,661,662,663,668,669,672,673,676,677,680],{},"Desde la 24.04, Ubuntu usa el ",[14,664,667],{"href":665,"rel":666},"https:\u002F\u002Fmanpages.ubuntu.com\u002Fmanpages\u002Fresolute\u002Fman5\u002Fsources.list.5.html",[26],"formato deb822"," (ficheros ",[50,670,671],{},".sources",") para sus propios repositorios, y el formato clásico ",[50,674,675],{},".list"," de una línea ya está oficialmente obsoleto. El nombre en clave se lee de ",[50,678,679],{},"\u002Fetc\u002Fos-release",", así que el mismo fragmento funciona también en Ubuntu 22.04 y 24.04, y en derivadas como Linux Mint.",[257,682,684],{"className":419,"code":683,"language":421,"meta":262,"style":262},"sudo tee \u002Fetc\u002Fapt\u002Fsources.list.d\u002Fphp.sources > \u002Fdev\u002Fnull \u003C\u003CEOF\nTypes: deb\nURIs: https:\u002F\u002Fpackages.sury.org\u002Fphp\u002F\nSuites: $(. \u002Fetc\u002Fos-release && echo \"${UBUNTU_CODENAME:-$VERSION_CODENAME}\")\nComponents: main\nArchitectures: $(dpkg --print-architecture)\nSigned-By: \u002Fusr\u002Fshare\u002Fkeyrings\u002Fdebsuryorg-archive-keyring.gpg\nEOF\n\nsudo apt update\n",[50,685,686,708,713,718,755,761,777,783,788,795],{"__ignoreMap":262},[266,687,688,690,693,696,699,702,705],{"class":268,"line":269},[266,689,428],{"class":289},[266,691,692],{"class":343}," tee",[266,694,695],{"class":343}," \u002Fetc\u002Fapt\u002Fsources.list.d\u002Fphp.sources",[266,697,698],{"class":276}," >",[266,700,701],{"class":343}," \u002Fdev\u002Fnull",[266,703,704],{"class":276}," \u003C\u003C",[266,706,707],{"class":343},"EOF\n",[266,709,710],{"class":268,"line":283},[266,711,712],{"class":343},"Types: deb\n",[266,714,715],{"class":268,"line":303},[266,716,717],{"class":343},"URIs: https:\u002F\u002Fpackages.sury.org\u002Fphp\u002F\n",[266,719,720,723,726,729,732,735,738,741,744,747,750,753],{"class":268,"line":361},[266,721,722],{"class":343},"Suites: ",[266,724,725],{"class":293},"$(",[266,727,229],{"class":728},"s-0VM",[266,730,731],{"class":343}," \u002Fetc\u002Fos-release ",[266,733,734],{"class":293},"&&",[266,736,737],{"class":728}," echo",[266,739,740],{"class":343}," \"",[266,742,743],{"class":272},"${UBUNTU_CODENAME",[266,745,746],{"class":276},":-",[266,748,749],{"class":272},"$VERSION_CODENAME}",[266,751,752],{"class":343},"\"",[266,754,300],{"class":293},[266,756,758],{"class":268,"line":757},5,[266,759,760],{"class":343},"Components: main\n",[266,762,764,767,769,772,775],{"class":268,"line":763},6,[266,765,766],{"class":343},"Architectures: ",[266,768,725],{"class":293},[266,770,771],{"class":289},"dpkg",[266,773,774],{"class":343}," --print-architecture",[266,776,300],{"class":293},[266,778,780],{"class":268,"line":779},7,[266,781,782],{"class":343},"Signed-By: \u002Fusr\u002Fshare\u002Fkeyrings\u002Fdebsuryorg-archive-keyring.gpg\n",[266,784,786],{"class":268,"line":785},8,[266,787,707],{"class":343},[266,789,791],{"class":268,"line":790},9,[266,792,794],{"emptyLinePlaceholder":793},true,"\n",[266,796,798,800,802],{"class":268,"line":797},10,[266,799,428],{"class":289},[266,801,516],{"class":343},[266,803,519],{"class":343},[540,805,807],{"id":806},"_4-instalar-php-85","4. Instalar PHP 8.5",[257,809,811],{"className":419,"code":810,"language":421,"meta":262,"style":262},"sudo apt install -y php8.5-cli php8.5-mbstring php8.5-curl php8.5-zip php8.5-xml\n",[50,812,813],{"__ignoreMap":262},[266,814,815,817,819,821,823,826,829,832,835],{"class":268,"line":269},[266,816,428],{"class":289},[266,818,516],{"class":343},[266,820,528],{"class":343},[266,822,567],{"class":343},[266,824,825],{"class":343}," php8.5-cli",[266,827,828],{"class":343}," php8.5-mbstring",[266,830,831],{"class":343}," php8.5-curl",[266,833,834],{"class":343}," php8.5-zip",[266,836,837],{"class":343}," php8.5-xml\n",[10,839,840,841,844,845,848,849,854,855,862,863,868,869,874,875,878,879,868,882,229],{},"Fíjate en que instalamos ",[50,842,843],{},"php8.5-cli"," y no el metapaquete ",[50,846,847],{},"php8.5"," a secas. El metapaquete arrastra ",[14,850,853],{"href":851,"rel":852},"https:\u002F\u002Fhttpd.apache.org\u002F",[26],"Apache"," y su módulo de PHP, que seguramente no quieres en tu máquina de desarrollo. Si necesitas un servidor web, añade ",[14,856,859],{"href":857,"rel":858},"https:\u002F\u002Fwww.php.net\u002Fmanual\u002Fes\u002Finstall.fpm.php",[26],[50,860,861],{},"php8.5-fpm"," y combínalo con ",[14,864,867],{"href":865,"rel":866},"https:\u002F\u002Fnginx.org\u002F",[26],"Nginx"," o ",[14,870,873],{"href":871,"rel":872},"https:\u002F\u002Fcaddyserver.com\u002F",[26],"Caddy",". ¿Base de datos? Añade ",[50,876,877],{},"php8.5-mysql",", ",[50,880,881],{},"php8.5-pgsql",[50,883,884],{},"php8.5-sqlite3",[10,886,887,888,890,891,893],{},"No hace falta fijar prioridades en apt: la ",[50,889,66],{}," de Sury tiene una versión mayor que la ",[50,892,56],{}," de Ubuntu, así que apt la elige automáticamente. Puedes comprobar de dónde viene cada paquete con:",[257,895,897],{"className":419,"code":896,"language":421,"meta":262,"style":262},"apt policy php8.5-cli\n",[50,898,899],{"__ignoreMap":262},[266,900,901,903,906],{"class":268,"line":269},[266,902,52],{"class":289},[266,904,905],{"class":343}," policy",[266,907,908],{"class":343}," php8.5-cli\n",[540,910,912],{"id":911},"_5-configurar-php-85-por-defecto","5. Configurar PHP 8.5 por defecto",[10,914,915,916,918,919,926],{},"El comando ",[50,917,261],{}," se gestiona con ",[14,920,923],{"href":921,"rel":922},"https:\u002F\u002Fmanpages.ubuntu.com\u002Fmanpages\u002Fresolute\u002Fman1\u002Fupdate-alternatives.1.html",[26],[50,924,925],{},"update-alternatives",", así que puedes elegir qué versión responde a él:",[257,928,930],{"className":419,"code":929,"language":421,"meta":262,"style":262},"sudo update-alternatives --set php \u002Fusr\u002Fbin\u002Fphp8.5\nphp --version\n",[50,931,932,948],{"__ignoreMap":262},[266,933,934,936,939,942,945],{"class":268,"line":269},[266,935,428],{"class":289},[266,937,938],{"class":343}," update-alternatives",[266,940,941],{"class":343}," --set",[266,943,944],{"class":343}," php",[266,946,947],{"class":343}," \u002Fusr\u002Fbin\u002Fphp8.5\n",[266,949,950,952],{"class":268,"line":283},[266,951,261],{"class":289},[266,953,954],{"class":343}," --version\n",[540,956,958],{"id":957},"_6-instalar-composer","6. Instalar Composer",[10,960,961,962,967],{},"El ",[14,963,966],{"href":964,"rel":965},"https:\u002F\u002Fgetcomposer.org\u002Fdownload\u002F",[26],"instalador oficial"," publica un checksum SHA-384, así que verifícalo antes de ejecutar nada:",[257,969,971],{"className":419,"code":970,"language":421,"meta":262,"style":262},"EXPECTED_CHECKSUM=\"$(curl -fsSL https:\u002F\u002Fcomposer.github.io\u002Finstaller.sig)\"\ncurl -fsSLo composer-setup.php https:\u002F\u002Fgetcomposer.org\u002Finstaller\nACTUAL_CHECKSUM=\"$(php -r \"echo hash_file('sha384', 'composer-setup.php');\")\"\n\nif [ \"$EXPECTED_CHECKSUM\" = \"$ACTUAL_CHECKSUM\" ]; then\n    php composer-setup.php --quiet\n    sudo install -m 0755 composer.phar \u002Fusr\u002Flocal\u002Fbin\u002Fcomposer\n    rm composer.phar\n    composer --version\nelse\n    >&2 echo \"ERROR: checksum del instalador de Composer no válido\"\nfi\nrm composer-setup.php\n",[50,972,973,994,1006,1026,1030,1061,1071,1091,1099,1106,1111,1122,1128],{"__ignoreMap":262},[266,974,975,978,980,982,984,986,989,991],{"class":268,"line":269},[266,976,977],{"class":272},"EXPECTED_CHECKSUM",[266,979,277],{"class":276},[266,981,752],{"class":343},[266,983,725],{"class":293},[266,985,472],{"class":289},[266,987,988],{"class":343}," -fsSL https:\u002F\u002Fcomposer.github.io\u002Finstaller.sig",[266,990,327],{"class":293},[266,992,993],{"class":343},"\"\n",[266,995,996,998,1000,1003],{"class":268,"line":283},[266,997,472],{"class":289},[266,999,599],{"class":343},[266,1001,1002],{"class":343}," composer-setup.php",[266,1004,1005],{"class":343}," https:\u002F\u002Fgetcomposer.org\u002Finstaller\n",[266,1007,1008,1011,1013,1015,1017,1019,1022,1024],{"class":268,"line":303},[266,1009,1010],{"class":272},"ACTUAL_CHECKSUM",[266,1012,277],{"class":276},[266,1014,752],{"class":343},[266,1016,725],{"class":293},[266,1018,261],{"class":289},[266,1020,1021],{"class":343}," -r \"echo hash_file('sha384', 'composer-setup.php');\"",[266,1023,327],{"class":293},[266,1025,993],{"class":343},[266,1027,1028],{"class":268,"line":361},[266,1029,794],{"emptyLinePlaceholder":793},[266,1031,1032,1035,1038,1040,1043,1045,1048,1050,1053,1055,1058],{"class":268,"line":757},[266,1033,1034],{"class":310},"if",[266,1036,1037],{"class":293}," [",[266,1039,740],{"class":343},[266,1041,1042],{"class":272},"$EXPECTED_CHECKSUM",[266,1044,752],{"class":343},[266,1046,1047],{"class":276}," =",[266,1049,740],{"class":343},[266,1051,1052],{"class":272},"$ACTUAL_CHECKSUM",[266,1054,752],{"class":343},[266,1056,1057],{"class":293}," ];",[266,1059,1060],{"class":310}," then\n",[266,1062,1063,1066,1068],{"class":268,"line":763},[266,1064,1065],{"class":289},"    php",[266,1067,1002],{"class":343},[266,1069,1070],{"class":343}," --quiet\n",[266,1072,1073,1076,1078,1081,1085,1088],{"class":268,"line":779},[266,1074,1075],{"class":289},"    sudo",[266,1077,528],{"class":343},[266,1079,1080],{"class":343}," -m",[266,1082,1084],{"class":1083},"st0oN"," 0755",[266,1086,1087],{"class":343}," composer.phar",[266,1089,1090],{"class":343}," \u002Fusr\u002Flocal\u002Fbin\u002Fcomposer\n",[266,1092,1093,1096],{"class":268,"line":785},[266,1094,1095],{"class":289},"    rm",[266,1097,1098],{"class":343}," composer.phar\n",[266,1100,1101,1104],{"class":268,"line":790},[266,1102,1103],{"class":289},"    composer",[266,1105,954],{"class":343},[266,1107,1108],{"class":268,"line":797},[266,1109,1110],{"class":310},"else\n",[266,1112,1114,1117,1119],{"class":268,"line":1113},11,[266,1115,1116],{"class":276},"    >&2",[266,1118,737],{"class":728},[266,1120,1121],{"class":343}," \"ERROR: checksum del instalador de Composer no válido\"\n",[266,1123,1125],{"class":268,"line":1124},12,[266,1126,1127],{"class":310},"fi\n",[266,1129,1131,1134],{"class":268,"line":1130},13,[266,1132,1133],{"class":289},"rm",[266,1135,1136],{"class":343}," composer-setup.php\n",[10,1138,1139,1140,1143,1144,1147,1148,1151,1152,229],{},"Usar ",[50,1141,1142],{},"install"," en lugar de ",[50,1145,1146],{},"mv"," deja el binario a nombre de ",[50,1149,1150],{},"root",", algo importante porque más adelante ejecutarás ",[50,1153,1154],{},"sudo composer self-update",[85,1156,1158],{"id":1157},"y-otras-versiones-de-php","¿Y otras versiones de PHP?",[10,1160,1161,1162,1165,1166,1168],{},"Aquí es donde el repositorio de Sury brilla de verdad. Publica todas las ramas desde ",[50,1163,1164],{},"php5.6"," hasta ",[50,1167,847],{},", además de las release candidates de PHP 8.6, y pueden convivir todas a la vez:",[257,1170,1172],{"className":419,"code":1171,"language":421,"meta":262,"style":262},"sudo apt install -y php8.4-cli php8.4-mbstring php8.4-curl php8.4-zip php8.4-xml\nsudo update-alternatives --config php\n",[50,1173,1174,1199],{"__ignoreMap":262},[266,1175,1176,1178,1180,1182,1184,1187,1190,1193,1196],{"class":268,"line":269},[266,1177,428],{"class":289},[266,1179,516],{"class":343},[266,1181,528],{"class":343},[266,1183,567],{"class":343},[266,1185,1186],{"class":343}," php8.4-cli",[266,1188,1189],{"class":343}," php8.4-mbstring",[266,1191,1192],{"class":343}," php8.4-curl",[266,1194,1195],{"class":343}," php8.4-zip",[266,1197,1198],{"class":343}," php8.4-xml\n",[266,1200,1201,1203,1205,1208],{"class":268,"line":283},[266,1202,428],{"class":289},[266,1204,938],{"class":343},[266,1206,1207],{"class":343}," --config",[266,1209,1210],{"class":343}," php\n",[10,1212,1213,1216,1217,1219,1220,868,1223,1225],{},[50,1214,1215],{},"update-alternatives --config php"," muestra un menú interactivo para cambiar el ",[50,1218,261],{}," por defecto. También puedes llamar directamente a una versión concreta con ",[50,1221,1222],{},"php8.4",[50,1224,847],{},", algo muy práctico para pasar los tests de un proyecto antiguo sin tocar tu versión por defecto.",[10,1227,1228,1229,1232],{},"Si pruebas la 8.6 antes de la versión final del 19 de noviembre, revisa ",[50,1230,1231],{},"apt policy php8.6-cli",": las builds anteriores a la RC4 no incluyen los parches de los RCE de octubre.",[10,1234,1235,1236,1238],{},"Ten en cuenta que cada versión que instalas es una más que tienes que mantener parcheada. Con Sury, al menos, ",[50,1237,651],{}," las parchea todas de una vez.",[85,1240,1242],{"id":1241},"el-script","El script",[10,1244,1245,1246,1248],{},"Este es el script completo. Incluye confirmaciones, usa un directorio temporal que se borra al terminar y lee tus respuestas desde la terminal, así que funciona cuando lo ejecutas con ",[50,1247,472],{},". Puedes cambiar la versión de PHP y las extensiones con las variables del principio.",[10,1250,1251,1252,1257,1258,1263,1264,248,1266,1269],{},"Este script sale de mi ",[14,1253,1256],{"href":1254,"rel":1255},"https:\u002F\u002Fgithub.com\u002Fangelblanco\u002Fkickstart.nvim",[26],"repo de configuración de Neovim",", donde guardo mis ",[14,1259,1262],{"href":1260,"rel":1261},"https:\u002F\u002Fgithub.com\u002Fangelblanco\u002Fkickstart.nvim\u002Fblob\u002Fmaster\u002Finstall\u002Finstall-php.sh",[26],"scripts de instalación",". El editor necesita ",[50,1265,261],{},[50,1267,1268],{},"composer"," para que funcionen los language servers y formateadores de PHP, así que los actualizo con frecuencia. Si quieres la versión más reciente, pásate por allí.",[257,1271,1274],{"className":419,"code":1272,"filename":1273,"language":421,"meta":262,"style":262},"#!\u002Fbin\u002Fbash\n#\n# Author: Ángel Blanco\n# License: MIT\n#\n# This script is provided \"as is\", without warranty of any kind. Use at your own risk.\n#\n# Source: https:\u002F\u002Fangelblanco.dev\u002Fblog\u002Fapt-install-php-85-on-ubuntu-26\n#\n# Usage:\n#   curl -fsSL https:\u002F\u002Fangelblanco.dev\u002Fscripts\u002Fubuntu-install-php-85.sh | bash\n#\n# Install PHP (from packages.sury.org) and Composer on Ubuntu.\n# Normally you will call it from your non-root user; elevated permissions\n# will be granted with sudo.\n#\n\nset -euo pipefail\n\n# You can configure these variables if needed\nPHP_VERSION=\"8.5\"\nPHP_EXTENSIONS=\"cli mbstring curl zip xml\"\nKEYRING=\"\u002Fusr\u002Fshare\u002Fkeyrings\u002Fdebsuryorg-archive-keyring.gpg\"\nSOURCE_FILE=\"\u002Fetc\u002Fapt\u002Fsources.list.d\u002Fphp.sources\"\n\n# Basic confirmation module before executing the script.\nconfirm_action() {\n    while true; do\n        read -r -p \"$1 (y\u002Fn): \" choice \u003C \u002Fdev\u002Ftty\n        case \"$choice\" in\n            [Yy]|[Yy][Ee][Ss]) return 0 ;;\n            [Nn]|[Nn][Oo])     return 1 ;;\n            *)                 echo \"Invalid choice. Please enter 'y' or 'n'.\" ;;\n        esac\n    done\n}\n\nWORKDIR=\"$(mktemp -d)\"\ntrap 'rm -rf \"$WORKDIR\"' EXIT\n\nif ! confirm_action \"Install PHP $PHP_VERSION from packages.sury.org?\"; then\n    echo \"Skipping PHP installation. Exiting.\"\n    exit 0\nfi\n\n# --- Prerequisites ---------------------------------------------------------\nsudo apt update\nsudo apt install -y ca-certificates curl unzip\n\n# --- Sury signing key (official keyring package) ---------------------------\ncurl -fsSLo \"$WORKDIR\u002Fdebsuryorg-archive-keyring.deb\" https:\u002F\u002Fpackages.sury.org\u002Fdebsuryorg-archive-keyring.deb\nsudo dpkg -i \"$WORKDIR\u002Fdebsuryorg-archive-keyring.deb\"\n\n# --- Sury repository --------------------------------------------------------\nCODENAME=\"$(. \u002Fetc\u002Fos-release && echo \"${UBUNTU_CODENAME:-$VERSION_CODENAME}\")\"\n\nsudo tee \"$SOURCE_FILE\" > \u002Fdev\u002Fnull \u003C\u003CEOF\nTypes: deb\nURIs: https:\u002F\u002Fpackages.sury.org\u002Fphp\u002F\nSuites: $CODENAME\nComponents: main\nArchitectures: $(dpkg --print-architecture)\nSigned-By: $KEYRING\nEOF\n\nsudo apt update\n\n# --- PHP --------------------------------------------------------------------\n# Use -cli instead of the bare \"phpX.Y\" metapackage, which pulls in Apache.\nPACKAGES=\"\"\nfor EXTENSION in $PHP_EXTENSIONS; do\n    PACKAGES=\"$PACKAGES php${PHP_VERSION}-${EXTENSION}\"\ndone\n\n# shellcheck disable=SC2086\nsudo apt install -y $PACKAGES\n\nsudo update-alternatives --set php \"\u002Fusr\u002Fbin\u002Fphp${PHP_VERSION}\"\n\necho \"\"\nphp --version\necho \"\"\n\n# --- Composer ---------------------------------------------------------------\nif confirm_action \"Install Composer?\"; then\n    cd \"$WORKDIR\"\n\n    EXPECTED_CHECKSUM=\"$(curl -fsSL https:\u002F\u002Fcomposer.github.io\u002Finstaller.sig)\"\n    curl -fsSLo composer-setup.php https:\u002F\u002Fgetcomposer.org\u002Finstaller\n    ACTUAL_CHECKSUM=\"$(php -r \"echo hash_file('sha384', 'composer-setup.php');\")\"\n\n    if [ \"$EXPECTED_CHECKSUM\" != \"$ACTUAL_CHECKSUM\" ]; then\n        >&2 echo \"ERROR: Invalid Composer installer checksum\"\n        exit 1\n    fi\n\n    php composer-setup.php --quiet\n    sudo install -m 0755 composer.phar \u002Fusr\u002Flocal\u002Fbin\u002Fcomposer\n\n    echo \"\"\n    composer --version\nfi\n\necho \"\"\necho \"Installation process finished.\"\necho \"Run 'sudo apt update && sudo apt upgrade' periodically to get PHP security releases.\"\n","ubuntu-install-php-85.sh",[50,1275,1276,1282,1288,1293,1298,1302,1307,1311,1316,1320,1325,1330,1334,1339,1345,1351,1356,1361,1373,1378,1384,1395,1406,1417,1428,1433,1439,1451,1466,1495,1511,1555,1588,1602,1608,1614,1620,1625,1647,1659,1664,1688,1697,1706,1711,1716,1722,1731,1748,1753,1759,1777,1793,1798,1804,1838,1843,1865,1870,1875,1883,1888,1901,1910,1915,1920,1929,1934,1940,1946,1957,1976,2002,2008,2013,2019,2033,2038,2056,2061,2070,2077,2084,2089,2095,2109,2121,2126,2146,2158,2178,2183,2210,2221,2230,2236,2241,2250,2265,2270,2277,2284,2289,2294,2301,2309],{"__ignoreMap":262},[266,1277,1278],{"class":268,"line":269},[266,1279,1281],{"class":1280},"skWWU","#!\u002Fbin\u002Fbash\n",[266,1283,1284],{"class":268,"line":283},[266,1285,1287],{"class":1286},"som-u","#\n",[266,1289,1290],{"class":268,"line":303},[266,1291,1292],{"class":1286},"# Author: Ángel Blanco\n",[266,1294,1295],{"class":268,"line":361},[266,1296,1297],{"class":1286},"# License: MIT\n",[266,1299,1300],{"class":268,"line":757},[266,1301,1287],{"class":1286},[266,1303,1304],{"class":268,"line":763},[266,1305,1306],{"class":1286},"# This script is provided \"as is\", without warranty of any kind. Use at your own risk.\n",[266,1308,1309],{"class":268,"line":779},[266,1310,1287],{"class":1286},[266,1312,1313],{"class":268,"line":785},[266,1314,1315],{"class":1286},"# Source: https:\u002F\u002Fangelblanco.dev\u002Fblog\u002Fapt-install-php-85-on-ubuntu-26\n",[266,1317,1318],{"class":268,"line":790},[266,1319,1287],{"class":1286},[266,1321,1322],{"class":268,"line":797},[266,1323,1324],{"class":1286},"# Usage:\n",[266,1326,1327],{"class":268,"line":1113},[266,1328,1329],{"class":1286},"#   curl -fsSL https:\u002F\u002Fangelblanco.dev\u002Fscripts\u002Fubuntu-install-php-85.sh | bash\n",[266,1331,1332],{"class":268,"line":1124},[266,1333,1287],{"class":1286},[266,1335,1336],{"class":268,"line":1130},[266,1337,1338],{"class":1286},"# Install PHP (from packages.sury.org) and Composer on Ubuntu.\n",[266,1340,1342],{"class":268,"line":1341},14,[266,1343,1344],{"class":1286},"# Normally you will call it from your non-root user; elevated permissions\n",[266,1346,1348],{"class":268,"line":1347},15,[266,1349,1350],{"class":1286},"# will be granted with sudo.\n",[266,1352,1354],{"class":268,"line":1353},16,[266,1355,1287],{"class":1286},[266,1357,1359],{"class":268,"line":1358},17,[266,1360,794],{"emptyLinePlaceholder":793},[266,1362,1364,1367,1370],{"class":268,"line":1363},18,[266,1365,1366],{"class":728},"set",[266,1368,1369],{"class":343}," -euo",[266,1371,1372],{"class":343}," pipefail\n",[266,1374,1376],{"class":268,"line":1375},19,[266,1377,794],{"emptyLinePlaceholder":793},[266,1379,1381],{"class":268,"line":1380},20,[266,1382,1383],{"class":1286},"# You can configure these variables if needed\n",[266,1385,1387,1390,1392],{"class":268,"line":1386},21,[266,1388,1389],{"class":272},"PHP_VERSION",[266,1391,277],{"class":276},[266,1393,1394],{"class":343},"\"8.5\"\n",[266,1396,1398,1401,1403],{"class":268,"line":1397},22,[266,1399,1400],{"class":272},"PHP_EXTENSIONS",[266,1402,277],{"class":276},[266,1404,1405],{"class":343},"\"cli mbstring curl zip xml\"\n",[266,1407,1409,1412,1414],{"class":268,"line":1408},23,[266,1410,1411],{"class":272},"KEYRING",[266,1413,277],{"class":276},[266,1415,1416],{"class":343},"\"\u002Fusr\u002Fshare\u002Fkeyrings\u002Fdebsuryorg-archive-keyring.gpg\"\n",[266,1418,1420,1423,1425],{"class":268,"line":1419},24,[266,1421,1422],{"class":272},"SOURCE_FILE",[266,1424,277],{"class":276},[266,1426,1427],{"class":343},"\"\u002Fetc\u002Fapt\u002Fsources.list.d\u002Fphp.sources\"\n",[266,1429,1431],{"class":268,"line":1430},25,[266,1432,794],{"emptyLinePlaceholder":793},[266,1434,1436],{"class":268,"line":1435},26,[266,1437,1438],{"class":1286},"# Basic confirmation module before executing the script.\n",[266,1440,1442,1445,1448],{"class":268,"line":1441},27,[266,1443,1444],{"class":289},"confirm_action",[266,1446,1447],{"class":293},"()",[266,1449,1450],{"class":293}," {\n",[266,1452,1454,1457,1460,1463],{"class":268,"line":1453},28,[266,1455,1456],{"class":310},"    while",[266,1458,1459],{"class":343}," true",[266,1461,1462],{"class":293},";",[266,1464,1465],{"class":310}," do\n",[266,1467,1469,1472,1475,1478,1480,1483,1486,1489,1492],{"class":268,"line":1468},29,[266,1470,1471],{"class":728},"        read",[266,1473,1474],{"class":343}," -r",[266,1476,1477],{"class":343}," -p",[266,1479,740],{"class":343},[266,1481,1482],{"class":323},"$1",[266,1484,1485],{"class":343}," (y\u002Fn): \"",[266,1487,1488],{"class":343}," choice",[266,1490,1491],{"class":276}," \u003C",[266,1493,1494],{"class":343}," \u002Fdev\u002Ftty\n",[266,1496,1498,1501,1503,1506,1508],{"class":268,"line":1497},30,[266,1499,1500],{"class":310},"        case",[266,1502,740],{"class":343},[266,1504,1505],{"class":272},"$choice",[266,1507,752],{"class":343},[266,1509,1510],{"class":310}," in\n",[266,1512,1514,1517,1520,1523,1526,1529,1531,1534,1537,1539,1542,1544,1546,1549,1552],{"class":268,"line":1513},31,[266,1515,1516],{"class":293},"            [",[266,1518,1519],{"class":343},"Yy",[266,1521,1522],{"class":293},"]",[266,1524,1525],{"class":293},"|",[266,1527,1528],{"class":293},"[",[266,1530,1519],{"class":343},[266,1532,1533],{"class":293},"][",[266,1535,1536],{"class":343},"Ee",[266,1538,1533],{"class":293},[266,1540,1541],{"class":343},"Ss",[266,1543,1522],{"class":293},[266,1545,327],{"class":276},[266,1547,1548],{"class":310}," return",[266,1550,1551],{"class":1083}," 0",[266,1553,1554],{"class":293}," ;;\n",[266,1556,1558,1560,1563,1565,1567,1569,1571,1573,1576,1578,1580,1583,1586],{"class":268,"line":1557},32,[266,1559,1516],{"class":293},[266,1561,1562],{"class":343},"Nn",[266,1564,1522],{"class":293},[266,1566,1525],{"class":293},[266,1568,1528],{"class":293},[266,1570,1562],{"class":343},[266,1572,1533],{"class":293},[266,1574,1575],{"class":343},"Oo",[266,1577,1522],{"class":293},[266,1579,327],{"class":276},[266,1581,1582],{"class":310},"     return",[266,1584,1585],{"class":1083}," 1",[266,1587,1554],{"class":293},[266,1589,1591,1594,1597,1600],{"class":268,"line":1590},33,[266,1592,1593],{"class":276},"            *)",[266,1595,1596],{"class":728},"                 echo",[266,1598,1599],{"class":343}," \"Invalid choice. Please enter 'y' or 'n'.\"",[266,1601,1554],{"class":293},[266,1603,1605],{"class":268,"line":1604},34,[266,1606,1607],{"class":310},"        esac\n",[266,1609,1611],{"class":268,"line":1610},35,[266,1612,1613],{"class":310},"    done\n",[266,1615,1617],{"class":268,"line":1616},36,[266,1618,1619],{"class":293},"}\n",[266,1621,1623],{"class":268,"line":1622},37,[266,1624,794],{"emptyLinePlaceholder":793},[266,1626,1628,1631,1633,1635,1637,1640,1643,1645],{"class":268,"line":1627},38,[266,1629,1630],{"class":272},"WORKDIR",[266,1632,277],{"class":276},[266,1634,752],{"class":343},[266,1636,725],{"class":293},[266,1638,1639],{"class":289},"mktemp",[266,1641,1642],{"class":343}," -d",[266,1644,327],{"class":293},[266,1646,993],{"class":343},[266,1648,1650,1653,1656],{"class":268,"line":1649},39,[266,1651,1652],{"class":728},"trap",[266,1654,1655],{"class":343}," 'rm -rf \"$WORKDIR\"'",[266,1657,1658],{"class":343}," EXIT\n",[266,1660,1662],{"class":268,"line":1661},40,[266,1663,794],{"emptyLinePlaceholder":793},[266,1665,1667,1669,1672,1675,1678,1681,1684,1686],{"class":268,"line":1666},41,[266,1668,1034],{"class":310},[266,1670,1671],{"class":276}," !",[266,1673,1674],{"class":289}," confirm_action",[266,1676,1677],{"class":343}," \"Install PHP ",[266,1679,1680],{"class":272},"$PHP_VERSION",[266,1682,1683],{"class":343}," from packages.sury.org?\"",[266,1685,1462],{"class":293},[266,1687,1060],{"class":310},[266,1689,1691,1694],{"class":268,"line":1690},42,[266,1692,1693],{"class":728},"    echo",[266,1695,1696],{"class":343}," \"Skipping PHP installation. Exiting.\"\n",[266,1698,1700,1703],{"class":268,"line":1699},43,[266,1701,1702],{"class":728},"    exit",[266,1704,1705],{"class":1083}," 0\n",[266,1707,1709],{"class":268,"line":1708},44,[266,1710,1127],{"class":310},[266,1712,1714],{"class":268,"line":1713},45,[266,1715,794],{"emptyLinePlaceholder":793},[266,1717,1719],{"class":268,"line":1718},46,[266,1720,1721],{"class":1286},"# --- Prerequisites ---------------------------------------------------------\n",[266,1723,1725,1727,1729],{"class":268,"line":1724},47,[266,1726,428],{"class":289},[266,1728,516],{"class":343},[266,1730,519],{"class":343},[266,1732,1734,1736,1738,1740,1742,1744,1746],{"class":268,"line":1733},48,[266,1735,428],{"class":289},[266,1737,516],{"class":343},[266,1739,528],{"class":343},[266,1741,567],{"class":343},[266,1743,570],{"class":343},[266,1745,573],{"class":343},[266,1747,576],{"class":343},[266,1749,1751],{"class":268,"line":1750},49,[266,1752,794],{"emptyLinePlaceholder":793},[266,1754,1756],{"class":268,"line":1755},50,[266,1757,1758],{"class":1286},"# --- Sury signing key (official keyring package) ---------------------------\n",[266,1760,1762,1764,1766,1768,1771,1774],{"class":268,"line":1761},51,[266,1763,472],{"class":289},[266,1765,599],{"class":343},[266,1767,740],{"class":343},[266,1769,1770],{"class":272},"$WORKDIR",[266,1772,1773],{"class":343},"\u002Fdebsuryorg-archive-keyring.deb\"",[266,1775,1776],{"class":343}," https:\u002F\u002Fpackages.sury.org\u002Fdebsuryorg-archive-keyring.deb\n",[266,1778,1780,1782,1784,1786,1788,1790],{"class":268,"line":1779},52,[266,1781,428],{"class":289},[266,1783,620],{"class":343},[266,1785,623],{"class":343},[266,1787,740],{"class":343},[266,1789,1770],{"class":272},[266,1791,1792],{"class":343},"\u002Fdebsuryorg-archive-keyring.deb\"\n",[266,1794,1796],{"class":268,"line":1795},53,[266,1797,794],{"emptyLinePlaceholder":793},[266,1799,1801],{"class":268,"line":1800},54,[266,1802,1803],{"class":1286},"# --- Sury repository --------------------------------------------------------\n",[266,1805,1807,1810,1812,1814,1816,1818,1820,1822,1824,1826,1828,1830,1832,1834,1836],{"class":268,"line":1806},55,[266,1808,1809],{"class":272},"CODENAME",[266,1811,277],{"class":276},[266,1813,752],{"class":343},[266,1815,725],{"class":293},[266,1817,229],{"class":728},[266,1819,731],{"class":343},[266,1821,734],{"class":293},[266,1823,737],{"class":728},[266,1825,740],{"class":343},[266,1827,743],{"class":272},[266,1829,746],{"class":276},[266,1831,749],{"class":272},[266,1833,752],{"class":343},[266,1835,327],{"class":293},[266,1837,993],{"class":343},[266,1839,1841],{"class":268,"line":1840},56,[266,1842,794],{"emptyLinePlaceholder":793},[266,1844,1846,1848,1850,1852,1855,1857,1859,1861,1863],{"class":268,"line":1845},57,[266,1847,428],{"class":289},[266,1849,692],{"class":343},[266,1851,740],{"class":343},[266,1853,1854],{"class":272},"$SOURCE_FILE",[266,1856,752],{"class":343},[266,1858,698],{"class":276},[266,1860,701],{"class":343},[266,1862,704],{"class":276},[266,1864,707],{"class":343},[266,1866,1868],{"class":268,"line":1867},58,[266,1869,712],{"class":343},[266,1871,1873],{"class":268,"line":1872},59,[266,1874,717],{"class":343},[266,1876,1878,1880],{"class":268,"line":1877},60,[266,1879,722],{"class":343},[266,1881,1882],{"class":272},"$CODENAME\n",[266,1884,1886],{"class":268,"line":1885},61,[266,1887,760],{"class":343},[266,1889,1891,1893,1895,1897,1899],{"class":268,"line":1890},62,[266,1892,766],{"class":343},[266,1894,725],{"class":293},[266,1896,771],{"class":289},[266,1898,774],{"class":343},[266,1900,300],{"class":293},[266,1902,1904,1907],{"class":268,"line":1903},63,[266,1905,1906],{"class":343},"Signed-By: ",[266,1908,1909],{"class":272},"$KEYRING\n",[266,1911,1913],{"class":268,"line":1912},64,[266,1914,707],{"class":343},[266,1916,1918],{"class":268,"line":1917},65,[266,1919,794],{"emptyLinePlaceholder":793},[266,1921,1923,1925,1927],{"class":268,"line":1922},66,[266,1924,428],{"class":289},[266,1926,516],{"class":343},[266,1928,519],{"class":343},[266,1930,1932],{"class":268,"line":1931},67,[266,1933,794],{"emptyLinePlaceholder":793},[266,1935,1937],{"class":268,"line":1936},68,[266,1938,1939],{"class":1286},"# --- PHP --------------------------------------------------------------------\n",[266,1941,1943],{"class":268,"line":1942},69,[266,1944,1945],{"class":1286},"# Use -cli instead of the bare \"phpX.Y\" metapackage, which pulls in Apache.\n",[266,1947,1949,1952,1954],{"class":268,"line":1948},70,[266,1950,1951],{"class":272},"PACKAGES",[266,1953,277],{"class":276},[266,1955,1956],{"class":343},"\"\"\n",[266,1958,1960,1963,1966,1969,1972,1974],{"class":268,"line":1959},71,[266,1961,1962],{"class":310},"for",[266,1964,1965],{"class":272}," EXTENSION ",[266,1967,1968],{"class":310},"in",[266,1970,1971],{"class":272}," $PHP_EXTENSIONS",[266,1973,1462],{"class":293},[266,1975,1465],{"class":310},[266,1977,1979,1982,1984,1986,1989,1991,1994,1997,2000],{"class":268,"line":1978},72,[266,1980,1981],{"class":272},"    PACKAGES",[266,1983,277],{"class":276},[266,1985,752],{"class":343},[266,1987,1988],{"class":272},"$PACKAGES",[266,1990,944],{"class":343},[266,1992,1993],{"class":272},"${PHP_VERSION}",[266,1995,1996],{"class":343},"-",[266,1998,1999],{"class":272},"${EXTENSION}",[266,2001,993],{"class":343},[266,2003,2005],{"class":268,"line":2004},73,[266,2006,2007],{"class":310},"done\n",[266,2009,2011],{"class":268,"line":2010},74,[266,2012,794],{"emptyLinePlaceholder":793},[266,2014,2016],{"class":268,"line":2015},75,[266,2017,2018],{"class":1286},"# shellcheck disable=SC2086\n",[266,2020,2022,2024,2026,2028,2030],{"class":268,"line":2021},76,[266,2023,428],{"class":289},[266,2025,516],{"class":343},[266,2027,528],{"class":343},[266,2029,567],{"class":343},[266,2031,2032],{"class":272}," $PACKAGES\n",[266,2034,2036],{"class":268,"line":2035},77,[266,2037,794],{"emptyLinePlaceholder":793},[266,2039,2041,2043,2045,2047,2049,2052,2054],{"class":268,"line":2040},78,[266,2042,428],{"class":289},[266,2044,938],{"class":343},[266,2046,941],{"class":343},[266,2048,944],{"class":343},[266,2050,2051],{"class":343}," \"\u002Fusr\u002Fbin\u002Fphp",[266,2053,1993],{"class":272},[266,2055,993],{"class":343},[266,2057,2059],{"class":268,"line":2058},79,[266,2060,794],{"emptyLinePlaceholder":793},[266,2062,2064,2067],{"class":268,"line":2063},80,[266,2065,2066],{"class":728},"echo",[266,2068,2069],{"class":343}," \"\"\n",[266,2071,2073,2075],{"class":268,"line":2072},81,[266,2074,261],{"class":289},[266,2076,954],{"class":343},[266,2078,2080,2082],{"class":268,"line":2079},82,[266,2081,2066],{"class":728},[266,2083,2069],{"class":343},[266,2085,2087],{"class":268,"line":2086},83,[266,2088,794],{"emptyLinePlaceholder":793},[266,2090,2092],{"class":268,"line":2091},84,[266,2093,2094],{"class":1286},"# --- Composer ---------------------------------------------------------------\n",[266,2096,2098,2100,2102,2105,2107],{"class":268,"line":2097},85,[266,2099,1034],{"class":310},[266,2101,1674],{"class":289},[266,2103,2104],{"class":343}," \"Install Composer?\"",[266,2106,1462],{"class":293},[266,2108,1060],{"class":310},[266,2110,2112,2115,2117,2119],{"class":268,"line":2111},86,[266,2113,2114],{"class":728},"    cd",[266,2116,740],{"class":343},[266,2118,1770],{"class":272},[266,2120,993],{"class":343},[266,2122,2124],{"class":268,"line":2123},87,[266,2125,794],{"emptyLinePlaceholder":793},[266,2127,2129,2132,2134,2136,2138,2140,2142,2144],{"class":268,"line":2128},88,[266,2130,2131],{"class":272},"    EXPECTED_CHECKSUM",[266,2133,277],{"class":276},[266,2135,752],{"class":343},[266,2137,725],{"class":293},[266,2139,472],{"class":289},[266,2141,988],{"class":343},[266,2143,327],{"class":293},[266,2145,993],{"class":343},[266,2147,2149,2152,2154,2156],{"class":268,"line":2148},89,[266,2150,2151],{"class":289},"    curl",[266,2153,599],{"class":343},[266,2155,1002],{"class":343},[266,2157,1005],{"class":343},[266,2159,2161,2164,2166,2168,2170,2172,2174,2176],{"class":268,"line":2160},90,[266,2162,2163],{"class":272},"    ACTUAL_CHECKSUM",[266,2165,277],{"class":276},[266,2167,752],{"class":343},[266,2169,725],{"class":293},[266,2171,261],{"class":289},[266,2173,1021],{"class":343},[266,2175,327],{"class":293},[266,2177,993],{"class":343},[266,2179,2181],{"class":268,"line":2180},91,[266,2182,794],{"emptyLinePlaceholder":793},[266,2184,2186,2189,2191,2193,2195,2197,2200,2202,2204,2206,2208],{"class":268,"line":2185},92,[266,2187,2188],{"class":310},"    if",[266,2190,1037],{"class":293},[266,2192,740],{"class":343},[266,2194,1042],{"class":272},[266,2196,752],{"class":343},[266,2198,2199],{"class":276}," !=",[266,2201,740],{"class":343},[266,2203,1052],{"class":272},[266,2205,752],{"class":343},[266,2207,1057],{"class":293},[266,2209,1060],{"class":310},[266,2211,2213,2216,2218],{"class":268,"line":2212},93,[266,2214,2215],{"class":276},"        >&2",[266,2217,737],{"class":728},[266,2219,2220],{"class":343}," \"ERROR: Invalid Composer installer checksum\"\n",[266,2222,2224,2227],{"class":268,"line":2223},94,[266,2225,2226],{"class":728},"        exit",[266,2228,2229],{"class":1083}," 1\n",[266,2231,2233],{"class":268,"line":2232},95,[266,2234,2235],{"class":310},"    fi\n",[266,2237,2239],{"class":268,"line":2238},96,[266,2240,794],{"emptyLinePlaceholder":793},[266,2242,2244,2246,2248],{"class":268,"line":2243},97,[266,2245,1065],{"class":289},[266,2247,1002],{"class":343},[266,2249,1070],{"class":343},[266,2251,2253,2255,2257,2259,2261,2263],{"class":268,"line":2252},98,[266,2254,1075],{"class":289},[266,2256,528],{"class":343},[266,2258,1080],{"class":343},[266,2260,1084],{"class":1083},[266,2262,1087],{"class":343},[266,2264,1090],{"class":343},[266,2266,2268],{"class":268,"line":2267},99,[266,2269,794],{"emptyLinePlaceholder":793},[266,2271,2273,2275],{"class":268,"line":2272},100,[266,2274,1693],{"class":728},[266,2276,2069],{"class":343},[266,2278,2280,2282],{"class":268,"line":2279},101,[266,2281,1103],{"class":289},[266,2283,954],{"class":343},[266,2285,2287],{"class":268,"line":2286},102,[266,2288,1127],{"class":310},[266,2290,2292],{"class":268,"line":2291},103,[266,2293,794],{"emptyLinePlaceholder":793},[266,2295,2297,2299],{"class":268,"line":2296},104,[266,2298,2066],{"class":728},[266,2300,2069],{"class":343},[266,2302,2304,2306],{"class":268,"line":2303},105,[266,2305,2066],{"class":728},[266,2307,2308],{"class":343}," \"Installation process finished.\"\n",[266,2310,2312,2314],{"class":268,"line":2311},106,[266,2313,2066],{"class":728},[266,2315,2316],{"class":343}," \"Run 'sudo apt update && sudo apt upgrade' periodically to get PHP security releases.\"\n",[85,2318,2320],{"id":2319},"mantén-todo-al-día","Mantén todo al día",[10,2322,2323],{},"Una vez instalado, mantenerlo actualizado es cosa de un par de comandos:",[257,2325,2327],{"className":419,"code":2326,"language":421,"meta":262,"style":262},"# Sistema operativo y PHP\nsudo apt update && sudo apt upgrade\n\n# Composer\nsudo composer self-update\n",[50,2328,2329,2334,2353,2357,2362],{"__ignoreMap":262},[266,2330,2331],{"class":268,"line":269},[266,2332,2333],{"class":1286},"# Sistema operativo y PHP\n",[266,2335,2336,2338,2340,2343,2346,2348,2350],{"class":268,"line":283},[266,2337,428],{"class":289},[266,2339,516],{"class":343},[266,2341,2342],{"class":343}," update",[266,2344,2345],{"class":293}," &&",[266,2347,617],{"class":289},[266,2349,516],{"class":343},[266,2351,2352],{"class":343}," upgrade\n",[266,2354,2355],{"class":268,"line":303},[266,2356,794],{"emptyLinePlaceholder":793},[266,2358,2359],{"class":268,"line":361},[266,2360,2361],{"class":1286},"# Composer\n",[266,2363,2364,2366,2369],{"class":268,"line":757},[266,2365,428],{"class":289},[266,2367,2368],{"class":343}," composer",[266,2370,2371],{"class":343}," self-update\n",[10,2373,2374,2375,2380],{},"Incluso con la 8.5.12, php.net ",[14,2376,2379],{"href":2377,"rel":2378},"https:\u002F\u002Fwww.php.net\u002Farchive\u002F2026.php#2026-10-23-1",[26],"recomienda"," desactivar el progreso de subida de sesiones hasta la próxima release, para cerrar del todo una vía de RCE poco probable (CVE-2026-115560). Si sirves PHP con FPM, es cosa de una línea:",[257,2382,2384],{"className":419,"code":2383,"language":421,"meta":262,"style":262},"echo 'session.upload_progress.enabled=0' | sudo tee \u002Fetc\u002Fphp\u002F8.5\u002Ffpm\u002Fconf.d\u002F99-session-upload-progress.ini\nsudo systemctl restart php8.5-fpm\n",[50,2385,2386,2402],{"__ignoreMap":262},[266,2387,2388,2390,2393,2395,2397,2399],{"class":268,"line":269},[266,2389,2066],{"class":728},[266,2391,2392],{"class":343}," 'session.upload_progress.enabled=0'",[266,2394,481],{"class":276},[266,2396,617],{"class":289},[266,2398,692],{"class":343},[266,2400,2401],{"class":343}," \u002Fetc\u002Fphp\u002F8.5\u002Ffpm\u002Fconf.d\u002F99-session-upload-progress.ini\n",[266,2403,2404,2406,2409,2412],{"class":268,"line":283},[266,2405,428],{"class":289},[266,2407,2408],{"class":343}," systemctl",[266,2410,2411],{"class":343}," restart",[266,2413,2414],{"class":343}," php8.5-fpm\n",[10,2416,2417,2418,248,2425,2432],{},"Y no te olvides de las dependencias de tus proyectos: ",[14,2419,2422],{"href":2420,"rel":2421},"https:\u002F\u002Fgetcomposer.org\u002Fdoc\u002F03-cli.md#outdated",[26],[50,2423,2424],{},"composer outdated",[14,2426,2429],{"href":2427,"rel":2428},"https:\u002F\u002Fgetcomposer.org\u002Fdoc\u002F03-cli.md#audit",[26],[50,2430,2431],{},"composer audit"," te dicen qué toca actualizar y qué paquetes tienen vulnerabilidades conocidas.",[10,2434,2435,2436,2438,2439,2442,2443,2445],{},"Dos tandas de parches de seguridad de PHP en menos de un mes, una de ellas de emergencia, recuerdan que no puedes saber qué parche será el importante. Lo que sí puedes hacer es que aplicarlos sea aburrido: un ",[50,2437,651],{}," para PHP, un ",[50,2440,2441],{},"composer self-update"," para Composer y ",[50,2444,2431],{}," para tus proyectos. Déjalo configurado una vez y olvídate.",[2447,2448,2449],"style",{},"html pre.shiki code .s0aCy, html code.shiki .s0aCy{--shiki-default:#4C4F69;--shiki-dark:#CDD6F4}html pre.shiki code .sjJjI, html code.shiki .sjJjI{--shiki-default:#179299;--shiki-dark:#94E2D5}html pre.shiki code .sMmZK, html code.shiki .sMmZK{--shiki-default:#1E66F5;--shiki-default-font-style:italic;--shiki-dark:#89B4FA;--shiki-dark-font-style:italic}html pre.shiki code .sxyLT, html code.shiki .sxyLT{--shiki-default:#7C7F93;--shiki-dark:#9399B2}html pre.shiki code .sAS4m, html code.shiki .sAS4m{--shiki-default:#8839EF;--shiki-dark:#CBA6F7}html pre.shiki code .seXix, html code.shiki .seXix{--shiki-default:#E64553;--shiki-dark:#EBA0AC}html pre.shiki code .s2f33, html code.shiki .s2f33{--shiki-default:#E64553;--shiki-default-font-style:italic;--shiki-dark:#EBA0AC;--shiki-dark-font-style:italic}html pre.shiki code .sgueU, html code.shiki .sgueU{--shiki-default:#40A02B;--shiki-dark:#A6E3A1}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sNVtu, html code.shiki .sNVtu{--shiki-default:#EA76CB;--shiki-dark:#F5C2E7}html pre.shiki code .s-0VM, html code.shiki .s-0VM{--shiki-default:#D20F39;--shiki-default-font-style:italic;--shiki-dark:#F38BA8;--shiki-dark-font-style:italic}html pre.shiki code .st0oN, html code.shiki .st0oN{--shiki-default:#FE640B;--shiki-dark:#FAB387}html pre.shiki code .skWWU, html code.shiki .skWWU{--shiki-default:#EA76CB;--shiki-default-font-style:italic;--shiki-dark:#F5C2E7;--shiki-dark-font-style:italic}html pre.shiki code .som-u, html code.shiki .som-u{--shiki-default:#7C7F93;--shiki-default-font-style:italic;--shiki-dark:#9399B2;--shiki-dark-font-style:italic}",{"title":262,"searchDepth":283,"depth":283,"links":2451},[2452,2453,2454,2455,2456,2464,2465,2466],{"id":87,"depth":283,"text":88},{"id":202,"depth":283,"text":203},{"id":376,"depth":283,"text":377},{"id":450,"depth":283,"text":451},{"id":534,"depth":283,"text":535,"children":2457},[2458,2459,2460,2461,2462,2463],{"id":542,"depth":303,"text":543},{"id":586,"depth":303,"text":587},{"id":658,"depth":303,"text":659},{"id":806,"depth":303,"text":807},{"id":911,"depth":303,"text":912},{"id":957,"depth":303,"text":958},{"id":1157,"depth":283,"text":1158},{"id":1241,"depth":283,"text":1242},{"id":2319,"depth":283,"text":2320},"2026-11-06","Instala PHP 8.5 y Composer en Ubuntu 26.04 LTS con apt desde el repositorio packages.sury.org de Ondřej Surý y mantenlos al día con apt upgrade.","md",null,{},"\u002Fes\u002Fblog\u002Fapt-install-php-85-on-ubuntu-26","12",{"title":5,"description":2468},"es\u002Fblog\u002F0005.apt-install-php-85-on-ubuntu-26",[261,2477,1268,421],"ubuntu",false,"U_VnZM0N9vbNzNKUHaUOEpa1M_1p_O3qZRBduTXAl5A",{"id":2481,"title":2482,"body":2483,"date":2467,"description":4441,"extension":2469,"image":2470,"meta":4442,"navigation":793,"path":4443,"readingTime":4444,"schemaOrg":2470,"seo":4445,"stem":4446,"tags":4447,"toc":2478,"updatedAt":2470,"__hash__":4448},"blog_en\u002Fblog\u002F0005.apt-install-php-85-on-ubuntu-26.md","Install PHP 8.5 with apt on Ubuntu 26.04",{"type":7,"value":2484,"toc":4424},[2485,2493,2504,2526,2540,2544,2551,2621,2632,2639,2643,2652,2685,2688,2764,2768,2789,2798,2812,2821,2825,2834,2850,2864,2870,2892,2896,2899,2903,2931,2937,2941,2979,2994,2998,3014,3104,3108,3132,3167,3176,3188,3192,3203,3225,3229,3236,3371,3386,3390,3398,3432,3445,3451,3457,3461,3467,3485,4311,4315,4318,4360,4368,4396,4410,4422],[10,2486,2487,2488,2492],{},"Yesterday I posted how to ",[14,2489,2491],{"href":2490},"\u002Fblog\u002Fapt-install-node-26-on-ubuntu-26\u002F","install Node.js 26 with apt"," so the operating system keeps it patched after October's security releases. Today it's PHP's turn, for the same reason: security breaches keep coming, and PHP has had its fair share.",[10,2494,2495,2496,2499,2500,2503],{},"On September 24, ",[14,2497,27],{"href":24,"rel":2498},[26]," fixed more than ten CVEs in OpenSSL, FPM, SOAP, Phar, and the HTTP stream wrapper, including a heap buffer overflow and a TLS hostname verification bypass. On October 21, ",[14,2501,33],{"href":31,"rel":2502},[26]," went further: an emergency release for two critical vulnerabilities (CVE-2026-109618 and CVE-2026-109619, CVSS 9.2) that allow unauthenticated remote code execution. In php.net's own words, \"updating is the only safe choice\". The 8.4, 8.3, and 8.2 branches got the same fixes.",[10,2505,2506,2507,43,2510,2512,2513,2515,2516,2518,2519,2522,2523,2525],{},"Here's the catch: ",[14,2508,42],{"href":40,"rel":2509},[26],[45,2511,47],{},") ships PHP 8.5 in its archive, but it freezes the version at release time and backports the fixes it considers important. At the time of writing, ",[50,2514,52],{}," gives you PHP ",[50,2517,56],{}," with patches on top, while ",[14,2520,62],{"href":60,"rel":2521},[26]," is already at ",[50,2524,66],{},". To be fair, Ubuntu's security team handles the urgent stuff well: it shipped the October RCE fixes the same day as php.net. But the September batch took 25 days to land, and upstream's regular bug fixes rarely make it at all.",[10,2527,2528,2529,2531,2532,2536,2537,2539],{},"If you want the full upstream release, the easiest way is still to let the operating system handle it. Install PHP with ",[50,2530,52],{}," from ",[14,2533,2535],{"href":76,"rel":2534},[26],"Ondřej Surý's repository",", the same packages that have powered PHP on Debian and Ubuntu for more than a decade, and let ",[50,2538,82],{}," take care of the rest.",[85,2541,2543],{"id":2542},"support-dates-at-a-glance","Support dates at a glance",[10,2545,2546,2547,97],{},"Each PHP branch gets two years of active support followed by two years of security-only fixes. This is where things stand according to the ",[14,2548,2550],{"href":94,"rel":2549},[26],"official supported versions page",[99,2552,2553,2569],{},[102,2554,2555],{},[105,2556,2557,2560,2563,2566],{},[108,2558,2559],{},"Version",[108,2561,2562],{},"Released",[108,2564,2565],{},"Active support until",[108,2567,2568],{},"Security support until",[121,2570,2571,2584,2597,2609],{},[105,2572,2573,2575,2578,2581],{},[126,2574,128],{},[126,2576,2577],{},"Dec 8, 2022",[126,2579,2580],{},"Dec 31, 2024",[126,2582,2583],{},"Dec 31, 2026",[105,2585,2586,2588,2591,2594],{},[126,2587,142],{},[126,2589,2590],{},"Nov 23, 2023",[126,2592,2593],{},"Dec 31, 2025",[126,2595,2596],{},"Dec 31, 2027",[105,2598,2599,2601,2604,2606],{},[126,2600,156],{},[126,2602,2603],{},"Nov 21, 2024",[126,2605,2583],{},[126,2607,2608],{},"Dec 31, 2028",[105,2610,2611,2613,2616,2618],{},[126,2612,169],{},[126,2614,2615],{},"Nov 20, 2025",[126,2617,2596],{},[126,2619,2620],{},"Dec 31, 2029",[10,2622,2623,2624,2627,2628,191],{},"If you're still on PHP 8.2, you have less than two months left. ",[14,2625,185],{"href":183,"rel":2626},[26]," is scheduled for November 19, 2026, but PHP 8.5 is the safe bet to pair with an LTS distribution today. You can always try 8.6 side by side (see ",[14,2629,2631],{"href":2630},"#what-about-other-php-versions","below",[10,2633,2634,2635,2638],{},"On the OS side, ",[14,2636,42],{"href":197,"rel":2637},[26]," was released in April 2026 and gets standard security maintenance until May 2031, extended to 2036 with Ubuntu Pro. So this setup will last for a while.",[85,2640,2642],{"id":2641},"whats-new-in-php-85","What's new in PHP 8.5",[10,2644,2645,2646,2651],{},"If you're coming from PHP 8.4 or older, here are a few reasons to upgrade beyond security. The ",[14,2647,2650],{"href":2648,"rel":2649},"https:\u002F\u002Fwww.php.net\u002Freleases\u002F8.5\u002Fen.php",[26],"release announcement"," has the full list, but my favorites are:",[214,2653,2654,2657,2665,2671,2677],{},[217,2655,2656],{},"The pipe operator, to chain callables from left to right without temporary variables.",[217,2658,2659,2661,2662,2664],{},[50,2660,224],{}," with properties, which turns the \"with-er\" pattern for ",[50,2663,228],{}," classes into one line.",[217,2666,2667,2668,2670],{},"The ",[50,2669,235],{}," attribute, which warns when someone ignores a return value that matters.",[217,2672,2673,2674,2676],{},"A native URI extension, with URL parsing that follows RFC 3986 and WHATWG, no more ",[50,2675,242],{}," surprises.",[217,2678,2679,2681,2682,2684],{},[50,2680,247],{}," and ",[50,2683,251],{},". Finally.",[10,2686,2687],{},"Here's the pipe operator turning a title into a slug:",[257,2689,2690],{"className":259,"code":260,"language":261,"meta":262,"style":262},[50,2691,2692,2700,2712,2752],{"__ignoreMap":262},[266,2693,2694,2696,2698],{"class":268,"line":269},[266,2695,273],{"class":272},[266,2697,277],{"class":276},[266,2699,280],{"class":272},[266,2701,2702,2704,2706,2708,2710],{"class":268,"line":283},[266,2703,286],{"class":276},[266,2705,290],{"class":289},[266,2707,294],{"class":293},[266,2709,297],{"class":276},[266,2711,300],{"class":293},[266,2713,2714,2716,2718,2720,2722,2724,2726,2728,2730,2732,2734,2736,2738,2740,2742,2744,2746,2748,2750],{"class":268,"line":303},[266,2715,286],{"class":276},[266,2717,43],{"class":293},[266,2719,311],{"class":310},[266,2721,43],{"class":293},[266,2723,316],{"class":310},[266,2725,320],{"class":319},[266,2727,324],{"class":323},[266,2729,327],{"class":293},[266,2731,97],{"class":276},[266,2733,332],{"class":310},[266,2735,335],{"class":293},[266,2737,338],{"class":289},[266,2739,294],{"class":293},[266,2741,344],{"class":343},[266,2743,347],{"class":293},[266,2745,350],{"class":343},[266,2747,347],{"class":293},[266,2749,355],{"class":272},[266,2751,358],{"class":293},[266,2753,2754,2756,2758,2760,2762],{"class":268,"line":361},[266,2755,286],{"class":276},[266,2757,366],{"class":289},[266,2759,294],{"class":293},[266,2761,297],{"class":276},[266,2763,373],{"class":293},[85,2765,2767],{"id":2766},"what-changed-goodbye-ppa-hello-packagessuryorg","What changed: goodbye PPA, hello packages.sury.org",[10,2769,2770,2771,2773,2774,2777,2778,2781,2782,2784,2785,2788],{},"If you've installed PHP on Ubuntu before, you probably ran ",[50,2772,383],{},". That's no longer the way to go: Ondřej Surý is moving his Ubuntu packages from ",[14,2775,389],{"href":387,"rel":2776},[26]," to ",[14,2779,395],{"href":393,"rel":2780},[26],", the server that already hosts the Debian ones. The ",[50,2783,399],{}," packages for Ubuntu 26.04 are ",[402,2786,2787],{},"only"," published there.",[10,2790,2791,2792,2794,2795,2797],{},"If you still have the PPA configured, you may have seen ",[50,2793,411],{}," complain this summer that the repository changed its 'Label' value, an error that made ",[50,2796,415],{}," fail in scripts until you accepted the change. For now the PPA still gets updates for Ubuntu 22.04 and 24.04, but it's being merged into packages.sury.org. And if both are configured, apt keeps preferring the PPA builds, so remove it before following the steps below:",[257,2799,2800],{"className":419,"code":420,"language":421,"meta":262,"style":262},[50,2801,2802],{"__ignoreMap":262},[266,2803,2804,2806,2808,2810],{"class":268,"line":269},[266,2805,428],{"class":289},[266,2807,431],{"class":343},[266,2809,434],{"class":343},[266,2811,437],{"class":343},[10,2813,2814,2815,2817,2818,2820],{},"The new setup also improves how the signing key is handled. Instead of downloading a raw ",[50,2816,443],{}," file, you install the official ",[50,2819,447],{}," package.",[85,2822,2824],{"id":2823},"the-easy-way","The easy way",[10,2826,2827,2828,2830,2831,229],{},"As usual, you can install everything with a single command. The script adds the Sury repository, installs PHP 8.5 with the most common extensions, makes it the default ",[50,2829,261],{},", and optionally installs ",[14,2832,462],{"href":460,"rel":2833},[26],[257,2835,2836],{"className":419,"code":465,"language":421,"meta":262,"style":262},[50,2837,2838],{"__ignoreMap":262},[266,2839,2840,2842,2844,2846,2848],{"class":268,"line":269},[266,2841,472],{"class":289},[266,2843,475],{"class":343},[266,2845,478],{"class":343},[266,2847,481],{"class":276},[266,2849,484],{"class":289},[10,2851,2852,2853,2857,2858,2860,2861,2863],{},"The script asks for confirmation at each major step. As always, read ",[14,2854,2856],{"href":2855},"#the-script","the script"," before you pipe it into ",[50,2859,421],{},". Trusting random URLs with ",[50,2862,428],{}," is a great way to learn about incident response.",[10,2865,2866,2867,2869],{},"If you don't have ",[50,2868,472],{}," installed:",[257,2871,2872],{"className":419,"code":507,"language":421,"meta":262,"style":262},[50,2873,2874,2882],{"__ignoreMap":262},[266,2875,2876,2878,2880],{"class":268,"line":269},[266,2877,428],{"class":289},[266,2879,516],{"class":343},[266,2881,519],{"class":343},[266,2883,2884,2886,2888,2890],{"class":268,"line":283},[266,2885,428],{"class":289},[266,2887,516],{"class":343},[266,2889,528],{"class":343},[266,2891,531],{"class":343},[85,2893,2895],{"id":2894},"the-step-by-step-guide","The step-by-step guide",[10,2897,2898],{},"Here's what the script does, in case you want to run it step by step.",[540,2900,2902],{"id":2901},"_1-install-the-prerequisites","1. Install the prerequisites",[257,2904,2905],{"className":419,"code":546,"language":421,"meta":262,"style":262},[50,2906,2907,2915],{"__ignoreMap":262},[266,2908,2909,2911,2913],{"class":268,"line":269},[266,2910,428],{"class":289},[266,2912,516],{"class":343},[266,2914,519],{"class":343},[266,2916,2917,2919,2921,2923,2925,2927,2929],{"class":268,"line":283},[266,2918,428],{"class":289},[266,2920,516],{"class":343},[266,2922,528],{"class":343},[266,2924,567],{"class":343},[266,2926,570],{"class":343},[266,2928,573],{"class":343},[266,2930,576],{"class":343},[10,2932,2933,2934,2936],{},"PHP doesn't need ",[50,2935,582],{},", but Composer uses it to extract packages much faster than its PHP fallback.",[540,2938,2940],{"id":2939},"_2-install-the-sury-signing-key","2. Install the Sury signing key",[257,2942,2943],{"className":419,"code":590,"language":421,"meta":262,"style":262},[50,2944,2945,2957,2971],{"__ignoreMap":262},[266,2946,2947,2949,2951,2953,2955],{"class":268,"line":269},[266,2948,472],{"class":289},[266,2950,599],{"class":343},[266,2952,602],{"class":343},[266,2954,605],{"class":343},[266,2956,609],{"class":608},[266,2958,2959,2961,2963,2965,2967,2969],{"class":268,"line":283},[266,2960,614],{"class":293},[266,2962,617],{"class":289},[266,2964,620],{"class":343},[266,2966,623],{"class":343},[266,2968,602],{"class":343},[266,2970,609],{"class":608},[266,2972,2973,2975,2977],{"class":268,"line":303},[266,2974,614],{"class":293},[266,2976,634],{"class":289},[266,2978,637],{"class":343},[10,2980,2981,2982,2984,2985,2987,2988,2990,2991,2993],{},"This drops the key in ",[50,2983,643],{}," (plus, for now, a global copy in ",[50,2986,647],{},"). On Debian the repository also ships the keyring package, so key rotations arrive with ",[50,2989,651],{},". The Ubuntu suites don't ship it yet, so if the key is ever rotated, download and install the ",[50,2992,655],{}," again.",[540,2995,2997],{"id":2996},"_3-add-the-sury-repository","3. Add the Sury repository",[10,2999,3000,3001,43,3005,3007,3008,3010,3011,3013],{},"Since 24.04, Ubuntu uses the ",[14,3002,3004],{"href":665,"rel":3003},[26],"deb822 format",[50,3006,671],{}," files) for its own repositories, and the classic one-line ",[50,3009,675],{}," format is now officially deprecated. The codename is read from ",[50,3012,679],{},", so the same snippet also works on Ubuntu 22.04 and 24.04, and on derivatives like Linux Mint.",[257,3015,3016],{"className":419,"code":683,"language":421,"meta":262,"style":262},[50,3017,3018,3034,3038,3042,3068,3072,3084,3088,3092,3096],{"__ignoreMap":262},[266,3019,3020,3022,3024,3026,3028,3030,3032],{"class":268,"line":269},[266,3021,428],{"class":289},[266,3023,692],{"class":343},[266,3025,695],{"class":343},[266,3027,698],{"class":276},[266,3029,701],{"class":343},[266,3031,704],{"class":276},[266,3033,707],{"class":343},[266,3035,3036],{"class":268,"line":283},[266,3037,712],{"class":343},[266,3039,3040],{"class":268,"line":303},[266,3041,717],{"class":343},[266,3043,3044,3046,3048,3050,3052,3054,3056,3058,3060,3062,3064,3066],{"class":268,"line":361},[266,3045,722],{"class":343},[266,3047,725],{"class":293},[266,3049,229],{"class":728},[266,3051,731],{"class":343},[266,3053,734],{"class":293},[266,3055,737],{"class":728},[266,3057,740],{"class":343},[266,3059,743],{"class":272},[266,3061,746],{"class":276},[266,3063,749],{"class":272},[266,3065,752],{"class":343},[266,3067,300],{"class":293},[266,3069,3070],{"class":268,"line":757},[266,3071,760],{"class":343},[266,3073,3074,3076,3078,3080,3082],{"class":268,"line":763},[266,3075,766],{"class":343},[266,3077,725],{"class":293},[266,3079,771],{"class":289},[266,3081,774],{"class":343},[266,3083,300],{"class":293},[266,3085,3086],{"class":268,"line":779},[266,3087,782],{"class":343},[266,3089,3090],{"class":268,"line":785},[266,3091,707],{"class":343},[266,3093,3094],{"class":268,"line":790},[266,3095,794],{"emptyLinePlaceholder":793},[266,3097,3098,3100,3102],{"class":268,"line":797},[266,3099,428],{"class":289},[266,3101,516],{"class":343},[266,3103,519],{"class":343},[540,3105,3107],{"id":3106},"_4-install-php-85","4. Install PHP 8.5",[257,3109,3110],{"className":419,"code":810,"language":421,"meta":262,"style":262},[50,3111,3112],{"__ignoreMap":262},[266,3113,3114,3116,3118,3120,3122,3124,3126,3128,3130],{"class":268,"line":269},[266,3115,428],{"class":289},[266,3117,516],{"class":343},[266,3119,528],{"class":343},[266,3121,567],{"class":343},[266,3123,825],{"class":343},[266,3125,828],{"class":343},[266,3127,831],{"class":343},[266,3129,834],{"class":343},[266,3131,837],{"class":343},[10,3133,3134,3135,3137,3138,3140,3141,3144,3145,3151,3152,3155,3156,3159,3160,878,3162,3164,3165,229],{},"Notice that we install ",[50,3136,843],{}," instead of the bare ",[50,3139,847],{}," metapackage. The metapackage pulls in ",[14,3142,853],{"href":851,"rel":3143},[26]," and its PHP module, which you probably don't want on your development machine. If you need a web server, add ",[14,3146,3149],{"href":3147,"rel":3148},"https:\u002F\u002Fwww.php.net\u002Fmanual\u002Fen\u002Finstall.fpm.php",[26],[50,3150,861],{}," and pair it with ",[14,3153,867],{"href":865,"rel":3154},[26]," or ",[14,3157,873],{"href":871,"rel":3158},[26],". Need a database? Add ",[50,3161,877],{},[50,3163,881],{},", or ",[50,3166,884],{},[10,3168,3169,3170,3172,3173,3175],{},"You don't need an apt pin: Sury's ",[50,3171,66],{}," has a higher version than Ubuntu's ",[50,3174,56],{},", so apt picks it automatically. You can check where each package comes from with:",[257,3177,3178],{"className":419,"code":896,"language":421,"meta":262,"style":262},[50,3179,3180],{"__ignoreMap":262},[266,3181,3182,3184,3186],{"class":268,"line":269},[266,3183,52],{"class":289},[266,3185,905],{"class":343},[266,3187,908],{"class":343},[540,3189,3191],{"id":3190},"_5-make-php-85-the-default","5. Make PHP 8.5 the default",[10,3193,2667,3194,3196,3197,3202],{},[50,3195,261],{}," command is managed by ",[14,3198,3200],{"href":921,"rel":3199},[26],[50,3201,925],{},", so you can choose which version answers to it:",[257,3204,3205],{"className":419,"code":929,"language":421,"meta":262,"style":262},[50,3206,3207,3219],{"__ignoreMap":262},[266,3208,3209,3211,3213,3215,3217],{"class":268,"line":269},[266,3210,428],{"class":289},[266,3212,938],{"class":343},[266,3214,941],{"class":343},[266,3216,944],{"class":343},[266,3218,947],{"class":343},[266,3220,3221,3223],{"class":268,"line":283},[266,3222,261],{"class":289},[266,3224,954],{"class":343},[540,3226,3228],{"id":3227},"_6-install-composer","6. Install Composer",[10,3230,2667,3231,3235],{},[14,3232,3234],{"href":964,"rel":3233},[26],"official installer"," publishes a SHA-384 checksum, so verify it before running anything:",[257,3237,3239],{"className":419,"code":3238,"language":421,"meta":262,"style":262},"EXPECTED_CHECKSUM=\"$(curl -fsSL https:\u002F\u002Fcomposer.github.io\u002Finstaller.sig)\"\ncurl -fsSLo composer-setup.php https:\u002F\u002Fgetcomposer.org\u002Finstaller\nACTUAL_CHECKSUM=\"$(php -r \"echo hash_file('sha384', 'composer-setup.php');\")\"\n\nif [ \"$EXPECTED_CHECKSUM\" = \"$ACTUAL_CHECKSUM\" ]; then\n    php composer-setup.php --quiet\n    sudo install -m 0755 composer.phar \u002Fusr\u002Flocal\u002Fbin\u002Fcomposer\n    rm composer.phar\n    composer --version\nelse\n    >&2 echo \"ERROR: Invalid Composer installer checksum\"\nfi\nrm composer-setup.php\n",[50,3240,3241,3259,3269,3287,3291,3315,3323,3337,3343,3349,3353,3361,3365],{"__ignoreMap":262},[266,3242,3243,3245,3247,3249,3251,3253,3255,3257],{"class":268,"line":269},[266,3244,977],{"class":272},[266,3246,277],{"class":276},[266,3248,752],{"class":343},[266,3250,725],{"class":293},[266,3252,472],{"class":289},[266,3254,988],{"class":343},[266,3256,327],{"class":293},[266,3258,993],{"class":343},[266,3260,3261,3263,3265,3267],{"class":268,"line":283},[266,3262,472],{"class":289},[266,3264,599],{"class":343},[266,3266,1002],{"class":343},[266,3268,1005],{"class":343},[266,3270,3271,3273,3275,3277,3279,3281,3283,3285],{"class":268,"line":303},[266,3272,1010],{"class":272},[266,3274,277],{"class":276},[266,3276,752],{"class":343},[266,3278,725],{"class":293},[266,3280,261],{"class":289},[266,3282,1021],{"class":343},[266,3284,327],{"class":293},[266,3286,993],{"class":343},[266,3288,3289],{"class":268,"line":361},[266,3290,794],{"emptyLinePlaceholder":793},[266,3292,3293,3295,3297,3299,3301,3303,3305,3307,3309,3311,3313],{"class":268,"line":757},[266,3294,1034],{"class":310},[266,3296,1037],{"class":293},[266,3298,740],{"class":343},[266,3300,1042],{"class":272},[266,3302,752],{"class":343},[266,3304,1047],{"class":276},[266,3306,740],{"class":343},[266,3308,1052],{"class":272},[266,3310,752],{"class":343},[266,3312,1057],{"class":293},[266,3314,1060],{"class":310},[266,3316,3317,3319,3321],{"class":268,"line":763},[266,3318,1065],{"class":289},[266,3320,1002],{"class":343},[266,3322,1070],{"class":343},[266,3324,3325,3327,3329,3331,3333,3335],{"class":268,"line":779},[266,3326,1075],{"class":289},[266,3328,528],{"class":343},[266,3330,1080],{"class":343},[266,3332,1084],{"class":1083},[266,3334,1087],{"class":343},[266,3336,1090],{"class":343},[266,3338,3339,3341],{"class":268,"line":785},[266,3340,1095],{"class":289},[266,3342,1098],{"class":343},[266,3344,3345,3347],{"class":268,"line":790},[266,3346,1103],{"class":289},[266,3348,954],{"class":343},[266,3350,3351],{"class":268,"line":797},[266,3352,1110],{"class":310},[266,3354,3355,3357,3359],{"class":268,"line":1113},[266,3356,1116],{"class":276},[266,3358,737],{"class":728},[266,3360,2220],{"class":343},[266,3362,3363],{"class":268,"line":1124},[266,3364,1127],{"class":310},[266,3366,3367,3369],{"class":268,"line":1130},[266,3368,1133],{"class":289},[266,3370,1136],{"class":343},[10,3372,3373,3374,3376,3377,3379,3380,3382,3383,3385],{},"Using ",[50,3375,1142],{}," instead of ",[50,3378,1146],{}," makes ",[50,3381,1150],{}," the owner of the binary, which matters because you'll run ",[50,3384,1154],{}," later.",[85,3387,3389],{"id":3388},"what-about-other-php-versions","What about other PHP versions?",[10,3391,3392,3393,2777,3395,3397],{},"This is where the Sury repository really shines. It publishes every branch from ",[50,3394,1164],{},[50,3396,847],{},", plus the PHP 8.6 release candidates, and they can all live side by side:",[257,3399,3400],{"className":419,"code":1171,"language":421,"meta":262,"style":262},[50,3401,3402,3422],{"__ignoreMap":262},[266,3403,3404,3406,3408,3410,3412,3414,3416,3418,3420],{"class":268,"line":269},[266,3405,428],{"class":289},[266,3407,516],{"class":343},[266,3409,528],{"class":343},[266,3411,567],{"class":343},[266,3413,1186],{"class":343},[266,3415,1189],{"class":343},[266,3417,1192],{"class":343},[266,3419,1195],{"class":343},[266,3421,1198],{"class":343},[266,3423,3424,3426,3428,3430],{"class":268,"line":283},[266,3425,428],{"class":289},[266,3427,938],{"class":343},[266,3429,1207],{"class":343},[266,3431,1210],{"class":343},[10,3433,3434,3436,3437,3439,3440,3155,3442,3444],{},[50,3435,1215],{}," shows an interactive menu to switch the default ",[50,3438,261],{},". You can also call a specific version directly with ",[50,3441,1222],{},[50,3443,847],{},", which is handy for running a legacy project's tests without touching your default.",[10,3446,3447,3448,3450],{},"If you try 8.6 before its final release on November 19, check ",[50,3449,1231],{},": builds older than RC4 don't include the October RCE fixes.",[10,3452,3453,3454,3456],{},"Keep in mind that every version you install is one more you have to keep patched. With Sury, at least, ",[50,3455,651],{}," patches all of them at once.",[85,3458,3460],{"id":3459},"the-script","The script",[10,3462,3463,3464,3466],{},"This is the complete script. It includes confirmations, uses a temporary directory that is removed on exit, and reads your answers from the terminal, so it works when you pipe it from ",[50,3465,472],{},". You can change the PHP version and the extensions with the variables at the top.",[10,3468,3469,3470,3474,3475,3479,3480,2681,3482,3484],{},"This script comes from my ",[14,3471,3473],{"href":1254,"rel":3472},[26],"Neovim configuration repo",", where I keep my ",[14,3476,3478],{"href":1260,"rel":3477},[26],"install scripts",". The editor needs ",[50,3481,261],{},[50,3483,1268],{}," for the PHP language servers and formatters to work, so I update them regularly. If you want the latest version, look there first.",[257,3486,3487],{"className":419,"code":1272,"filename":1273,"language":421,"meta":262,"style":262},[50,3488,3489,3493,3497,3501,3505,3509,3513,3517,3521,3525,3529,3533,3537,3541,3545,3549,3553,3557,3565,3569,3573,3581,3589,3597,3605,3609,3613,3621,3631,3651,3663,3695,3723,3733,3737,3741,3745,3749,3767,3775,3779,3797,3803,3809,3813,3817,3821,3829,3845,3849,3853,3867,3881,3885,3889,3921,3925,3945,3949,3953,3959,3963,3975,3981,3985,3989,3997,4001,4005,4009,4017,4031,4051,4055,4059,4063,4075,4079,4095,4099,4105,4111,4117,4121,4125,4137,4147,4151,4169,4179,4197,4201,4225,4233,4239,4243,4247,4255,4269,4273,4279,4285,4289,4293,4299,4305],{"__ignoreMap":262},[266,3490,3491],{"class":268,"line":269},[266,3492,1281],{"class":1280},[266,3494,3495],{"class":268,"line":283},[266,3496,1287],{"class":1286},[266,3498,3499],{"class":268,"line":303},[266,3500,1292],{"class":1286},[266,3502,3503],{"class":268,"line":361},[266,3504,1297],{"class":1286},[266,3506,3507],{"class":268,"line":757},[266,3508,1287],{"class":1286},[266,3510,3511],{"class":268,"line":763},[266,3512,1306],{"class":1286},[266,3514,3515],{"class":268,"line":779},[266,3516,1287],{"class":1286},[266,3518,3519],{"class":268,"line":785},[266,3520,1315],{"class":1286},[266,3522,3523],{"class":268,"line":790},[266,3524,1287],{"class":1286},[266,3526,3527],{"class":268,"line":797},[266,3528,1324],{"class":1286},[266,3530,3531],{"class":268,"line":1113},[266,3532,1329],{"class":1286},[266,3534,3535],{"class":268,"line":1124},[266,3536,1287],{"class":1286},[266,3538,3539],{"class":268,"line":1130},[266,3540,1338],{"class":1286},[266,3542,3543],{"class":268,"line":1341},[266,3544,1344],{"class":1286},[266,3546,3547],{"class":268,"line":1347},[266,3548,1350],{"class":1286},[266,3550,3551],{"class":268,"line":1353},[266,3552,1287],{"class":1286},[266,3554,3555],{"class":268,"line":1358},[266,3556,794],{"emptyLinePlaceholder":793},[266,3558,3559,3561,3563],{"class":268,"line":1363},[266,3560,1366],{"class":728},[266,3562,1369],{"class":343},[266,3564,1372],{"class":343},[266,3566,3567],{"class":268,"line":1375},[266,3568,794],{"emptyLinePlaceholder":793},[266,3570,3571],{"class":268,"line":1380},[266,3572,1383],{"class":1286},[266,3574,3575,3577,3579],{"class":268,"line":1386},[266,3576,1389],{"class":272},[266,3578,277],{"class":276},[266,3580,1394],{"class":343},[266,3582,3583,3585,3587],{"class":268,"line":1397},[266,3584,1400],{"class":272},[266,3586,277],{"class":276},[266,3588,1405],{"class":343},[266,3590,3591,3593,3595],{"class":268,"line":1408},[266,3592,1411],{"class":272},[266,3594,277],{"class":276},[266,3596,1416],{"class":343},[266,3598,3599,3601,3603],{"class":268,"line":1419},[266,3600,1422],{"class":272},[266,3602,277],{"class":276},[266,3604,1427],{"class":343},[266,3606,3607],{"class":268,"line":1430},[266,3608,794],{"emptyLinePlaceholder":793},[266,3610,3611],{"class":268,"line":1435},[266,3612,1438],{"class":1286},[266,3614,3615,3617,3619],{"class":268,"line":1441},[266,3616,1444],{"class":289},[266,3618,1447],{"class":293},[266,3620,1450],{"class":293},[266,3622,3623,3625,3627,3629],{"class":268,"line":1453},[266,3624,1456],{"class":310},[266,3626,1459],{"class":343},[266,3628,1462],{"class":293},[266,3630,1465],{"class":310},[266,3632,3633,3635,3637,3639,3641,3643,3645,3647,3649],{"class":268,"line":1468},[266,3634,1471],{"class":728},[266,3636,1474],{"class":343},[266,3638,1477],{"class":343},[266,3640,740],{"class":343},[266,3642,1482],{"class":323},[266,3644,1485],{"class":343},[266,3646,1488],{"class":343},[266,3648,1491],{"class":276},[266,3650,1494],{"class":343},[266,3652,3653,3655,3657,3659,3661],{"class":268,"line":1497},[266,3654,1500],{"class":310},[266,3656,740],{"class":343},[266,3658,1505],{"class":272},[266,3660,752],{"class":343},[266,3662,1510],{"class":310},[266,3664,3665,3667,3669,3671,3673,3675,3677,3679,3681,3683,3685,3687,3689,3691,3693],{"class":268,"line":1513},[266,3666,1516],{"class":293},[266,3668,1519],{"class":343},[266,3670,1522],{"class":293},[266,3672,1525],{"class":293},[266,3674,1528],{"class":293},[266,3676,1519],{"class":343},[266,3678,1533],{"class":293},[266,3680,1536],{"class":343},[266,3682,1533],{"class":293},[266,3684,1541],{"class":343},[266,3686,1522],{"class":293},[266,3688,327],{"class":276},[266,3690,1548],{"class":310},[266,3692,1551],{"class":1083},[266,3694,1554],{"class":293},[266,3696,3697,3699,3701,3703,3705,3707,3709,3711,3713,3715,3717,3719,3721],{"class":268,"line":1557},[266,3698,1516],{"class":293},[266,3700,1562],{"class":343},[266,3702,1522],{"class":293},[266,3704,1525],{"class":293},[266,3706,1528],{"class":293},[266,3708,1562],{"class":343},[266,3710,1533],{"class":293},[266,3712,1575],{"class":343},[266,3714,1522],{"class":293},[266,3716,327],{"class":276},[266,3718,1582],{"class":310},[266,3720,1585],{"class":1083},[266,3722,1554],{"class":293},[266,3724,3725,3727,3729,3731],{"class":268,"line":1590},[266,3726,1593],{"class":276},[266,3728,1596],{"class":728},[266,3730,1599],{"class":343},[266,3732,1554],{"class":293},[266,3734,3735],{"class":268,"line":1604},[266,3736,1607],{"class":310},[266,3738,3739],{"class":268,"line":1610},[266,3740,1613],{"class":310},[266,3742,3743],{"class":268,"line":1616},[266,3744,1619],{"class":293},[266,3746,3747],{"class":268,"line":1622},[266,3748,794],{"emptyLinePlaceholder":793},[266,3750,3751,3753,3755,3757,3759,3761,3763,3765],{"class":268,"line":1627},[266,3752,1630],{"class":272},[266,3754,277],{"class":276},[266,3756,752],{"class":343},[266,3758,725],{"class":293},[266,3760,1639],{"class":289},[266,3762,1642],{"class":343},[266,3764,327],{"class":293},[266,3766,993],{"class":343},[266,3768,3769,3771,3773],{"class":268,"line":1649},[266,3770,1652],{"class":728},[266,3772,1655],{"class":343},[266,3774,1658],{"class":343},[266,3776,3777],{"class":268,"line":1661},[266,3778,794],{"emptyLinePlaceholder":793},[266,3780,3781,3783,3785,3787,3789,3791,3793,3795],{"class":268,"line":1666},[266,3782,1034],{"class":310},[266,3784,1671],{"class":276},[266,3786,1674],{"class":289},[266,3788,1677],{"class":343},[266,3790,1680],{"class":272},[266,3792,1683],{"class":343},[266,3794,1462],{"class":293},[266,3796,1060],{"class":310},[266,3798,3799,3801],{"class":268,"line":1690},[266,3800,1693],{"class":728},[266,3802,1696],{"class":343},[266,3804,3805,3807],{"class":268,"line":1699},[266,3806,1702],{"class":728},[266,3808,1705],{"class":1083},[266,3810,3811],{"class":268,"line":1708},[266,3812,1127],{"class":310},[266,3814,3815],{"class":268,"line":1713},[266,3816,794],{"emptyLinePlaceholder":793},[266,3818,3819],{"class":268,"line":1718},[266,3820,1721],{"class":1286},[266,3822,3823,3825,3827],{"class":268,"line":1724},[266,3824,428],{"class":289},[266,3826,516],{"class":343},[266,3828,519],{"class":343},[266,3830,3831,3833,3835,3837,3839,3841,3843],{"class":268,"line":1733},[266,3832,428],{"class":289},[266,3834,516],{"class":343},[266,3836,528],{"class":343},[266,3838,567],{"class":343},[266,3840,570],{"class":343},[266,3842,573],{"class":343},[266,3844,576],{"class":343},[266,3846,3847],{"class":268,"line":1750},[266,3848,794],{"emptyLinePlaceholder":793},[266,3850,3851],{"class":268,"line":1755},[266,3852,1758],{"class":1286},[266,3854,3855,3857,3859,3861,3863,3865],{"class":268,"line":1761},[266,3856,472],{"class":289},[266,3858,599],{"class":343},[266,3860,740],{"class":343},[266,3862,1770],{"class":272},[266,3864,1773],{"class":343},[266,3866,1776],{"class":343},[266,3868,3869,3871,3873,3875,3877,3879],{"class":268,"line":1779},[266,3870,428],{"class":289},[266,3872,620],{"class":343},[266,3874,623],{"class":343},[266,3876,740],{"class":343},[266,3878,1770],{"class":272},[266,3880,1792],{"class":343},[266,3882,3883],{"class":268,"line":1795},[266,3884,794],{"emptyLinePlaceholder":793},[266,3886,3887],{"class":268,"line":1800},[266,3888,1803],{"class":1286},[266,3890,3891,3893,3895,3897,3899,3901,3903,3905,3907,3909,3911,3913,3915,3917,3919],{"class":268,"line":1806},[266,3892,1809],{"class":272},[266,3894,277],{"class":276},[266,3896,752],{"class":343},[266,3898,725],{"class":293},[266,3900,229],{"class":728},[266,3902,731],{"class":343},[266,3904,734],{"class":293},[266,3906,737],{"class":728},[266,3908,740],{"class":343},[266,3910,743],{"class":272},[266,3912,746],{"class":276},[266,3914,749],{"class":272},[266,3916,752],{"class":343},[266,3918,327],{"class":293},[266,3920,993],{"class":343},[266,3922,3923],{"class":268,"line":1840},[266,3924,794],{"emptyLinePlaceholder":793},[266,3926,3927,3929,3931,3933,3935,3937,3939,3941,3943],{"class":268,"line":1845},[266,3928,428],{"class":289},[266,3930,692],{"class":343},[266,3932,740],{"class":343},[266,3934,1854],{"class":272},[266,3936,752],{"class":343},[266,3938,698],{"class":276},[266,3940,701],{"class":343},[266,3942,704],{"class":276},[266,3944,707],{"class":343},[266,3946,3947],{"class":268,"line":1867},[266,3948,712],{"class":343},[266,3950,3951],{"class":268,"line":1872},[266,3952,717],{"class":343},[266,3954,3955,3957],{"class":268,"line":1877},[266,3956,722],{"class":343},[266,3958,1882],{"class":272},[266,3960,3961],{"class":268,"line":1885},[266,3962,760],{"class":343},[266,3964,3965,3967,3969,3971,3973],{"class":268,"line":1890},[266,3966,766],{"class":343},[266,3968,725],{"class":293},[266,3970,771],{"class":289},[266,3972,774],{"class":343},[266,3974,300],{"class":293},[266,3976,3977,3979],{"class":268,"line":1903},[266,3978,1906],{"class":343},[266,3980,1909],{"class":272},[266,3982,3983],{"class":268,"line":1912},[266,3984,707],{"class":343},[266,3986,3987],{"class":268,"line":1917},[266,3988,794],{"emptyLinePlaceholder":793},[266,3990,3991,3993,3995],{"class":268,"line":1922},[266,3992,428],{"class":289},[266,3994,516],{"class":343},[266,3996,519],{"class":343},[266,3998,3999],{"class":268,"line":1931},[266,4000,794],{"emptyLinePlaceholder":793},[266,4002,4003],{"class":268,"line":1936},[266,4004,1939],{"class":1286},[266,4006,4007],{"class":268,"line":1942},[266,4008,1945],{"class":1286},[266,4010,4011,4013,4015],{"class":268,"line":1948},[266,4012,1951],{"class":272},[266,4014,277],{"class":276},[266,4016,1956],{"class":343},[266,4018,4019,4021,4023,4025,4027,4029],{"class":268,"line":1959},[266,4020,1962],{"class":310},[266,4022,1965],{"class":272},[266,4024,1968],{"class":310},[266,4026,1971],{"class":272},[266,4028,1462],{"class":293},[266,4030,1465],{"class":310},[266,4032,4033,4035,4037,4039,4041,4043,4045,4047,4049],{"class":268,"line":1978},[266,4034,1981],{"class":272},[266,4036,277],{"class":276},[266,4038,752],{"class":343},[266,4040,1988],{"class":272},[266,4042,944],{"class":343},[266,4044,1993],{"class":272},[266,4046,1996],{"class":343},[266,4048,1999],{"class":272},[266,4050,993],{"class":343},[266,4052,4053],{"class":268,"line":2004},[266,4054,2007],{"class":310},[266,4056,4057],{"class":268,"line":2010},[266,4058,794],{"emptyLinePlaceholder":793},[266,4060,4061],{"class":268,"line":2015},[266,4062,2018],{"class":1286},[266,4064,4065,4067,4069,4071,4073],{"class":268,"line":2021},[266,4066,428],{"class":289},[266,4068,516],{"class":343},[266,4070,528],{"class":343},[266,4072,567],{"class":343},[266,4074,2032],{"class":272},[266,4076,4077],{"class":268,"line":2035},[266,4078,794],{"emptyLinePlaceholder":793},[266,4080,4081,4083,4085,4087,4089,4091,4093],{"class":268,"line":2040},[266,4082,428],{"class":289},[266,4084,938],{"class":343},[266,4086,941],{"class":343},[266,4088,944],{"class":343},[266,4090,2051],{"class":343},[266,4092,1993],{"class":272},[266,4094,993],{"class":343},[266,4096,4097],{"class":268,"line":2058},[266,4098,794],{"emptyLinePlaceholder":793},[266,4100,4101,4103],{"class":268,"line":2063},[266,4102,2066],{"class":728},[266,4104,2069],{"class":343},[266,4106,4107,4109],{"class":268,"line":2072},[266,4108,261],{"class":289},[266,4110,954],{"class":343},[266,4112,4113,4115],{"class":268,"line":2079},[266,4114,2066],{"class":728},[266,4116,2069],{"class":343},[266,4118,4119],{"class":268,"line":2086},[266,4120,794],{"emptyLinePlaceholder":793},[266,4122,4123],{"class":268,"line":2091},[266,4124,2094],{"class":1286},[266,4126,4127,4129,4131,4133,4135],{"class":268,"line":2097},[266,4128,1034],{"class":310},[266,4130,1674],{"class":289},[266,4132,2104],{"class":343},[266,4134,1462],{"class":293},[266,4136,1060],{"class":310},[266,4138,4139,4141,4143,4145],{"class":268,"line":2111},[266,4140,2114],{"class":728},[266,4142,740],{"class":343},[266,4144,1770],{"class":272},[266,4146,993],{"class":343},[266,4148,4149],{"class":268,"line":2123},[266,4150,794],{"emptyLinePlaceholder":793},[266,4152,4153,4155,4157,4159,4161,4163,4165,4167],{"class":268,"line":2128},[266,4154,2131],{"class":272},[266,4156,277],{"class":276},[266,4158,752],{"class":343},[266,4160,725],{"class":293},[266,4162,472],{"class":289},[266,4164,988],{"class":343},[266,4166,327],{"class":293},[266,4168,993],{"class":343},[266,4170,4171,4173,4175,4177],{"class":268,"line":2148},[266,4172,2151],{"class":289},[266,4174,599],{"class":343},[266,4176,1002],{"class":343},[266,4178,1005],{"class":343},[266,4180,4181,4183,4185,4187,4189,4191,4193,4195],{"class":268,"line":2160},[266,4182,2163],{"class":272},[266,4184,277],{"class":276},[266,4186,752],{"class":343},[266,4188,725],{"class":293},[266,4190,261],{"class":289},[266,4192,1021],{"class":343},[266,4194,327],{"class":293},[266,4196,993],{"class":343},[266,4198,4199],{"class":268,"line":2180},[266,4200,794],{"emptyLinePlaceholder":793},[266,4202,4203,4205,4207,4209,4211,4213,4215,4217,4219,4221,4223],{"class":268,"line":2185},[266,4204,2188],{"class":310},[266,4206,1037],{"class":293},[266,4208,740],{"class":343},[266,4210,1042],{"class":272},[266,4212,752],{"class":343},[266,4214,2199],{"class":276},[266,4216,740],{"class":343},[266,4218,1052],{"class":272},[266,4220,752],{"class":343},[266,4222,1057],{"class":293},[266,4224,1060],{"class":310},[266,4226,4227,4229,4231],{"class":268,"line":2212},[266,4228,2215],{"class":276},[266,4230,737],{"class":728},[266,4232,2220],{"class":343},[266,4234,4235,4237],{"class":268,"line":2223},[266,4236,2226],{"class":728},[266,4238,2229],{"class":1083},[266,4240,4241],{"class":268,"line":2232},[266,4242,2235],{"class":310},[266,4244,4245],{"class":268,"line":2238},[266,4246,794],{"emptyLinePlaceholder":793},[266,4248,4249,4251,4253],{"class":268,"line":2243},[266,4250,1065],{"class":289},[266,4252,1002],{"class":343},[266,4254,1070],{"class":343},[266,4256,4257,4259,4261,4263,4265,4267],{"class":268,"line":2252},[266,4258,1075],{"class":289},[266,4260,528],{"class":343},[266,4262,1080],{"class":343},[266,4264,1084],{"class":1083},[266,4266,1087],{"class":343},[266,4268,1090],{"class":343},[266,4270,4271],{"class":268,"line":2267},[266,4272,794],{"emptyLinePlaceholder":793},[266,4274,4275,4277],{"class":268,"line":2272},[266,4276,1693],{"class":728},[266,4278,2069],{"class":343},[266,4280,4281,4283],{"class":268,"line":2279},[266,4282,1103],{"class":289},[266,4284,954],{"class":343},[266,4286,4287],{"class":268,"line":2286},[266,4288,1127],{"class":310},[266,4290,4291],{"class":268,"line":2291},[266,4292,794],{"emptyLinePlaceholder":793},[266,4294,4295,4297],{"class":268,"line":2296},[266,4296,2066],{"class":728},[266,4298,2069],{"class":343},[266,4300,4301,4303],{"class":268,"line":2303},[266,4302,2066],{"class":728},[266,4304,2308],{"class":343},[266,4306,4307,4309],{"class":268,"line":2311},[266,4308,2066],{"class":728},[266,4310,2316],{"class":343},[85,4312,4314],{"id":4313},"keep-everything-up-to-date","Keep everything up to date",[10,4316,4317],{},"Once it's installed, keeping it up to date takes just a couple of commands:",[257,4319,4321],{"className":419,"code":4320,"language":421,"meta":262,"style":262},"# Operating system and PHP\nsudo apt update && sudo apt upgrade\n\n# Composer\nsudo composer self-update\n",[50,4322,4323,4328,4344,4348,4352],{"__ignoreMap":262},[266,4324,4325],{"class":268,"line":269},[266,4326,4327],{"class":1286},"# Operating system and PHP\n",[266,4329,4330,4332,4334,4336,4338,4340,4342],{"class":268,"line":283},[266,4331,428],{"class":289},[266,4333,516],{"class":343},[266,4335,2342],{"class":343},[266,4337,2345],{"class":293},[266,4339,617],{"class":289},[266,4341,516],{"class":343},[266,4343,2352],{"class":343},[266,4345,4346],{"class":268,"line":303},[266,4347,794],{"emptyLinePlaceholder":793},[266,4349,4350],{"class":268,"line":361},[266,4351,2361],{"class":1286},[266,4353,4354,4356,4358],{"class":268,"line":757},[266,4355,428],{"class":289},[266,4357,2368],{"class":343},[266,4359,2371],{"class":343},[10,4361,4362,4363,4367],{},"Even on 8.5.12, php.net ",[14,4364,4366],{"href":2377,"rel":4365},[26],"recommends"," disabling session upload progress until the next release, to fully close an unlikely RCE path (CVE-2026-115560). If you serve PHP with FPM, it's a one-liner:",[257,4369,4370],{"className":419,"code":2383,"language":421,"meta":262,"style":262},[50,4371,4372,4386],{"__ignoreMap":262},[266,4373,4374,4376,4378,4380,4382,4384],{"class":268,"line":269},[266,4375,2066],{"class":728},[266,4377,2392],{"class":343},[266,4379,481],{"class":276},[266,4381,617],{"class":289},[266,4383,692],{"class":343},[266,4385,2401],{"class":343},[266,4387,4388,4390,4392,4394],{"class":268,"line":283},[266,4389,428],{"class":289},[266,4391,2408],{"class":343},[266,4393,2411],{"class":343},[266,4395,2414],{"class":343},[10,4397,4398,4399,2681,4404,4409],{},"And don't forget your project dependencies: ",[14,4400,4402],{"href":2420,"rel":4401},[26],[50,4403,2424],{},[14,4405,4407],{"href":2427,"rel":4406},[26],[50,4408,2431],{}," tell you what needs updating and which packages have known vulnerabilities.",[10,4411,4412,4413,4415,4416,4418,4419,4421],{},"Two rounds of PHP security releases in less than a month, one of them an emergency, is a good reminder that you can't predict which patch will matter. What you can do is make applying them boring: one ",[50,4414,651],{}," for PHP, one ",[50,4417,2441],{}," for Composer, and ",[50,4420,2431],{}," for your projects. Set it up once and stop thinking about it.",[2447,4423,2449],{},{"title":262,"searchDepth":283,"depth":283,"links":4425},[4426,4427,4428,4429,4430,4438,4439,4440],{"id":2542,"depth":283,"text":2543},{"id":2641,"depth":283,"text":2642},{"id":2766,"depth":283,"text":2767},{"id":2823,"depth":283,"text":2824},{"id":2894,"depth":283,"text":2895,"children":4431},[4432,4433,4434,4435,4436,4437],{"id":2901,"depth":303,"text":2902},{"id":2939,"depth":303,"text":2940},{"id":2996,"depth":303,"text":2997},{"id":3106,"depth":303,"text":3107},{"id":3190,"depth":303,"text":3191},{"id":3227,"depth":303,"text":3228},{"id":3388,"depth":283,"text":3389},{"id":3459,"depth":283,"text":3460},{"id":4313,"depth":283,"text":4314},"Install PHP 8.5 and Composer on Ubuntu 26.04 LTS with apt from Ondřej Surý's packages.sury.org repository, and keep them patched with apt upgrade.",{},"\u002Fblog\u002Fapt-install-php-85-on-ubuntu-26","11",{"title":2482,"description":4441},"blog\u002F0005.apt-install-php-85-on-ubuntu-26",[261,2477,1268,421],"UDiw6piUSPb35RaXtzbyBoiAaFF7Gz5KN8NSEPa49CA",[4450,4462,4464,4474,4484,4492],{"id":4451,"path":4452,"title":4453,"description":4454,"date":4455,"readingTime":4456,"tags":4457},"blog_es\u002Fes\u002Fblog\u002F0006.lint-tailwind-css-v4-with-eslint.md","\u002Fes\u002Fblog\u002Flint-tailwind-css-v4-with-eslint","@angelblanco\u002Feslint-config 3.0 ya disponible, ahora con Tailwind CSS","@angelblanco\u002Feslint-config 3.0 ya está en npm: lint opcional de Tailwind CSS v4, @antfu\u002Feslint-config v10 y ESLint 10.","2026-11-07","2",[4458,4459,4460,4461],"eslint","tailwindcss","tooling","npm",{"id":4,"path":2472,"title":5,"description":2468,"date":2467,"readingTime":2473,"tags":4463},[261,2477,1268,421],{"id":4465,"path":4466,"title":4467,"description":4468,"date":4469,"readingTime":4470,"tags":4471},"blog_es\u002Fes\u002Fblog\u002F0004.apt-install-node-26-on-ubuntu-26.md","\u002Fes\u002Fblog\u002Fapt-install-node-26-on-ubuntu-26","Instalar Node.js 26 con apt en Ubuntu 26.04","El 21 de octubre de 2026, Node.js publicó parches de seguridad para diez vulnerabilidades que afectan a sus versiones con soporte, cuatro de ellas graves, incluida una ejecución remota de código. Las versiones sin soporte, como Node.js 20 y 25, no recibirán actualizaciones.","2026-11-05","8",[4472,2477,4473,421],"nodejs","javascript",{"id":4475,"path":4476,"title":4477,"description":4478,"date":4479,"readingTime":4480,"tags":4481},"blog_es\u002Fes\u002Fblog\u002F0003.create-your-eslint-config.md","\u002Fes\u002Fblog\u002Fcreate-your-eslint-config","Crea tu propia configuración de ESLint y compártela entre proyectos","Si alguna vez has trabajado en varios proyectos, conoces el aburrimiento de copiar configuraciones de ESLint de un repositorio a otro. Cada vez que empiezas un proyecto nuevo, o partes de cero o copias el archivo eslint.config.js del anterior. Hay una forma mejor: publicar tu propio paquete de configuración de ESLint.","2025-11-02","3",[4458,4482,4483,4460,4461],"typescript","vue",{"id":4485,"path":4486,"title":4487,"description":4488,"date":4489,"readingTime":4490,"tags":4491},"blog_es\u002Fes\u002Fblog\u002F0002.install-node-24-on-ubuntu-24.md","\u002Fes\u002Fblog\u002Finstall-node-24-on-ubuntu-24","Instalar Node.js 24 en Ubuntu 24.04","Instalar Node.js 24 en Ubuntu 24 debería ser un proceso sencillo. Aunque Ubuntu incluye una versión de Node.js en sus repositorios por defecto, es posible que quieras utilizar una versión más reciente, como Node.js 24, que es LTS desde el 28 de octubre de 2025 y tiene soporte hasta abril de 2028. Si vas a instalarlo desde cero, mejor instala Node.js 26 en Ubuntu 26.04. En esta guía te enseño dos métodos para que lo tengas listo rápidamente.","2025-10-12","6",[4472,2477,4473,421],{"id":4493,"path":4494,"title":4495,"description":4496,"date":4497,"readingTime":4498,"tags":4499},"blog_es\u002Fes\u002Fblog\u002F0001.hello.md","\u002Fes\u002Fblog\u002Fhello","De Svelte a Nuxt: Reconstruyendo mi portfolio en 2025","Estamos en 2025 y acabo de publicar una versión completamente nueva de mi web personal. He migrado de un stack basado en Svelte y Sapper a Nuxt, Tailwind CSS y un monorepo con Turborepo. No ha sido un cambio estético, sino una reescritura completa, fruto de cinco años de evolución en el frontend y de las ganas de usar en casa las mismas herramientas que en el trabajo.","2025-09-27","4",[4500,4483,4501,4502,4459],"nuxt","svelte","turborepo",1794096655260]