[{"data":1,"prerenderedAt":2401},["ShallowReactive",2],{"en-main-blog_en-\u002Fblog\u002Fapt-install-php-85-on-ubuntu-26\u002F":3,"en-alternative-blog_es-\u002Fblog\u002Fapt-install-php-85-on-ubuntu-26\u002F":2391},{"id":4,"title":5,"body":6,"date":2388,"description":2389,"extension":2390,"image":2391,"meta":2392,"navigation":719,"path":2393,"schemaOrg":2391,"seo":2394,"stem":2395,"tags":2396,"toc":2399,"updatedAt":2391,"__hash__":2400},"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":8,"toc":2378},"minimark",[9,19,35,68,84,89,98,178,192,200,204,213,254,257,292,296,324,335,358,369,373,385,408,422,428,455,459,462,467,500,507,511,562,581,585,605,730,734,764,812,821,836,840,853,881,885,893,1065,1084,1088,1097,1139,1154,1161,1167,1171,1177,1198,2245,2249,2252,2300,2309,2343,2361,2374],[10,11,12,13,18],"p",{},"Yesterday I posted how to ",[14,15,17],"a",{"href":16},"\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,20,21,22,28,29,34],{},"On September 24, ",[14,23,27],{"href":24,"rel":25},"https:\u002F\u002Fwww.php.net\u002FChangeLog-8.php#8.5.11",[26],"nofollow","PHP 8.5.11"," 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,30,33],{"href":31,"rel":32},"https:\u002F\u002Fwww.php.net\u002Farchive\u002F2026.php#2026-10-21-4",[26],"PHP 8.5.12"," 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,36,37,38,43,44,48,49,53,54,57,58,63,64,67],{},"Here's the catch: ",[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",") 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,51,52],"code",{},"apt"," gives you PHP ",[50,55,56],{},"8.5.4"," with patches on top, while ",[14,59,62],{"href":60,"rel":61},"https:\u002F\u002Fwww.php.net\u002F",[26],"php.net"," is already at ",[50,65,66],{},"8.5.12",". 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,69,70,71,73,74,79,80,83],{},"If you want the full upstream release, the easiest way is still to let the operating system handle it. Install PHP with ",[50,72,52],{}," from ",[14,75,78],{"href":76,"rel":77},"https:\u002F\u002Fdeb.sury.org\u002F",[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,81,82],{},"sudo apt upgrade"," take care of the rest.",[85,86,88],"h3",{"id":87},"support-dates-at-a-glance","Support dates at a glance",[10,90,91,92,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,93,96],{"href":94,"rel":95},"https:\u002F\u002Fwww.php.net\u002Fsupported-versions.php",[26],"official supported versions page",":",[99,100,101,120],"table",{},[102,103,104],"thead",{},[105,106,107,111,114,117],"tr",{},[108,109,110],"th",{},"Version",[108,112,113],{},"Released",[108,115,116],{},"Active support until",[108,118,119],{},"Security support until",[121,122,123,138,152,165],"tbody",{},[105,124,125,129,132,135],{},[126,127,128],"td",{},"8.2",[126,130,131],{},"Dec 8, 2022",[126,133,134],{},"Dec 31, 2024",[126,136,137],{},"Dec 31, 2026",[105,139,140,143,146,149],{},[126,141,142],{},"8.3",[126,144,145],{},"Nov 23, 2023",[126,147,148],{},"Dec 31, 2025",[126,150,151],{},"Dec 31, 2027",[105,153,154,157,160,162],{},[126,155,156],{},"8.4",[126,158,159],{},"Nov 21, 2024",[126,161,137],{},[126,163,164],{},"Dec 31, 2028",[105,166,167,170,173,175],{},[126,168,169],{},"8.5",[126,171,172],{},"Nov 20, 2025",[126,174,151],{},[126,176,177],{},"Dec 31, 2029",[10,179,180,181,186,187,191],{},"If you're still on PHP 8.2, you have less than two months left. ",[14,182,185],{"href":183,"rel":184},"https:\u002F\u002Fwiki.php.net\u002Ftodo\u002Fphp86",[26],"PHP 8.6"," 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,188,190],{"href":189},"#what-about-other-php-versions","below",").",[10,193,194,195,199],{},"On the OS side, ",[14,196,42],{"href":197,"rel":198},"https:\u002F\u002Fubuntu.com\u002Fabout\u002Frelease-cycle",[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,201,203],{"id":202},"whats-new-in-php-85","What's new in PHP 8.5",[10,205,206,207,212],{},"If you're coming from PHP 8.4 or older, here are a few reasons to upgrade beyond security. The ",[14,208,211],{"href":209,"rel":210},"https:\u002F\u002Fwww.php.net\u002Freleases\u002F8.5\u002Fen.php",[26],"release announcement"," has the full list, but my favorites are:",[214,215,216,220,230,237,244],"ul",{},[217,218,219],"li",{},"The pipe operator, to chain callables from left to right without temporary variables.",[217,221,222,225,226,229],{},[50,223,224],{},"clone()"," with properties, which turns the \"with-er\" pattern for ",[50,227,228],{},"readonly"," classes into one line.",[217,231,232,233,236],{},"The ",[50,234,235],{},"#[\\NoDiscard]"," attribute, which warns when someone ignores a return value that matters.",[217,238,239,240,243],{},"A native URI extension, with URL parsing that follows RFC 3986 and WHATWG, no more ",[50,241,242],{},"parse_url()"," surprises.",[217,245,246,249,250,253],{},[50,247,248],{},"array_first()"," and ",[50,251,252],{},"array_last()",". Finally.",[10,255,256],{},"Here's the pipe operator turning a title into a slug:",[258,259,264],"pre",{"className":260,"code":261,"language":262,"meta":263,"style":263},"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,265,266,274,280,286],{"__ignoreMap":263},[267,268,271],"span",{"class":269,"line":270},"line",1,[267,272,273],{},"$slug = $title\n",[267,275,277],{"class":269,"line":276},2,[267,278,279],{},"    |> trim(...)\n",[267,281,283],{"class":269,"line":282},3,[267,284,285],{},"    |> (fn (string $str): string => str_replace(' ', '-', $str))\n",[267,287,289],{"class":269,"line":288},4,[267,290,291],{},"    |> strtolower(...);\n",[85,293,295],{"id":294},"what-changed-goodbye-ppa-hello-packagessuryorg","What changed: goodbye PPA, hello packages.sury.org",[10,297,298,299,302,303,308,309,314,315,318,319,323],{},"If you've installed PHP on Ubuntu before, you probably ran ",[50,300,301],{},"add-apt-repository ppa:ondrej\u002Fphp",". That's no longer the way to go: Ondřej Surý is moving his Ubuntu packages from ",[14,304,307],{"href":305,"rel":306},"https:\u002F\u002Flaunchpad.net\u002F~ondrej\u002F+archive\u002Fubuntu\u002Fphp",[26],"Launchpad"," to ",[14,310,313],{"href":311,"rel":312},"https:\u002F\u002Fpackages.sury.org\u002Fphp\u002F",[26],"packages.sury.org",", the server that already hosts the Debian ones. The ",[50,316,317],{},"resolute"," packages for Ubuntu 26.04 are ",[320,321,322],"strong",{},"only"," published there.",[10,325,326,327,330,331,334],{},"If you still have the PPA configured, you may have seen ",[50,328,329],{},"apt update"," complain this summer that the repository changed its 'Label' value, an error that made ",[50,332,333],{},"apt-get update"," 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:",[258,336,340],{"className":337,"code":338,"language":339,"meta":263,"style":263},"language-bash shiki shiki-themes catppuccin-latte catppuccin-mocha","sudo add-apt-repository --remove ppa:ondrej\u002Fphp\n","bash",[50,341,342],{"__ignoreMap":263},[267,343,344,348,352,355],{"class":269,"line":270},[267,345,347],{"class":346},"sMmZK","sudo",[267,349,351],{"class":350},"sgueU"," add-apt-repository",[267,353,354],{"class":350}," --remove",[267,356,357],{"class":350}," ppa:ondrej\u002Fphp\n",[10,359,360,361,364,365,368],{},"The new setup also improves how the signing key is handled. Instead of downloading a raw ",[50,362,363],{},".gpg"," file, you install the official ",[50,366,367],{},"debsuryorg-archive-keyring"," package.",[85,370,372],{"id":371},"the-easy-way","The easy way",[10,374,375,376,378,379,384],{},"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,377,262],{},", and optionally installs ",[14,380,383],{"href":381,"rel":382},"https:\u002F\u002Fgetcomposer.org\u002F",[26],"Composer",".",[258,386,388],{"className":337,"code":387,"language":339,"meta":263,"style":263},"curl -fsSL https:\u002F\u002Fangelblanco.dev\u002Fscripts\u002Fubuntu-install-php-85.sh | bash\n",[50,389,390],{"__ignoreMap":263},[267,391,392,395,398,401,405],{"class":269,"line":270},[267,393,394],{"class":346},"curl",[267,396,397],{"class":350}," -fsSL",[267,399,400],{"class":350}," https:\u002F\u002Fangelblanco.dev\u002Fscripts\u002Fubuntu-install-php-85.sh",[267,402,404],{"class":403},"sjJjI"," |",[267,406,407],{"class":346}," bash\n",[10,409,410,411,415,416,418,419,421],{},"The script asks for confirmation at each major step. As always, read ",[14,412,414],{"href":413},"#the-script","the script"," before you pipe it into ",[50,417,339],{},". Trusting random URLs with ",[50,420,347],{}," is a great way to learn about incident response.",[10,423,424,425,427],{},"If you don't have ",[50,426,394],{}," installed:",[258,429,431],{"className":337,"code":430,"language":339,"meta":263,"style":263},"sudo apt update\nsudo apt install curl\n",[50,432,433,443],{"__ignoreMap":263},[267,434,435,437,440],{"class":269,"line":270},[267,436,347],{"class":346},[267,438,439],{"class":350}," apt",[267,441,442],{"class":350}," update\n",[267,444,445,447,449,452],{"class":269,"line":276},[267,446,347],{"class":346},[267,448,439],{"class":350},[267,450,451],{"class":350}," install",[267,453,454],{"class":350}," curl\n",[85,456,458],{"id":457},"the-step-by-step-guide","The step-by-step guide",[10,460,461],{},"Here's what the script does, in case you want to run it step by step.",[463,464,466],"h4",{"id":465},"_1-install-the-prerequisites","1. Install the prerequisites",[258,468,470],{"className":337,"code":469,"language":339,"meta":263,"style":263},"sudo apt update\nsudo apt install -y ca-certificates curl unzip\n",[50,471,472,480],{"__ignoreMap":263},[267,473,474,476,478],{"class":269,"line":270},[267,475,347],{"class":346},[267,477,439],{"class":350},[267,479,442],{"class":350},[267,481,482,484,486,488,491,494,497],{"class":269,"line":276},[267,483,347],{"class":346},[267,485,439],{"class":350},[267,487,451],{"class":350},[267,489,490],{"class":350}," -y",[267,492,493],{"class":350}," ca-certificates",[267,495,496],{"class":350}," curl",[267,498,499],{"class":350}," unzip\n",[10,501,502,503,506],{},"PHP doesn't need ",[50,504,505],{},"unzip",", but Composer uses it to extract packages much faster than its PHP fallback.",[463,508,510],{"id":509},"_2-install-the-sury-signing-key","2. Install the Sury signing key",[258,512,514],{"className":337,"code":513,"language":339,"meta":263,"style":263},"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,515,516,533,552],{"__ignoreMap":263},[267,517,518,520,523,526,529],{"class":269,"line":270},[267,519,394],{"class":346},[267,521,522],{"class":350}," -fsSLo",[267,524,525],{"class":350}," \u002Ftmp\u002Fdebsuryorg-archive-keyring.deb",[267,527,528],{"class":350}," https:\u002F\u002Fpackages.sury.org\u002Fdebsuryorg-archive-keyring.deb",[267,530,532],{"class":531},"sNVtu"," \\\n",[267,534,535,539,542,545,548,550],{"class":269,"line":276},[267,536,538],{"class":537},"sxyLT","  &&",[267,540,541],{"class":346}," sudo",[267,543,544],{"class":350}," dpkg",[267,546,547],{"class":350}," -i",[267,549,525],{"class":350},[267,551,532],{"class":531},[267,553,554,556,559],{"class":269,"line":282},[267,555,538],{"class":537},[267,557,558],{"class":346}," rm",[267,560,561],{"class":350}," \u002Ftmp\u002Fdebsuryorg-archive-keyring.deb\n",[10,563,564,565,568,569,572,573,576,577,580],{},"This drops the key in ",[50,566,567],{},"\u002Fusr\u002Fshare\u002Fkeyrings\u002Fdebsuryorg-archive-keyring.gpg"," (plus, for now, a global copy in ",[50,570,571],{},"\u002Fetc\u002Fapt\u002Ftrusted.gpg.d\u002F","). On Debian the repository also ships the keyring package, so key rotations arrive with ",[50,574,575],{},"apt upgrade",". The Ubuntu suites don't ship it yet, so if the key is ever rotated, download and install the ",[50,578,579],{},".deb"," again.",[463,582,584],{"id":583},"_3-add-the-sury-repository","3. Add the Sury repository",[10,586,587,588,43,593,596,597,600,601,604],{},"Since 24.04, Ubuntu uses the ",[14,589,592],{"href":590,"rel":591},"https:\u002F\u002Fmanpages.ubuntu.com\u002Fmanpages\u002Fresolute\u002Fman5\u002Fsources.list.5.html",[26],"deb822 format",[50,594,595],{},".sources"," files) for its own repositories, and the classic one-line ",[50,598,599],{},".list"," format is now officially deprecated. The codename is read from ",[50,602,603],{},"\u002Fetc\u002Fos-release",", so the same snippet also works on Ubuntu 22.04 and 24.04, and on derivatives like Linux Mint.",[258,606,608],{"className":337,"code":607,"language":339,"meta":263,"style":263},"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,609,610,632,637,642,681,687,703,709,714,721],{"__ignoreMap":263},[267,611,612,614,617,620,623,626,629],{"class":269,"line":270},[267,613,347],{"class":346},[267,615,616],{"class":350}," tee",[267,618,619],{"class":350}," \u002Fetc\u002Fapt\u002Fsources.list.d\u002Fphp.sources",[267,621,622],{"class":403}," >",[267,624,625],{"class":350}," \u002Fdev\u002Fnull",[267,627,628],{"class":403}," \u003C\u003C",[267,630,631],{"class":350},"EOF\n",[267,633,634],{"class":269,"line":276},[267,635,636],{"class":350},"Types: deb\n",[267,638,639],{"class":269,"line":282},[267,640,641],{"class":350},"URIs: https:\u002F\u002Fpackages.sury.org\u002Fphp\u002F\n",[267,643,644,647,650,653,656,659,662,665,669,672,675,678],{"class":269,"line":288},[267,645,646],{"class":350},"Suites: ",[267,648,649],{"class":537},"$(",[267,651,384],{"class":652},"s-0VM",[267,654,655],{"class":350}," \u002Fetc\u002Fos-release ",[267,657,658],{"class":537},"&&",[267,660,661],{"class":652}," echo",[267,663,664],{"class":350}," \"",[267,666,668],{"class":667},"s0aCy","${UBUNTU_CODENAME",[267,670,671],{"class":403},":-",[267,673,674],{"class":667},"$VERSION_CODENAME}",[267,676,677],{"class":350},"\"",[267,679,680],{"class":537},")\n",[267,682,684],{"class":269,"line":683},5,[267,685,686],{"class":350},"Components: main\n",[267,688,690,693,695,698,701],{"class":269,"line":689},6,[267,691,692],{"class":350},"Architectures: ",[267,694,649],{"class":537},[267,696,697],{"class":346},"dpkg",[267,699,700],{"class":350}," --print-architecture",[267,702,680],{"class":537},[267,704,706],{"class":269,"line":705},7,[267,707,708],{"class":350},"Signed-By: \u002Fusr\u002Fshare\u002Fkeyrings\u002Fdebsuryorg-archive-keyring.gpg\n",[267,710,712],{"class":269,"line":711},8,[267,713,631],{"class":350},[267,715,717],{"class":269,"line":716},9,[267,718,720],{"emptyLinePlaceholder":719},true,"\n",[267,722,724,726,728],{"class":269,"line":723},10,[267,725,347],{"class":346},[267,727,439],{"class":350},[267,729,442],{"class":350},[463,731,733],{"id":732},"_4-install-php-85","4. Install PHP 8.5",[258,735,737],{"className":337,"code":736,"language":339,"meta":263,"style":263},"sudo apt install -y php8.5-cli php8.5-mbstring php8.5-curl php8.5-zip php8.5-xml\n",[50,738,739],{"__ignoreMap":263},[267,740,741,743,745,747,749,752,755,758,761],{"class":269,"line":270},[267,742,347],{"class":346},[267,744,439],{"class":350},[267,746,451],{"class":350},[267,748,490],{"class":350},[267,750,751],{"class":350}," php8.5-cli",[267,753,754],{"class":350}," php8.5-mbstring",[267,756,757],{"class":350}," php8.5-curl",[267,759,760],{"class":350}," php8.5-zip",[267,762,763],{"class":350}," php8.5-xml\n",[10,765,766,767,770,771,774,775,780,781,788,789,794,795,800,801,804,805,808,809,384],{},"Notice that we install ",[50,768,769],{},"php8.5-cli"," instead of the bare ",[50,772,773],{},"php8.5"," metapackage. The metapackage pulls in ",[14,776,779],{"href":777,"rel":778},"https:\u002F\u002Fhttpd.apache.org\u002F",[26],"Apache"," and its PHP module, which you probably don't want on your development machine. If you need a web server, add ",[14,782,785],{"href":783,"rel":784},"https:\u002F\u002Fwww.php.net\u002Fmanual\u002Fen\u002Finstall.fpm.php",[26],[50,786,787],{},"php8.5-fpm"," and pair it with ",[14,790,793],{"href":791,"rel":792},"https:\u002F\u002Fnginx.org\u002F",[26],"Nginx"," or ",[14,796,799],{"href":797,"rel":798},"https:\u002F\u002Fcaddyserver.com\u002F",[26],"Caddy",". Need a database? Add ",[50,802,803],{},"php8.5-mysql",", ",[50,806,807],{},"php8.5-pgsql",", or ",[50,810,811],{},"php8.5-sqlite3",[10,813,814,815,817,818,820],{},"You don't need an apt pin: Sury's ",[50,816,66],{}," has a higher version than Ubuntu's ",[50,819,56],{},", so apt picks it automatically. You can check where each package comes from with:",[258,822,824],{"className":337,"code":823,"language":339,"meta":263,"style":263},"apt policy php8.5-cli\n",[50,825,826],{"__ignoreMap":263},[267,827,828,830,833],{"class":269,"line":270},[267,829,52],{"class":346},[267,831,832],{"class":350}," policy",[267,834,835],{"class":350}," php8.5-cli\n",[463,837,839],{"id":838},"_5-make-php-85-the-default","5. Make PHP 8.5 the default",[10,841,232,842,844,845,852],{},[50,843,262],{}," command is managed by ",[14,846,849],{"href":847,"rel":848},"https:\u002F\u002Fmanpages.ubuntu.com\u002Fmanpages\u002Fresolute\u002Fman1\u002Fupdate-alternatives.1.html",[26],[50,850,851],{},"update-alternatives",", so you can choose which version answers to it:",[258,854,856],{"className":337,"code":855,"language":339,"meta":263,"style":263},"sudo update-alternatives --set php \u002Fusr\u002Fbin\u002Fphp8.5\nphp --version\n",[50,857,858,874],{"__ignoreMap":263},[267,859,860,862,865,868,871],{"class":269,"line":270},[267,861,347],{"class":346},[267,863,864],{"class":350}," update-alternatives",[267,866,867],{"class":350}," --set",[267,869,870],{"class":350}," php",[267,872,873],{"class":350}," \u002Fusr\u002Fbin\u002Fphp8.5\n",[267,875,876,878],{"class":269,"line":276},[267,877,262],{"class":346},[267,879,880],{"class":350}," --version\n",[463,882,884],{"id":883},"_6-install-composer","6. Install Composer",[10,886,232,887,892],{},[14,888,891],{"href":889,"rel":890},"https:\u002F\u002Fgetcomposer.org\u002Fdownload\u002F",[26],"official installer"," publishes a SHA-384 checksum, so verify it before running anything:",[258,894,896],{"className":337,"code":895,"language":339,"meta":263,"style":263},"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,897,898,921,933,953,957,989,999,1019,1027,1034,1039,1050,1056],{"__ignoreMap":263},[267,899,900,903,906,908,910,912,915,918],{"class":269,"line":270},[267,901,902],{"class":667},"EXPECTED_CHECKSUM",[267,904,905],{"class":403},"=",[267,907,677],{"class":350},[267,909,649],{"class":537},[267,911,394],{"class":346},[267,913,914],{"class":350}," -fsSL https:\u002F\u002Fcomposer.github.io\u002Finstaller.sig",[267,916,917],{"class":537},")",[267,919,920],{"class":350},"\"\n",[267,922,923,925,927,930],{"class":269,"line":276},[267,924,394],{"class":346},[267,926,522],{"class":350},[267,928,929],{"class":350}," composer-setup.php",[267,931,932],{"class":350}," https:\u002F\u002Fgetcomposer.org\u002Finstaller\n",[267,934,935,938,940,942,944,946,949,951],{"class":269,"line":282},[267,936,937],{"class":667},"ACTUAL_CHECKSUM",[267,939,905],{"class":403},[267,941,677],{"class":350},[267,943,649],{"class":537},[267,945,262],{"class":346},[267,947,948],{"class":350}," -r \"echo hash_file('sha384', 'composer-setup.php');\"",[267,950,917],{"class":537},[267,952,920],{"class":350},[267,954,955],{"class":269,"line":288},[267,956,720],{"emptyLinePlaceholder":719},[267,958,959,963,966,968,971,973,976,978,981,983,986],{"class":269,"line":683},[267,960,962],{"class":961},"sAS4m","if",[267,964,965],{"class":537}," [",[267,967,664],{"class":350},[267,969,970],{"class":667},"$EXPECTED_CHECKSUM",[267,972,677],{"class":350},[267,974,975],{"class":403}," =",[267,977,664],{"class":350},[267,979,980],{"class":667},"$ACTUAL_CHECKSUM",[267,982,677],{"class":350},[267,984,985],{"class":537}," ];",[267,987,988],{"class":961}," then\n",[267,990,991,994,996],{"class":269,"line":689},[267,992,993],{"class":346},"    php",[267,995,929],{"class":350},[267,997,998],{"class":350}," --quiet\n",[267,1000,1001,1004,1006,1009,1013,1016],{"class":269,"line":705},[267,1002,1003],{"class":346},"    sudo",[267,1005,451],{"class":350},[267,1007,1008],{"class":350}," -m",[267,1010,1012],{"class":1011},"st0oN"," 0755",[267,1014,1015],{"class":350}," composer.phar",[267,1017,1018],{"class":350}," \u002Fusr\u002Flocal\u002Fbin\u002Fcomposer\n",[267,1020,1021,1024],{"class":269,"line":711},[267,1022,1023],{"class":346},"    rm",[267,1025,1026],{"class":350}," composer.phar\n",[267,1028,1029,1032],{"class":269,"line":716},[267,1030,1031],{"class":346},"    composer",[267,1033,880],{"class":350},[267,1035,1036],{"class":269,"line":723},[267,1037,1038],{"class":961},"else\n",[267,1040,1042,1045,1047],{"class":269,"line":1041},11,[267,1043,1044],{"class":403},"    >&2",[267,1046,661],{"class":652},[267,1048,1049],{"class":350}," \"ERROR: Invalid Composer installer checksum\"\n",[267,1051,1053],{"class":269,"line":1052},12,[267,1054,1055],{"class":961},"fi\n",[267,1057,1059,1062],{"class":269,"line":1058},13,[267,1060,1061],{"class":346},"rm",[267,1063,1064],{"class":350}," composer-setup.php\n",[10,1066,1067,1068,1071,1072,1075,1076,1079,1080,1083],{},"Using ",[50,1069,1070],{},"install"," instead of ",[50,1073,1074],{},"mv"," makes ",[50,1077,1078],{},"root"," the owner of the binary, which matters because you'll run ",[50,1081,1082],{},"sudo composer self-update"," later.",[85,1085,1087],{"id":1086},"what-about-other-php-versions","What about other PHP versions?",[10,1089,1090,1091,308,1094,1096],{},"This is where the Sury repository really shines. It publishes every branch from ",[50,1092,1093],{},"php5.6",[50,1095,773],{},", plus the PHP 8.6 release candidates, and they can all live side by side:",[258,1098,1100],{"className":337,"code":1099,"language":339,"meta":263,"style":263},"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,1101,1102,1127],{"__ignoreMap":263},[267,1103,1104,1106,1108,1110,1112,1115,1118,1121,1124],{"class":269,"line":270},[267,1105,347],{"class":346},[267,1107,439],{"class":350},[267,1109,451],{"class":350},[267,1111,490],{"class":350},[267,1113,1114],{"class":350}," php8.4-cli",[267,1116,1117],{"class":350}," php8.4-mbstring",[267,1119,1120],{"class":350}," php8.4-curl",[267,1122,1123],{"class":350}," php8.4-zip",[267,1125,1126],{"class":350}," php8.4-xml\n",[267,1128,1129,1131,1133,1136],{"class":269,"line":276},[267,1130,347],{"class":346},[267,1132,864],{"class":350},[267,1134,1135],{"class":350}," --config",[267,1137,1138],{"class":350}," php\n",[10,1140,1141,1144,1145,1147,1148,794,1151,1153],{},[50,1142,1143],{},"update-alternatives --config php"," shows an interactive menu to switch the default ",[50,1146,262],{},". You can also call a specific version directly with ",[50,1149,1150],{},"php8.4",[50,1152,773],{},", which is handy for running a legacy project's tests without touching your default.",[10,1155,1156,1157,1160],{},"If you try 8.6 before its final release on November 19, check ",[50,1158,1159],{},"apt policy php8.6-cli",": builds older than RC4 don't include the October RCE fixes.",[10,1162,1163,1164,1166],{},"Keep in mind that every version you install is one more you have to keep patched. With Sury, at least, ",[50,1165,575],{}," patches all of them at once.",[85,1168,1170],{"id":1169},"the-script","The script",[10,1172,1173,1174,1176],{},"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,1175,394],{},". You can change the PHP version and the extensions with the variables at the top.",[10,1178,1179,1180,1185,1186,1191,1192,249,1194,1197],{},"This script comes from my ",[14,1181,1184],{"href":1182,"rel":1183},"https:\u002F\u002Fgithub.com\u002Fangelblanco\u002Fkickstart.nvim",[26],"Neovim configuration repo",", where I keep my ",[14,1187,1190],{"href":1188,"rel":1189},"https:\u002F\u002Fgithub.com\u002Fangelblanco\u002Fkickstart.nvim\u002Fblob\u002Fmaster\u002Finstall\u002Finstall-php.sh",[26],"install scripts",". The editor needs ",[50,1193,262],{},[50,1195,1196],{},"composer"," for the PHP language servers and formatters to work, so I update them regularly. If you want the latest version, look there first.",[258,1199,1202],{"className":337,"code":1200,"filename":1201,"language":339,"meta":263,"style":263},"#!\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,1203,1204,1210,1216,1221,1226,1230,1235,1239,1244,1248,1253,1258,1262,1267,1273,1279,1284,1289,1301,1306,1312,1323,1334,1345,1356,1361,1367,1379,1394,1424,1440,1484,1517,1531,1537,1543,1549,1554,1576,1588,1593,1617,1626,1635,1640,1645,1651,1660,1677,1682,1688,1706,1722,1727,1733,1767,1772,1794,1799,1804,1812,1817,1830,1839,1844,1849,1858,1863,1869,1875,1886,1905,1931,1937,1942,1948,1962,1967,1985,1990,1999,2006,2013,2018,2024,2038,2050,2055,2075,2087,2107,2112,2139,2149,2158,2164,2169,2178,2193,2198,2205,2212,2217,2222,2229,2237],{"__ignoreMap":263},[267,1205,1206],{"class":269,"line":270},[267,1207,1209],{"class":1208},"skWWU","#!\u002Fbin\u002Fbash\n",[267,1211,1212],{"class":269,"line":276},[267,1213,1215],{"class":1214},"som-u","#\n",[267,1217,1218],{"class":269,"line":282},[267,1219,1220],{"class":1214},"# Author: Ángel Blanco\n",[267,1222,1223],{"class":269,"line":288},[267,1224,1225],{"class":1214},"# License: MIT\n",[267,1227,1228],{"class":269,"line":683},[267,1229,1215],{"class":1214},[267,1231,1232],{"class":269,"line":689},[267,1233,1234],{"class":1214},"# This script is provided \"as is\", without warranty of any kind. Use at your own risk.\n",[267,1236,1237],{"class":269,"line":705},[267,1238,1215],{"class":1214},[267,1240,1241],{"class":269,"line":711},[267,1242,1243],{"class":1214},"# Source: https:\u002F\u002Fangelblanco.dev\u002Fblog\u002Fapt-install-php-85-on-ubuntu-26\n",[267,1245,1246],{"class":269,"line":716},[267,1247,1215],{"class":1214},[267,1249,1250],{"class":269,"line":723},[267,1251,1252],{"class":1214},"# Usage:\n",[267,1254,1255],{"class":269,"line":1041},[267,1256,1257],{"class":1214},"#   curl -fsSL https:\u002F\u002Fangelblanco.dev\u002Fscripts\u002Fubuntu-install-php-85.sh | bash\n",[267,1259,1260],{"class":269,"line":1052},[267,1261,1215],{"class":1214},[267,1263,1264],{"class":269,"line":1058},[267,1265,1266],{"class":1214},"# Install PHP (from packages.sury.org) and Composer on Ubuntu.\n",[267,1268,1270],{"class":269,"line":1269},14,[267,1271,1272],{"class":1214},"# Normally you will call it from your non-root user; elevated permissions\n",[267,1274,1276],{"class":269,"line":1275},15,[267,1277,1278],{"class":1214},"# will be granted with sudo.\n",[267,1280,1282],{"class":269,"line":1281},16,[267,1283,1215],{"class":1214},[267,1285,1287],{"class":269,"line":1286},17,[267,1288,720],{"emptyLinePlaceholder":719},[267,1290,1292,1295,1298],{"class":269,"line":1291},18,[267,1293,1294],{"class":652},"set",[267,1296,1297],{"class":350}," -euo",[267,1299,1300],{"class":350}," pipefail\n",[267,1302,1304],{"class":269,"line":1303},19,[267,1305,720],{"emptyLinePlaceholder":719},[267,1307,1309],{"class":269,"line":1308},20,[267,1310,1311],{"class":1214},"# You can configure these variables if needed\n",[267,1313,1315,1318,1320],{"class":269,"line":1314},21,[267,1316,1317],{"class":667},"PHP_VERSION",[267,1319,905],{"class":403},[267,1321,1322],{"class":350},"\"8.5\"\n",[267,1324,1326,1329,1331],{"class":269,"line":1325},22,[267,1327,1328],{"class":667},"PHP_EXTENSIONS",[267,1330,905],{"class":403},[267,1332,1333],{"class":350},"\"cli mbstring curl zip xml\"\n",[267,1335,1337,1340,1342],{"class":269,"line":1336},23,[267,1338,1339],{"class":667},"KEYRING",[267,1341,905],{"class":403},[267,1343,1344],{"class":350},"\"\u002Fusr\u002Fshare\u002Fkeyrings\u002Fdebsuryorg-archive-keyring.gpg\"\n",[267,1346,1348,1351,1353],{"class":269,"line":1347},24,[267,1349,1350],{"class":667},"SOURCE_FILE",[267,1352,905],{"class":403},[267,1354,1355],{"class":350},"\"\u002Fetc\u002Fapt\u002Fsources.list.d\u002Fphp.sources\"\n",[267,1357,1359],{"class":269,"line":1358},25,[267,1360,720],{"emptyLinePlaceholder":719},[267,1362,1364],{"class":269,"line":1363},26,[267,1365,1366],{"class":1214},"# Basic confirmation module before executing the script.\n",[267,1368,1370,1373,1376],{"class":269,"line":1369},27,[267,1371,1372],{"class":346},"confirm_action",[267,1374,1375],{"class":537},"()",[267,1377,1378],{"class":537}," {\n",[267,1380,1382,1385,1388,1391],{"class":269,"line":1381},28,[267,1383,1384],{"class":961},"    while",[267,1386,1387],{"class":350}," true",[267,1389,1390],{"class":537},";",[267,1392,1393],{"class":961}," do\n",[267,1395,1397,1400,1403,1406,1408,1412,1415,1418,1421],{"class":269,"line":1396},29,[267,1398,1399],{"class":652},"        read",[267,1401,1402],{"class":350}," -r",[267,1404,1405],{"class":350}," -p",[267,1407,664],{"class":350},[267,1409,1411],{"class":1410},"s2f33","$1",[267,1413,1414],{"class":350}," (y\u002Fn): \"",[267,1416,1417],{"class":350}," choice",[267,1419,1420],{"class":403}," \u003C",[267,1422,1423],{"class":350}," \u002Fdev\u002Ftty\n",[267,1425,1427,1430,1432,1435,1437],{"class":269,"line":1426},30,[267,1428,1429],{"class":961},"        case",[267,1431,664],{"class":350},[267,1433,1434],{"class":667},"$choice",[267,1436,677],{"class":350},[267,1438,1439],{"class":961}," in\n",[267,1441,1443,1446,1449,1452,1455,1458,1460,1463,1466,1468,1471,1473,1475,1478,1481],{"class":269,"line":1442},31,[267,1444,1445],{"class":537},"            [",[267,1447,1448],{"class":350},"Yy",[267,1450,1451],{"class":537},"]",[267,1453,1454],{"class":537},"|",[267,1456,1457],{"class":537},"[",[267,1459,1448],{"class":350},[267,1461,1462],{"class":537},"][",[267,1464,1465],{"class":350},"Ee",[267,1467,1462],{"class":537},[267,1469,1470],{"class":350},"Ss",[267,1472,1451],{"class":537},[267,1474,917],{"class":403},[267,1476,1477],{"class":961}," return",[267,1479,1480],{"class":1011}," 0",[267,1482,1483],{"class":537}," ;;\n",[267,1485,1487,1489,1492,1494,1496,1498,1500,1502,1505,1507,1509,1512,1515],{"class":269,"line":1486},32,[267,1488,1445],{"class":537},[267,1490,1491],{"class":350},"Nn",[267,1493,1451],{"class":537},[267,1495,1454],{"class":537},[267,1497,1457],{"class":537},[267,1499,1491],{"class":350},[267,1501,1462],{"class":537},[267,1503,1504],{"class":350},"Oo",[267,1506,1451],{"class":537},[267,1508,917],{"class":403},[267,1510,1511],{"class":961},"     return",[267,1513,1514],{"class":1011}," 1",[267,1516,1483],{"class":537},[267,1518,1520,1523,1526,1529],{"class":269,"line":1519},33,[267,1521,1522],{"class":403},"            *)",[267,1524,1525],{"class":652},"                 echo",[267,1527,1528],{"class":350}," \"Invalid choice. Please enter 'y' or 'n'.\"",[267,1530,1483],{"class":537},[267,1532,1534],{"class":269,"line":1533},34,[267,1535,1536],{"class":961},"        esac\n",[267,1538,1540],{"class":269,"line":1539},35,[267,1541,1542],{"class":961},"    done\n",[267,1544,1546],{"class":269,"line":1545},36,[267,1547,1548],{"class":537},"}\n",[267,1550,1552],{"class":269,"line":1551},37,[267,1553,720],{"emptyLinePlaceholder":719},[267,1555,1557,1560,1562,1564,1566,1569,1572,1574],{"class":269,"line":1556},38,[267,1558,1559],{"class":667},"WORKDIR",[267,1561,905],{"class":403},[267,1563,677],{"class":350},[267,1565,649],{"class":537},[267,1567,1568],{"class":346},"mktemp",[267,1570,1571],{"class":350}," -d",[267,1573,917],{"class":537},[267,1575,920],{"class":350},[267,1577,1579,1582,1585],{"class":269,"line":1578},39,[267,1580,1581],{"class":652},"trap",[267,1583,1584],{"class":350}," 'rm -rf \"$WORKDIR\"'",[267,1586,1587],{"class":350}," EXIT\n",[267,1589,1591],{"class":269,"line":1590},40,[267,1592,720],{"emptyLinePlaceholder":719},[267,1594,1596,1598,1601,1604,1607,1610,1613,1615],{"class":269,"line":1595},41,[267,1597,962],{"class":961},[267,1599,1600],{"class":403}," !",[267,1602,1603],{"class":346}," confirm_action",[267,1605,1606],{"class":350}," \"Install PHP ",[267,1608,1609],{"class":667},"$PHP_VERSION",[267,1611,1612],{"class":350}," from packages.sury.org?\"",[267,1614,1390],{"class":537},[267,1616,988],{"class":961},[267,1618,1620,1623],{"class":269,"line":1619},42,[267,1621,1622],{"class":652},"    echo",[267,1624,1625],{"class":350}," \"Skipping PHP installation. Exiting.\"\n",[267,1627,1629,1632],{"class":269,"line":1628},43,[267,1630,1631],{"class":652},"    exit",[267,1633,1634],{"class":1011}," 0\n",[267,1636,1638],{"class":269,"line":1637},44,[267,1639,1055],{"class":961},[267,1641,1643],{"class":269,"line":1642},45,[267,1644,720],{"emptyLinePlaceholder":719},[267,1646,1648],{"class":269,"line":1647},46,[267,1649,1650],{"class":1214},"# --- Prerequisites ---------------------------------------------------------\n",[267,1652,1654,1656,1658],{"class":269,"line":1653},47,[267,1655,347],{"class":346},[267,1657,439],{"class":350},[267,1659,442],{"class":350},[267,1661,1663,1665,1667,1669,1671,1673,1675],{"class":269,"line":1662},48,[267,1664,347],{"class":346},[267,1666,439],{"class":350},[267,1668,451],{"class":350},[267,1670,490],{"class":350},[267,1672,493],{"class":350},[267,1674,496],{"class":350},[267,1676,499],{"class":350},[267,1678,1680],{"class":269,"line":1679},49,[267,1681,720],{"emptyLinePlaceholder":719},[267,1683,1685],{"class":269,"line":1684},50,[267,1686,1687],{"class":1214},"# --- Sury signing key (official keyring package) ---------------------------\n",[267,1689,1691,1693,1695,1697,1700,1703],{"class":269,"line":1690},51,[267,1692,394],{"class":346},[267,1694,522],{"class":350},[267,1696,664],{"class":350},[267,1698,1699],{"class":667},"$WORKDIR",[267,1701,1702],{"class":350},"\u002Fdebsuryorg-archive-keyring.deb\"",[267,1704,1705],{"class":350}," https:\u002F\u002Fpackages.sury.org\u002Fdebsuryorg-archive-keyring.deb\n",[267,1707,1709,1711,1713,1715,1717,1719],{"class":269,"line":1708},52,[267,1710,347],{"class":346},[267,1712,544],{"class":350},[267,1714,547],{"class":350},[267,1716,664],{"class":350},[267,1718,1699],{"class":667},[267,1720,1721],{"class":350},"\u002Fdebsuryorg-archive-keyring.deb\"\n",[267,1723,1725],{"class":269,"line":1724},53,[267,1726,720],{"emptyLinePlaceholder":719},[267,1728,1730],{"class":269,"line":1729},54,[267,1731,1732],{"class":1214},"# --- Sury repository --------------------------------------------------------\n",[267,1734,1736,1739,1741,1743,1745,1747,1749,1751,1753,1755,1757,1759,1761,1763,1765],{"class":269,"line":1735},55,[267,1737,1738],{"class":667},"CODENAME",[267,1740,905],{"class":403},[267,1742,677],{"class":350},[267,1744,649],{"class":537},[267,1746,384],{"class":652},[267,1748,655],{"class":350},[267,1750,658],{"class":537},[267,1752,661],{"class":652},[267,1754,664],{"class":350},[267,1756,668],{"class":667},[267,1758,671],{"class":403},[267,1760,674],{"class":667},[267,1762,677],{"class":350},[267,1764,917],{"class":537},[267,1766,920],{"class":350},[267,1768,1770],{"class":269,"line":1769},56,[267,1771,720],{"emptyLinePlaceholder":719},[267,1773,1775,1777,1779,1781,1784,1786,1788,1790,1792],{"class":269,"line":1774},57,[267,1776,347],{"class":346},[267,1778,616],{"class":350},[267,1780,664],{"class":350},[267,1782,1783],{"class":667},"$SOURCE_FILE",[267,1785,677],{"class":350},[267,1787,622],{"class":403},[267,1789,625],{"class":350},[267,1791,628],{"class":403},[267,1793,631],{"class":350},[267,1795,1797],{"class":269,"line":1796},58,[267,1798,636],{"class":350},[267,1800,1802],{"class":269,"line":1801},59,[267,1803,641],{"class":350},[267,1805,1807,1809],{"class":269,"line":1806},60,[267,1808,646],{"class":350},[267,1810,1811],{"class":667},"$CODENAME\n",[267,1813,1815],{"class":269,"line":1814},61,[267,1816,686],{"class":350},[267,1818,1820,1822,1824,1826,1828],{"class":269,"line":1819},62,[267,1821,692],{"class":350},[267,1823,649],{"class":537},[267,1825,697],{"class":346},[267,1827,700],{"class":350},[267,1829,680],{"class":537},[267,1831,1833,1836],{"class":269,"line":1832},63,[267,1834,1835],{"class":350},"Signed-By: ",[267,1837,1838],{"class":667},"$KEYRING\n",[267,1840,1842],{"class":269,"line":1841},64,[267,1843,631],{"class":350},[267,1845,1847],{"class":269,"line":1846},65,[267,1848,720],{"emptyLinePlaceholder":719},[267,1850,1852,1854,1856],{"class":269,"line":1851},66,[267,1853,347],{"class":346},[267,1855,439],{"class":350},[267,1857,442],{"class":350},[267,1859,1861],{"class":269,"line":1860},67,[267,1862,720],{"emptyLinePlaceholder":719},[267,1864,1866],{"class":269,"line":1865},68,[267,1867,1868],{"class":1214},"# --- PHP --------------------------------------------------------------------\n",[267,1870,1872],{"class":269,"line":1871},69,[267,1873,1874],{"class":1214},"# Use -cli instead of the bare \"phpX.Y\" metapackage, which pulls in Apache.\n",[267,1876,1878,1881,1883],{"class":269,"line":1877},70,[267,1879,1880],{"class":667},"PACKAGES",[267,1882,905],{"class":403},[267,1884,1885],{"class":350},"\"\"\n",[267,1887,1889,1892,1895,1898,1901,1903],{"class":269,"line":1888},71,[267,1890,1891],{"class":961},"for",[267,1893,1894],{"class":667}," EXTENSION ",[267,1896,1897],{"class":961},"in",[267,1899,1900],{"class":667}," $PHP_EXTENSIONS",[267,1902,1390],{"class":537},[267,1904,1393],{"class":961},[267,1906,1908,1911,1913,1915,1918,1920,1923,1926,1929],{"class":269,"line":1907},72,[267,1909,1910],{"class":667},"    PACKAGES",[267,1912,905],{"class":403},[267,1914,677],{"class":350},[267,1916,1917],{"class":667},"$PACKAGES",[267,1919,870],{"class":350},[267,1921,1922],{"class":667},"${PHP_VERSION}",[267,1924,1925],{"class":350},"-",[267,1927,1928],{"class":667},"${EXTENSION}",[267,1930,920],{"class":350},[267,1932,1934],{"class":269,"line":1933},73,[267,1935,1936],{"class":961},"done\n",[267,1938,1940],{"class":269,"line":1939},74,[267,1941,720],{"emptyLinePlaceholder":719},[267,1943,1945],{"class":269,"line":1944},75,[267,1946,1947],{"class":1214},"# shellcheck disable=SC2086\n",[267,1949,1951,1953,1955,1957,1959],{"class":269,"line":1950},76,[267,1952,347],{"class":346},[267,1954,439],{"class":350},[267,1956,451],{"class":350},[267,1958,490],{"class":350},[267,1960,1961],{"class":667}," $PACKAGES\n",[267,1963,1965],{"class":269,"line":1964},77,[267,1966,720],{"emptyLinePlaceholder":719},[267,1968,1970,1972,1974,1976,1978,1981,1983],{"class":269,"line":1969},78,[267,1971,347],{"class":346},[267,1973,864],{"class":350},[267,1975,867],{"class":350},[267,1977,870],{"class":350},[267,1979,1980],{"class":350}," \"\u002Fusr\u002Fbin\u002Fphp",[267,1982,1922],{"class":667},[267,1984,920],{"class":350},[267,1986,1988],{"class":269,"line":1987},79,[267,1989,720],{"emptyLinePlaceholder":719},[267,1991,1993,1996],{"class":269,"line":1992},80,[267,1994,1995],{"class":652},"echo",[267,1997,1998],{"class":350}," \"\"\n",[267,2000,2002,2004],{"class":269,"line":2001},81,[267,2003,262],{"class":346},[267,2005,880],{"class":350},[267,2007,2009,2011],{"class":269,"line":2008},82,[267,2010,1995],{"class":652},[267,2012,1998],{"class":350},[267,2014,2016],{"class":269,"line":2015},83,[267,2017,720],{"emptyLinePlaceholder":719},[267,2019,2021],{"class":269,"line":2020},84,[267,2022,2023],{"class":1214},"# --- Composer ---------------------------------------------------------------\n",[267,2025,2027,2029,2031,2034,2036],{"class":269,"line":2026},85,[267,2028,962],{"class":961},[267,2030,1603],{"class":346},[267,2032,2033],{"class":350}," \"Install Composer?\"",[267,2035,1390],{"class":537},[267,2037,988],{"class":961},[267,2039,2041,2044,2046,2048],{"class":269,"line":2040},86,[267,2042,2043],{"class":652},"    cd",[267,2045,664],{"class":350},[267,2047,1699],{"class":667},[267,2049,920],{"class":350},[267,2051,2053],{"class":269,"line":2052},87,[267,2054,720],{"emptyLinePlaceholder":719},[267,2056,2058,2061,2063,2065,2067,2069,2071,2073],{"class":269,"line":2057},88,[267,2059,2060],{"class":667},"    EXPECTED_CHECKSUM",[267,2062,905],{"class":403},[267,2064,677],{"class":350},[267,2066,649],{"class":537},[267,2068,394],{"class":346},[267,2070,914],{"class":350},[267,2072,917],{"class":537},[267,2074,920],{"class":350},[267,2076,2078,2081,2083,2085],{"class":269,"line":2077},89,[267,2079,2080],{"class":346},"    curl",[267,2082,522],{"class":350},[267,2084,929],{"class":350},[267,2086,932],{"class":350},[267,2088,2090,2093,2095,2097,2099,2101,2103,2105],{"class":269,"line":2089},90,[267,2091,2092],{"class":667},"    ACTUAL_CHECKSUM",[267,2094,905],{"class":403},[267,2096,677],{"class":350},[267,2098,649],{"class":537},[267,2100,262],{"class":346},[267,2102,948],{"class":350},[267,2104,917],{"class":537},[267,2106,920],{"class":350},[267,2108,2110],{"class":269,"line":2109},91,[267,2111,720],{"emptyLinePlaceholder":719},[267,2113,2115,2118,2120,2122,2124,2126,2129,2131,2133,2135,2137],{"class":269,"line":2114},92,[267,2116,2117],{"class":961},"    if",[267,2119,965],{"class":537},[267,2121,664],{"class":350},[267,2123,970],{"class":667},[267,2125,677],{"class":350},[267,2127,2128],{"class":403}," !=",[267,2130,664],{"class":350},[267,2132,980],{"class":667},[267,2134,677],{"class":350},[267,2136,985],{"class":537},[267,2138,988],{"class":961},[267,2140,2142,2145,2147],{"class":269,"line":2141},93,[267,2143,2144],{"class":403},"        >&2",[267,2146,661],{"class":652},[267,2148,1049],{"class":350},[267,2150,2152,2155],{"class":269,"line":2151},94,[267,2153,2154],{"class":652},"        exit",[267,2156,2157],{"class":1011}," 1\n",[267,2159,2161],{"class":269,"line":2160},95,[267,2162,2163],{"class":961},"    fi\n",[267,2165,2167],{"class":269,"line":2166},96,[267,2168,720],{"emptyLinePlaceholder":719},[267,2170,2172,2174,2176],{"class":269,"line":2171},97,[267,2173,993],{"class":346},[267,2175,929],{"class":350},[267,2177,998],{"class":350},[267,2179,2181,2183,2185,2187,2189,2191],{"class":269,"line":2180},98,[267,2182,1003],{"class":346},[267,2184,451],{"class":350},[267,2186,1008],{"class":350},[267,2188,1012],{"class":1011},[267,2190,1015],{"class":350},[267,2192,1018],{"class":350},[267,2194,2196],{"class":269,"line":2195},99,[267,2197,720],{"emptyLinePlaceholder":719},[267,2199,2201,2203],{"class":269,"line":2200},100,[267,2202,1622],{"class":652},[267,2204,1998],{"class":350},[267,2206,2208,2210],{"class":269,"line":2207},101,[267,2209,1031],{"class":346},[267,2211,880],{"class":350},[267,2213,2215],{"class":269,"line":2214},102,[267,2216,1055],{"class":961},[267,2218,2220],{"class":269,"line":2219},103,[267,2221,720],{"emptyLinePlaceholder":719},[267,2223,2225,2227],{"class":269,"line":2224},104,[267,2226,1995],{"class":652},[267,2228,1998],{"class":350},[267,2230,2232,2234],{"class":269,"line":2231},105,[267,2233,1995],{"class":652},[267,2235,2236],{"class":350}," \"Installation process finished.\"\n",[267,2238,2240,2242],{"class":269,"line":2239},106,[267,2241,1995],{"class":652},[267,2243,2244],{"class":350}," \"Run 'sudo apt update && sudo apt upgrade' periodically to get PHP security releases.\"\n",[85,2246,2248],{"id":2247},"keep-everything-up-to-date","Keep everything up to date",[10,2250,2251],{},"Once it's installed, keeping it up to date takes just a couple of commands:",[258,2253,2255],{"className":337,"code":2254,"language":339,"meta":263,"style":263},"# Operating system and PHP\nsudo apt update && sudo apt upgrade\n\n# Composer\nsudo composer self-update\n",[50,2256,2257,2262,2281,2285,2290],{"__ignoreMap":263},[267,2258,2259],{"class":269,"line":270},[267,2260,2261],{"class":1214},"# Operating system and PHP\n",[267,2263,2264,2266,2268,2271,2274,2276,2278],{"class":269,"line":276},[267,2265,347],{"class":346},[267,2267,439],{"class":350},[267,2269,2270],{"class":350}," update",[267,2272,2273],{"class":537}," &&",[267,2275,541],{"class":346},[267,2277,439],{"class":350},[267,2279,2280],{"class":350}," upgrade\n",[267,2282,2283],{"class":269,"line":282},[267,2284,720],{"emptyLinePlaceholder":719},[267,2286,2287],{"class":269,"line":288},[267,2288,2289],{"class":1214},"# Composer\n",[267,2291,2292,2294,2297],{"class":269,"line":683},[267,2293,347],{"class":346},[267,2295,2296],{"class":350}," composer",[267,2298,2299],{"class":350}," self-update\n",[10,2301,2302,2303,2308],{},"Even on 8.5.12, php.net ",[14,2304,2307],{"href":2305,"rel":2306},"https:\u002F\u002Fwww.php.net\u002Farchive\u002F2026.php#2026-10-23-1",[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:",[258,2310,2312],{"className":337,"code":2311,"language":339,"meta":263,"style":263},"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,2313,2314,2330],{"__ignoreMap":263},[267,2315,2316,2318,2321,2323,2325,2327],{"class":269,"line":270},[267,2317,1995],{"class":652},[267,2319,2320],{"class":350}," 'session.upload_progress.enabled=0'",[267,2322,404],{"class":403},[267,2324,541],{"class":346},[267,2326,616],{"class":350},[267,2328,2329],{"class":350}," \u002Fetc\u002Fphp\u002F8.5\u002Ffpm\u002Fconf.d\u002F99-session-upload-progress.ini\n",[267,2331,2332,2334,2337,2340],{"class":269,"line":276},[267,2333,347],{"class":346},[267,2335,2336],{"class":350}," systemctl",[267,2338,2339],{"class":350}," restart",[267,2341,2342],{"class":350}," php8.5-fpm\n",[10,2344,2345,2346,249,2353,2360],{},"And don't forget your project dependencies: ",[14,2347,2350],{"href":2348,"rel":2349},"https:\u002F\u002Fgetcomposer.org\u002Fdoc\u002F03-cli.md#outdated",[26],[50,2351,2352],{},"composer outdated",[14,2354,2357],{"href":2355,"rel":2356},"https:\u002F\u002Fgetcomposer.org\u002Fdoc\u002F03-cli.md#audit",[26],[50,2358,2359],{},"composer audit"," tell you what needs updating and which packages have known vulnerabilities.",[10,2362,2363,2364,2366,2367,2370,2371,2373],{},"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,2365,575],{}," for PHP, one ",[50,2368,2369],{},"composer self-update"," for Composer, and ",[50,2372,2359],{}," for your projects. Set it up once and stop thinking about it.",[2375,2376,2377],"style",{},"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 .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 .sgueU, html code.shiki .sgueU{--shiki-default:#40A02B;--shiki-dark:#A6E3A1}html pre.shiki code .sjJjI, html code.shiki .sjJjI{--shiki-default:#179299;--shiki-dark:#94E2D5}html pre.shiki code .sNVtu, html code.shiki .sNVtu{--shiki-default:#EA76CB;--shiki-dark:#F5C2E7}html pre.shiki code .sxyLT, html code.shiki .sxyLT{--shiki-default:#7C7F93;--shiki-dark:#9399B2}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 .s0aCy, html code.shiki .s0aCy{--shiki-default:#4C4F69;--shiki-dark:#CDD6F4}html pre.shiki code .sAS4m, html code.shiki .sAS4m{--shiki-default:#8839EF;--shiki-dark:#CBA6F7}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}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}",{"title":263,"searchDepth":276,"depth":276,"links":2379},[2380,2381,2382,2383,2384,2385,2386,2387],{"id":87,"depth":282,"text":88},{"id":202,"depth":282,"text":203},{"id":294,"depth":282,"text":295},{"id":371,"depth":282,"text":372},{"id":457,"depth":282,"text":458},{"id":1086,"depth":282,"text":1087},{"id":1169,"depth":282,"text":1170},{"id":2247,"depth":282,"text":2248},"2026-11-06","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.","md",null,{},"\u002Fblog\u002Fapt-install-php-85-on-ubuntu-26",{"title":5,"description":2389},"blog\u002F0005.apt-install-php-85-on-ubuntu-26",[262,2397,52,1196,339,2398],"ubuntu","script",false,"cpdA9s1Lza9MaGUw1_AslRm9Zf5Lijp1g5Bc1_Clnxs",1793976413142]