Skip to content
View in the app

A better way to browse. Learn more.

PHP论坛人

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

Debian 13 安裝 PHP 8.3

Featured Replies

Debian 13 安裝 PHP 8.3



環境:Debian 13

VPS規格:2 vCPU / 2GB RAM

用途:LNMP 論壇網站


-----------------
前置確認
-----------------

在開始之前,請先確認以下事項,避免後續安裝失敗或設定衝突


確認OS版本
cat /etc/os-release


預期輸出應包含:PRETTY_NAME="Debian GNU/Linux 13 (trixie)"

注意:sury.org 的套件來源會依 lsb_release -sc 取得代號(trixie),若OS版本不符,後續 apt update 會出現 404 錯誤



確認目前是否已安裝其他PHP版本
dpkg -l | grep php



若已有舊版 PHP(如 PHP 7.x / 8.1 / 8.2),請評估是否先移除,避免多版本衝突


列出所有已安裝的 PHP 套件(僅查詢,不執行移除)
dpkg -l | grep '^ii' | grep php




確認系統時間正確

憑證驗證與 log 時間戳均依賴系統時間,請先確認
timedatectl status




-----------------------------
加入 sury.org PHP套件來源
-----------------------------


Debian官方倉庫的PHP版本通常落後官方發佈數個月,安裝最新 PHP 8.3 需加入 sury.org 第三方來源

此來源由Debian PHP維護者 Ondřej Surý 長期維護,穩定性與安全性有保障,是Debian社群的主流選擇






更新系統並安裝必要工具

apt update -y && apt upgrade -y



apt install -y wget curl vim gnupg dpkg apt-transport-https lsb-release ca-certificates




下載 GPG 金鑰
curl -sSLo /usr/share/keyrings/deb.sury.org-php.gpg https://packages.sury.org/php/apt.gpg





驗證 GPG 金鑰指紋 (資安關鍵,請勿略過)
gpg --show-keys --with-fingerprint /usr/share/keyrings/deb.sury.org-php.gpg





預期輸出:
pub   rsa3072 2019-03-18 [SC] [expires: 2028-02-04]
      1505 8500 A023 5D97 F5D1  0063 B188 E2B6 95BD 4743
uid                      DEB.SURY.ORG Automatic Signing Key <deb@sury.org>
sub   rsa3072 2019-03-18 [E] [expires: 2028-02-04]




安全提醒:若指紋不符,請立即停止安裝

可能代表金鑰遭竄改或下載來源異常,這是防範供應鏈攻擊的重要步驟,切勿略過





加入套件來源
echo "deb [signed-by=/usr/share/keyrings/deb.sury.org-php.gpg] https://packages.sury.org/php/ $(lsb_release -sc) main" > /etc/apt/sources.list.d/php.list





確認內容是否正確
cat /etc/apt/sources.list.d/php.list


預期輸出:deb [signed-by=/usr/share/keyrings/deb.sury.org-php.gpg] https://packages.sury.org/php/ trixie main






更新套件清單,執行升級
apt update -y && apt upgrade -y





安裝 PHP 8.3 核心與擴展

以下3行一次複製貼上

apt install -y php8.3 php8.3-cli php8.3-fpm php8.3-mysql php8.3-curl php8.3-gd \
php8.3-mbstring php8.3-xml php8.3-zip php8.3-imap php8.3-soap php8.3-gmp \
php8.3-bcmath php8.3-redis php8.3-exif php8.3-imagick php8.3-intl





各擴展用途說明
php8.3-fpm:PHP FastCGI 處理程序 (搭配 Nginx 必要)
php8.3-mysql:連接 MySQL / MariaDB 資料庫
php8.3-curl:發送 HTTP 請求 (呼叫 API 等)
php8.3-gd:圖片處理 (縮圖、浮水印等基本功能)
php8.3-mbstring:多位元組字串處理 (中文、日文等)
php8.3-xml:XML解析與生成
php8.3-zip:壓縮與解壓縮ZIP檔
php8.3-imap:收發 Email (IMAP 協定)
php8.3-soap:SOAP Web Service 支援
php8.3-gmp:大數運算 (加密相關)
php8.3-bcmath:高精度數學運算 (金融計算常用)
php8.3-redis:連接 Redis 快取伺服器
php8.3-exif:讀取圖片 EXIF 後設資料 (相機拍攝資訊)
php8.3-imagick:進階圖片處理 (需搭配 imagemagick)
php8.3-intl:國際化 (Internationalization, i18n) 擴展模組,用於處理 多語言文字、Unicode、地區格式化、排序、轉換等功能

說明: 若論壇未來有發送簡訊驗證或整合第三方支付需求,php8.3-curl 與 php8.3-soap 均屬必要,建議一併安裝







安裝 PEAR、ImageMagick 與 Redis 服務
apt install -y php-pear imagemagick redis



說明
php-pear:PHP套件管理工具,部分函式庫安裝時需要
imagemagick:系統層級的圖片處理程式,php8.3-imagick 的依賴套件
redis:Redis 伺服器本體,提供快取與Session儲存服務




重啟
systemctl restart php8.3-fpm





確認 PEAR 安裝
pear version


預期輸出
PEAR Version: 1.10.16
PHP Version: 8.3.31
Zend Engine Version: 4.3.31
Running on: Linux xxxx 6.12.86+deb13-cloud-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.12.86-1 (2026-05-08) x86_64







搜尋其他可用的 PHP 8.3 擴展

若未來有其他功能需求,可先查詢是否有對應套件:

apt-cache search php8.3 | grep php8.3






安全強化:關閉 cgi.fix_pathinfo

防止跨目錄攻擊 / 防止路徑攻擊 cgi.fix_pathinfo

cgi.fix_pathinfo 預設值為 1(啟用),在此模式下,攻擊者可藉由偽造路徑(如 /uploads/evil.jpg/nonexistent.php)讓伺服器嘗試執行惡意腳本,必須關閉

使用 sed 自動修改(推薦:快速且不易出錯)

sed -i 's@^;*cgi.fix_pathinfo=.*@cgi.fix_pathinfo=0@' /etc/php/8.3/fpm/php.ini




確認修改成功,預期輸出 cgi.fix_pathinfo=0
grep cgi.fix_pathinfo /etc/php/8.3/fpm/php.ini







-------------------------------
修改 php.ini(FPM)
-------------------------------

範圍說明:本文僅修改 PHP-FPM 使用的 php.ini,路徑為 /etc/php/8.3/fpm/php.ini

CLI 使用獨立設定檔 /etc/php/8.3/cli/php.ini,兩者彼此獨立,互不影響



編輯
vi /etc/php/8.3/fpm/php.ini



使用Xshell 8軟體上面的選項,編輯 -> 尋找 -> 尋找目標,將能快速找到以下這些要修改的地方


停用危險函數,修改為 (請依實際需求調整)

; IPS論壇用
disable_functions = exec, proc_open, passthru, system, chroot, chgrp, chown, shell_exec, popen, ini_alter, ini_restore, dl, readlink, symlink, popepassthru, stream_socket_server, pcntl_exec



; 執行時間與記憶體

max_execution_time = 300

max_input_time = 300

memory_limit = 512M




; 錯誤顯示,正式環境關閉,請設 display_errors = Off,避免洩漏程式碼與路徑資訊
display_errors = Off



; 開啟錯誤記錄
log_errors = On



; Production 正式環境用
error_reporting = E_ALL & ~E_DEPRECATED


; 錯誤記錄檔路徑
; 放在 error_reporting = E_ALL & ~E_DEPRECATED 的底下
error_log = /var/log/php8.3-fpm-error.log








; 上傳與傳輸設定
; upload_max_filesize 必須小於 post_max_size,否則上傳會靜默失敗

post_max_size = 220M

upload_max_filesize = 200M

max_file_uploads = 100

default_socket_timeout = 180




; Session 安全強化
; 論壇高度依賴 Session 管理登入狀態,以下設定可有效防範常見攻擊

;Session 儲存位置(常被忽略)
session.save_path = "/var/lib/php/sessions"



; 防止 Session Fixation 攻擊
session.use_strict_mode = 1



; 只允許透過 HTTPS 傳送 Cookie(需已部署 HTTPS)
; 僅在 HTTPS 環境下有效;若伺服器尚未配置 SSL,請先暫時設為 0,待 HTTPS 部署完成後再改回 1
session.cookie_secure = 1




; 僅允許使用 Cookie 保存 Session ID(防止 URL 洩漏)
session.use_only_cookies = 1



; 禁止 JavaScript 讀取 Session Cookie(防止 XSS 竊取)
session.cookie_httponly = 1



; 防止跨站請求偽造(CSRF)
session.cookie_samesite = Lax



; Session 過期時間(秒),1440 = 24 分鐘
session.gc_maxlifetime = 1440


; Session ID 長度(較長的 ID 更難被暴力猜測)
session.sid_length = 48


; Session ID 每字元的熵值位元數(6 = 使用 base64url 字元集)
session.sid_bits_per_character = 6







儲存檔案並離開vi編輯器
按 Esc,輸入 :wq,按 Enter





說明

upload_max_filesize 必須小於 post_max_size,否則上傳會靜默失敗

若使用 Nginx,同時需在 Nginx 設定中調整 client_max_body_size,兩者需對應



--------------------------------
Session 儲存位置 (常被忽略)
--------------------------------

確認目錄是否存在
ls -ld /var/lib/php/sessions


若目錄不存在,需手動建立
mkdir -p /var/lib/php/sessions



確認權限,預期權限應為 drwx-wx-wt(即 1733)
ls -ld /var/lib/php/sessions




若權限不正確,執行

chown root:www-data /var/lib/php/sessions

chmod 1733 /var/lib/php/sessions



說明:權限 1733 中的 Sticky bit 可防止不同使用者互相刪除彼此的 Session 檔案

www-data 群組需有寫入權限,PHP-FPM 才能正常建立 Session 檔案






-------------------------
驗證並重啟
-------------------------

檢查 php.ini 語法,預期顯示 No syntax errors detected in /etc/php/8.3/fpm/php.ini

php -l /etc/php/8.3/fpm/php.ini




驗證 PHP-FPM 設定語法,預期顯示 NOTICE: configuration file /etc/php/8.3/fpm/php-fpm.conf test is successful

php-fpm8.3 -t






重啟
systemctl restart php8.3-fpm





確認服務狀態,預期輸出 Active: active (running)
systemctl status php8.3-fpm







-------------------------------
確認擴展載入狀態
-------------------------------

某些擴展可能在安裝過程中未被正確啟用,建議逐一確認

/bin/php8.3 -m



輸出清單中應可看到:exif、gmp、imagick、redis、intl 以及其他已安裝的擴展






若清單中缺少某個擴展,重新安裝對應套件

apt install --reinstall php8.3-擴展名稱


systemctl restart php8.3-fpm









--------------------------
設定系統預設 PHP 版本
--------------------------

若伺服器上安裝了多個PHP版本,需明確指定預設使用的版本,避免版本衝突


查看目前已登錄的PHP版本
update-alternatives --list php



設定預設版本為PHP 8.3
update-alternatives --set php /usr/bin/php8.3



互動式選擇 (若有多個版本可供切換)
update-alternatives --config php



確認目前PHP版本
php -v



預期輸出 PHP 8.3.31 (cli)


補充:update-alternatives 只影響 CLI 的 php 指令預設版本,不影響 PHP-FPM 的運作版本

PHP-FPM 的版本由安裝的 php8.3-fpm 套件本身決定,兩者彼此獨立






---------------------------
設定開機自動啟動
---------------------------


開機自動啟動
systemctl enable php8.3-fpm



立即重啟
systemctl restart php8.3-fpm



確認服務狀態,應顯示 Active: active (running)
systemctl status php8.3-fpm




-------------------------
同步確認 Redis 服務
-------------------------


systemctl enable redis-server



systemctl start redis



systemctl status redis



常見疏失: 安裝 Redis 後忘記設定開機自啟動,重開機後論壇 Session 快取失效,導致用戶被強制登出







-----------------------------------
PHP-FPM Pool 效能調整
-----------------------------------

PHP-FPM 的行程池設定檔位於 /etc/php/8.3/fpm/pool.d/www.conf,可依伺服器規格調整參數


以下適合 VPS 2C/2G 優化參數



編輯
vi /etc/php/8.3/fpm/pool.d/www.conf



搜尋以下內容,並替換



; 行程管理模式(dynamic 閒置時縮減行程,節省記憶體)
pm = dynamic



; 最大子行程數 (依據記憶體調整,每行程約 128~256MB)
pm.max_children = 8




; 啟動時建立的行程數
pm.start_servers = 3



; 最少待機行程數 (保留少量應付瞬間流量)
pm.min_spare_servers = 2



; 最多待機行程數 (避免過多閒置行程浪費記憶體)
pm.max_spare_servers = 5


; 每個子行程最多處理請求次數 (防止記憶體洩漏,超過後自動回收並重建行程)
pm.max_requests = 500



; 逾時設定。單一請求最長執行時間 (需與 php.ini 的 max_execution_time 對應)
request_terminate_timeout = 300s




; 在 www.conf 末尾 加入錯誤記錄設定
; Pool 設定檔的優先權高於 php.ini,適合多網站不同 log 路徑的情境
; 正式環境關閉 display_errors 後,務必確保錯誤訊息被記錄
; 自訂錯誤記錄路徑
php_flag[log_errors] = on
php_value[error_log] = /var/log/php8.3-fpm-error.log






儲存檔案並離開vi編輯器
按 Esc,輸入 :wq,按 Enter





---------------------------------
建立錯誤記錄與 logrotate
---------------------------------

建立記錄檔
touch /var/log/php8.3-fpm-error.log



設定擁有者 (與 PHP-FPM 執行使用者一致)
chown www-data:www-data /var/log/php8.3-fpm-error.log



設定權限 (640 = 擁有者可讀寫,群組可讀,其他人無權限)
chmod 640 /var/log/php8.3-fpm-error.log



設定 logrotate (避免 log檔 過大)

以下這幾行一起貼上


cat > /etc/logrotate.d/php-fpm << 'EOF'
/var/log/php8.3-fpm-error.log {
    daily
    rotate 30
    compress
    delaycompress
    missingok
    notifempty
    create 640 www-data www-data
    sharedscripts
    postrotate
        systemctl reload php8.3-fpm > /dev/null 2>&1 || true
    endscript
}
EOF



---------------------------
測試 logrotate 設定
---------------------------

logrotate --debug /etc/logrotate.d/php-fpm


預期輸出不應有 error,若有錯誤請依訊息修正路徑或權限設定


常見疏失:logrotate 設定後從未測試,直到 log 檔長到 數GB 才發現問題。建議設定完成後立即執行一次除錯測試













-------------------------
驗證並重新載入
-------------------------


驗證 PHP-FPM 設定語法,預期顯示 NOTICE: configuration file /etc/php/8.3/fpm/php-fpm.conf test is successful

php-fpm8.3 -t





重新載入
systemctl reload php8.3-fpm








-----------------------------------------
如何計算適合的 pm.max_children?
-----------------------------------------

執行以下指令測量單個 PHP 行程平均佔用記憶體 :

ps --no-header -o rss -C php-fpm8.3 | awk '{sum+=$1} END {print sum/NR/1024" MB"}'



計算公式
pm.max_children = 可分配給 PHP-FPM 的記憶體 ÷ 單個行程平均記憶體用量


範例:
可用 RAM 約 1 GB(2 GB 扣除 Nginx、MySQL、Redis 後的餘量)
單個行程平均用量 128 MB
pm.max_children = 1024 ÷ 128 = 8


提醒:2GB RAM 的VPS需同時運行 Nginx、MySQL、Redis 等服務,不要將全部記憶體分配給PHP-FPM

初始建議值為 6~10,上線後依實際流量與記憶體監控再調整


---------------------------
監控實際記憶體用量
---------------------------

查看所有 PHP-FPM 行程的總記憶體用量
ps --no-header -o rss -C php-fpm8.3 | awk '{sum+=$1} END {print sum/1024" MB total"}'



查看整體可用記憶體
free -h








----------------
重開機驗證
----------------

重開機
reboot




確認PHP-FPM已自動啟動,應顯示 Active: active (running)
systemctl status php8.3-fpm



確認Redis已自動啟動
systemctl status redis



再次確認PHP版本
php -v




確認 Session 目錄權限仍正確
ls -ld /var/lib/php/sessions




確認錯誤記錄檔存在
ls -lh /var/log/php8.3-fpm-error.log









---------------
常見問題排查
---------------


PHP-FPM 啟動失敗

查看詳細錯誤訊息
journalctl -xe | grep php


語法檢查
php-fpm8.3 -t


語法檢查輸出 FAILED 時,依錯誤訊息修正 php.ini 或 www.conf






擴展載入失敗

確認特定擴展是否載入
php8.3 -m | grep 套件名稱


確認 conf.d 目錄是否有對應 .ini 檔
ls /etc/php/8.3/fpm/conf.d/


若 .ini 檔不存在,重新安裝對應套件
apt install --reinstall php8.3-擴展名稱


systemctl restart php8.3-fpm






記憶體不足導致 504 逾時

查看整體可用記憶體
free -h

查看 PHP-FPM 各行程記憶體用量
ps --no-header -o rss -C php-fpm8.3 | awk '{sum+=$1} END {print sum/1024" MB total"}'


處理方式:適當降低 pm.max_children,並確認 memory_limit 設定合理







Nginx 與 PHP-FPM 連線失敗(502 Bad Gateway)

確認 PHP-FPM socket 路徑
grep "^listen" /etc/php/8.3/fpm/pool.d/www.conf


預設 socket 路徑為 /run/php/php8.3-fpm.sock,Nginx 設定中的 fastcgi_pass 必須對應此路徑
fastcgi_pass unix:/run/php/php8.3-fpm.sock;



確認 socket 檔案存在
ls -lh /run/php/php8.3-fpm.sock





上傳檔案失敗(無錯誤訊息)

請同時確認以下三個設定的一致性

php.ini
upload_max_filesize
200M

php.ini
post_max_size
220M

nginx.conf
client_max_body_size
220M


關鍵:upload_max_filesize 必須小於 post_max_size;client_max_body_size 必須大於或等於 post_max_size

三者任一設定過小都會導致靜默失敗







PHP 錯誤不記錄到 log 檔

確認以下條件全部成立

1. 確認 log 檔存在且權限正確
ls -lh /var/log/php8.3-fpm-error.log


2. 確認 www-data 可寫入
sudo -u www-data touch /var/log/php8.3-fpm-error.log


確認 php.ini 設定
php -i | grep -E 'log_errors|error_log|error_reporting'

Edited by Jack

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

Account

Navigation

Search

Search

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.