跳转到帖子
在手机APP中查看

一个更好的浏览方法。了解更多

PHP论坛人

主屏幕上的全屏APP,带有推送通知、徽章等。

在iOS和iPadOS上安装此APP
  1. 在Safari中轻敲分享图标
  2. 滚动菜单并轻敲添加到主屏幕
  3. 轻敲右上角的添加按钮。
在安卓上安装此APP
  1. 轻敲浏览器右上角的三个点菜单 (⋮) 。
  2. 轻敲添加到主屏幕安装APP
  3. 轻敲安装进行确认。

Debian 13 安裝 PHP 8.3

精选回复

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 full-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 full-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'

本帖最后于,由Jack编辑

创建帐户或登录后发表意见

帐户

导航

搜索

搜索

配置浏览器推送通知

Chrome (安卓)
  1. 轻敲地址栏旁的锁形图标。
  2. 轻敲权限 → 通知。
  3. 调整你的偏好。
Chrome (台式电脑)
  1. 点击地址栏中的挂锁图标。
  2. 选择网站设置。
  3. 找到通知选项并调整你的偏好。