Eric L. Barnes จาก PHP News เขียนเช็คลิสต์ไว้ก่อนวันหมดอายุราวสองเดือน โพสต์นี้สรุปเช็คลิสต์นั้น แล้วเติมส่วนที่เราเจอบ่อยกับเว็บ Laravel บน shared hosting และ VPS ที่ดูแลเอง ส่วนว่าแต่ละเวอร์ชันของ PHP ได้ support กี่ปี และ active support ต่างจาก security fixes ยังไง อ่านได้ในโพสต์อายุ support ของ PHP
เว็บยังเปิดได้หลังวันหมดอายุ แต่จะไม่มีใครแพตช์ให้อีก
วันที่ 1 ม.ค. 2570 เว็บที่รันบน PHP 8.2 ยังทำงานได้เหมือนเดิมทุกอย่าง ที่เปลี่ยนคือทีม PHP จะไม่ออก 8.2.36 อีกแล้ว ถ้ามีช่องโหว่ร้ายแรงแบบ PHP2Shell ที่ 8.2 ยังได้แพตช์ทันในเดือนนี้ ครั้งหน้า 8.2 จะไม่ได้
เจ้าของระบบจึงควรรู้ว่าเว็บของตัวเองรัน PHP เวอร์ชันอะไร และวางแผนกับคนดูแลระบบไว้ก่อนสิ้นปี ไม่ต้องรีบจนพลาด แต่ก็ไม่ควรปล่อยข้ามปี
เลือกเวอร์ชันปลายทาง
ขึ้นข้ามสองสามเวอร์ชันในรอบเดียวเป็นเรื่องปกติ แค่ต้องอ่านของที่เปลี่ยนในทุกเวอร์ชันที่ข้าม
| ปลายทาง | แพตช์ความปลอดภัยถึง | เหมาะกับ |
|---|---|---|
| 8.3 | 31 ธ.ค. 2570 | ขยับน้อยที่สุด แต่อีกปีก็ต้องอัปเกรดอีกรอบ |
| 8.4 | 31 ธ.ค. 2571 | ออกมาเกือบสองปีแล้ว package จึงมักรองรับครบ หมด active support สิ้นปีนี้ เหลือแค่แพตช์ความปลอดภัย |
| 8.5 | 31 ธ.ค. 2572 | ใหม่สุดที่ออกแล้ว ยังแก้บั๊กให้ถึงสิ้นปี 2570 |
| 8.6 | ยังไม่ออก | มีกำหนดออก 19 พ.ย. 2569 รอตัว stable และรอ package ประกาศรองรับก่อน ไม่ควรเอา release candidate ขึ้น production |
ถ้าเป็นเว็บ Laravel ดูเวอร์ชันของ Laravel ไปด้วย Laravel 12 รองรับ PHP 8.2 ถึง 8.5 ส่วน Laravel 13 ต้องใช้ 8.3 ขึ้นไป เว็บที่จะขึ้น Laravel 13 ในปีหน้า ย้าย PHP ไป 8.4 หรือ 8.5 ตั้งแต่ตอนนี้ก็ไม่ต้องย้ายซ้ำอีก
หาให้ครบว่า PHP รันอยู่ที่ไหนบ้าง
ขั้นนี้พลาดบ่อยที่สุด เครื่องเดียวกันอาจมี PHP หลายตัว และ php -v บอกแค่ตัวที่เรียกจาก terminal ซึ่งเป็น PHP CLI ไล่ดูให้ครบทุกที่ที่โค้ดของเรารัน
- PHP-FPM ที่เว็บใช้จริง ดูจาก
fastcgi_passใน config ของ nginx ว่าชี้ไปที่ socket ของเวอร์ชันไหน - cron ที่เรียก
schedule:runและ queue worker ใน Supervisor ที่อาจเขียน path เต็มอย่าง/usr/bin/php8.2ไว้ - Docker image ที่
FROM php:8.2-fpmและ image ใน CI ที่รัน test - shared hosting ตัวเลือกเวอร์ชันใน cPanel หรือ DirectAdmin ตั้งแยกได้ทีละโดเมน และ PHP ที่ cron ของ hosting เรียกก็อาจเป็นคนละตัวกับเว็บ
เช็คว่า package ไหนยังไม่รองรับ
ก่อนแตะเซิร์ฟเวอร์ ให้ Composer บอกว่า package ไหนจะขวางเวอร์ชันใหม่ คำสั่ง composer prohibits (หรือ why-not) ตอบได้ในคำสั่งเดียว
composer prohibits php 8.4
ถ้ามีรายชื่อ package ขึ้นมา อัปเดต package เหล่านั้นตั้งแต่ยังอยู่บน 8.2 ทีละตัว ทดสอบให้ผ่าน แล้วค่อยเปลี่ยนเวอร์ชัน PHP งานจะแยกเป็นสองก้อนที่ไล่ปัญหาง่ายกว่าทำพร้อมกัน
อ่าน migration guide แล้วให้ Rector แก้ส่วนที่แก้ตามกันได้
php.net เขียน migration guide ไว้ทุกเวอร์ชัน แต่ละหน้ามีของที่เลิกใช้และของที่เปลี่ยนแล้วโค้ดเดิมอาจพัง ขึ้นจาก 8.2 ไป 8.5 ต้องอ่านสามหน้า คือ 8.3, 8.4 และ 8.5
งานแก้ที่ทำซ้ำได้ตามกฎ ให้ Rector ทำแทน ถ้าตั้ง withPhpSets() ไว้แบบไม่ใส่ค่า Rector จะอ่านเวอร์ชันจาก require.php ใน composer.json เราจึงแก้เวอร์ชันในนั้นเป็นปลายทางก่อน แล้วลองรันแบบดูอย่างเดียว Rector 2.6.2 ขึ้นไปมี --php ให้รันเฉพาะกฎที่ผูกกับเวอร์ชัน PHP
vendor/bin/rector process --php --dry-run
อ่าน diff ก่อนรันจริงทุกครั้ง และอย่าเชื่อว่า Rector จับได้ทุกอย่าง function ที่ชื่อเดิมแต่ทำงานต่างไปในเวอร์ชันใหม่ Rector มองไม่เห็น ต้องรู้จาก migration guide กับ test
ทดสอบใน CI บนเวอร์ชันใหม่ไปพร้อมกับเวอร์ชันเดิม
เพิ่มเวอร์ชันปลายทางเข้า matrix ของ CI คู่กับ 8.2 ระหว่างที่ยังย้ายไม่เสร็จ test จะบอกได้ว่าโค้ดชุดเดียวกันใช้ได้ทั้งสองฝั่ง ถ้ายังไม่มี CI ตั้งตามโพสต์ GitHub Actions สำหรับ Laravel ได้
อีกสองอย่างที่ควรตั้งไว้
- เปิด
error_reporting=E_ALLบนเครื่อง dev และใน CI deprecation ที่ปิดไว้คือของที่จะพังในเวอร์ชันถัดไป เห็นตอนนี้แก้ง่ายกว่า - ตั้ง static analysis ให้ตรวจตามเวอร์ชันปลายทาง อย่าง
phpVersionของ PHPStan
ย้ายเซิร์ฟเวอร์ทีละส่วน
พอ test ผ่านแล้ว ค่อยย้ายของจริง
- บนเครื่องใหม่หรือหลังลง PHP ตัวใหม่ รัน
composer check-platform-reqsเช็คว่าเวอร์ชัน PHP และ extension ครบตามที่ package ต้องการ - ย้ายทีละส่วน เครื่องเดียว worker กลุ่มเดียว หรือเว็บตัวเดียวก่อน
- ดู log ช่วงแรกว่ามี warning หรือ deprecation ใหม่ไหม
- เก็บ PHP ตัวเก่าหรือ image เก่าไว้จนมั่นใจว่าไม่ต้องย้อนกลับ
กรณีที่อาจเจอตอนย้ายเวอร์ชันจริง
- VPS ที่ลง PHP จาก PPA ของ Ondřej Surý ลง 8.4 คู่กับ 8.2 บนเครื่องเดียวกันได้ ย้ายทีละเว็บด้วยการเปลี่ยน
fastcgi_passไปที่ socket ของphp8.4-fpmแต่ extension ต้องลงแยกทุกเวอร์ชัน อย่างphp8.4-mbstringหรือphp8.4-gdถ้าลืม เว็บจะพังตรงหน้าที่ใช้ extension นั้น และค่าที่เคยปรับในphp.iniหรือ pool ของ FPM ก็ต้องตั้งใหม่ เพราะแต่ละเวอร์ชันมีโฟลเดอร์ config ของตัวเอง - cron กับ queue worker ยังเรียก PHP ตัวเก่า เว็บย้ายแล้วแต่งานเบื้องหลังยังรันบน 8.2 ต้องแก้ path ใน crontab และใน config ของ Supervisor แล้วสั่ง
queue:restart - shared hosting ที่เลือกเวอร์ชันได้ เปลี่ยนในหน้า MultiPHP หรือ PHP Selector ได้เอง ลองกับ subdomain ทดสอบก่อนถ้ามี และถามผู้ให้บริการว่า cron ใช้ PHP ตัวไหน
- Ubuntu ที่ใช้ PHP ของ Ubuntu เอง นับอายุตามรอบของ Ubuntu ไม่ใช่ของ php.net รายละเอียดอยู่ในโพสต์อายุ support ของ PHP






