คำตอบสั้น ๆ: ติดตั้ง PHP หลายเวอร์ชันคู่กันบน Ubuntu ด้วย PPA ondrej/php และ PHP-FPM แล้วกำหนดให้แต่ละเว็บบน Nginx หรือ Apache ใช้เวอร์ชันที่ต้องการ
คู่มือนี้อธิบาย Ubuntu ทีละขั้นตอน พร้อมคำสั่งที่ใช้ได้จริงและปัญหาที่พบบ่อย
เว็บไซต์เก่าบางระบบยังต้องการ PHP 7.4 หรือ 8.1 ขณะที่เว็บใหม่ต้องการ PHP 8.3 ขึ้นไป แพ็กเกจมาตรฐานของ Ubuntu มี PHP ให้เพียงเวอร์ชันเดียวต่อรุ่นของระบบ (8.1 บน 22.04 และ 8.3 บน 24.04) หากต้องการรันหลายเวอร์ชันพร้อมกันบนเครื่องเดียว วิธีที่นิยมที่สุดคือใช้ PPA ondrej/php ร่วมกับ PHP-FPM แล้วให้แต่ละเว็บส่งงานไปยัง FPM ของเวอร์ชันที่ต้องการ
บทความนี้ติดตั้ง PHP 8.2 และ 8.3 คู่กัน กำหนดให้แต่ละเว็บใช้เวอร์ชันต่างกันทั้งบน Nginx และ Apache และเลือกเวอร์ชันของคำสั่ง php ใน Command Line หากคุณใช้ Plesk ให้เปลี่ยนเวอร์ชันผ่านหน้าจอของ Plesk แทน ตาม การเปลี่ยนเวอร์ชั่น PHP ใน Plesk อย่าติดตั้ง PPA ซ้อนบนเครื่องที่มี Control Panel
สิ่งที่ต้องเตรียม
- Ubuntu 22.04 หรือ 24.04 ที่ไม่มี Control Panel และผู้ใช้ที่มีสิทธิ์
sudo - เว็บเซิร์ฟเวอร์ Nginx หรือ Apache ที่ติดตั้งแล้ว
- สำรองข้อมูลเว็บและ Snapshot ของเครื่องก่อนเริ่ม เพราะการเพิ่ม PPA จะอัปเกรดแพ็กเกจ PHP เดิมของคุณด้วย
หมายเหตุ: PPA
ondrej/phpดูแลโดย Ondřej Surý ผู้ดูแลแพ็กเกจ PHP ของ Debian ไม่ใช่ Canonical โดยตรง และรองรับเฉพาะ Ubuntu LTS ที่ยังอยู่ในระยะสนับสนุน PHP เวอร์ชันที่หมดอายุการดูแลจากทีม PHP (เช่น 7.4, 8.0 และ 8.1) ยังติดตั้งได้ แต่ไม่ได้รับแพตช์ความปลอดภัยอย่างเป็นทางการ ควรใช้เป็นการชั่วคราวระหว่างปรับโค้ดเท่านั้น ตรวจตารางอายุการสนับสนุนได้ที่ php.net/supported-versions.php
ขั้นตอนที่ 1: เพิ่ม PPA ondrej/php
sudo apt update
sudo apt install -y software-properties-common
sudo add-apt-repository ppa:ondrej/php
sudo apt update
คำสั่ง add-apt-repository จะแสดงคำอธิบายของ PPA และให้กด Enter เพื่อยืนยัน เมื่อเสร็จ ตรวจว่าเห็นแพ็กเกจจาก PPA แล้ว:
apt-cache policy php8.2-fpm
บรรทัด Candidate ต้องมีเลขเวอร์ชัน และบรรทัดแหล่งที่มาควรมี ppa.launchpadcontent.net/ondrej/php
ขั้นตอนที่ 2: ติดตั้ง PHP แต่ละเวอร์ชันพร้อม FPM
ชื่อแพ็กเกจจะมีเลขเวอร์ชันนำหน้าเสมอ ต้องติดตั้งส่วนขยายแยกของแต่ละเวอร์ชัน:
sudo apt install -y php8.2-fpm php8.2-cli php8.2-mysql php8.2-curl \
php8.2-gd php8.2-mbstring php8.2-xml php8.2-zip php8.2-intl
sudo apt install -y php8.3-fpm php8.3-cli php8.3-mysql php8.3-curl \
php8.3-gd php8.3-mbstring php8.3-xml php8.3-zip php8.3-intl
ตรวจว่า FPM ทั้งสองทำงานและมี Socket แยกกัน:
systemctl status php8.2-fpm php8.3-fpm --no-pager | grep -E "fpm.service|Active"
ls -l /run/php/
ควรเห็น php8.2-fpm.sock และ php8.3-fpm.sock แต่ละเวอร์ชันมีไฟล์ตั้งค่าของตัวเองแยกกันทั้งหมด:
| รายการ | ตำแหน่ง (ตัวอย่าง PHP 8.2) |
|---|---|
| php.ini ของ FPM (เว็บ) | /etc/php/8.2/fpm/php.ini |
| php.ini ของ CLI | /etc/php/8.2/cli/php.ini |
| Pool ของ FPM | /etc/php/8.2/fpm/pool.d/www.conf |
| Socket | /run/php/php8.2-fpm.sock |
| ชื่อ Service | php8.2-fpm |
การแก้ memory_limit หรือ upload_max_filesize จึงต้องแก้ใน php.ini ของเวอร์ชันที่เว็บนั้นใช้ แล้วรีสตาร์ต Service ของเวอร์ชันนั้น เช่น sudo systemctl restart php8.2-fpm
ขั้นตอนที่ 3 (Nginx): กำหนดเวอร์ชันต่อเว็บ
ใน Server Block ของแต่ละเว็บ เปลี่ยนเฉพาะบรรทัด fastcgi_pass ให้ชี้ไปที่ Socket ของเวอร์ชันที่ต้องการ ตัวอย่างเว็บเก่าใช้ 8.2:
server {
listen 80;
server_name legacy.example.com;
root /var/www/legacy.example.com/public;
index index.php;
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.2-fpm.sock;
}
}
ส่วนเว็บใหม่ใช้ fastcgi_pass unix:/run/php/php8.3-fpm.sock; จากนั้นตรวจและโหลดค่าใหม่:
sudo nginx -t && sudo systemctl reload nginx
การตั้ง Server Block หลายเว็บอธิบายไว้ครบใน ตั้งค่า Nginx Server Block สำหรับหลายเว็บไซต์ในเครื่องเดียว
ขั้นตอนที่ 3 (Apache): เปลี่ยนจาก mod_php เป็น PHP-FPM
mod_php โหลด PHP ได้เพียงเวอร์ชันเดียวต่อ Apache ถ้าติดตั้ง LAMP ด้วย libapache2-mod-php มาก่อน ต้องสลับไปใช้ FPM ก่อน:
sudo a2dismod php8.3
sudo a2dismod mpm_prefork
sudo a2enmod mpm_event proxy_fcgi setenvif
ถ้า a2dismod php8.3 แจ้งว่าไม่มีโมดูลนี้ ให้ดูชื่อที่เปิดอยู่จริงด้วย apache2ctl -M | grep php จากนั้นใน VirtualHost ของแต่ละเว็บ เพิ่มบล็อกนี้โดยเลือก Socket ตามเวอร์ชัน:
<VirtualHost *:80>
ServerName legacy.example.com
DocumentRoot /var/www/legacy.example.com/public
<FilesMatch \.php$>
SetHandler "proxy:unix:/run/php/php8.2-fpm.sock|fcgi://localhost"
</FilesMatch>
</VirtualHost>
ตรวจไวยากรณ์และรีสตาร์ต (ต้อง restart เพราะเปลี่ยน MPM):
sudo apache2ctl configtest
sudo systemctl restart apache2
อย่าเปิด a2enconf php8.x-fpm ของหลายเวอร์ชันพร้อมกัน เพราะไฟล์เหล่านั้นตั้ง Handler ระดับทั้งเซิร์ฟเวอร์ และจะทับกันเอง การกำหนดใน VirtualHost อย่างเดียวชัดเจนกว่า