場景描述
- 服務器為定制版 CentOS,不確定具體版本。
- PHP 為手動編譯安裝,**源碼目錄已刪除**,無法直接
make install 擴展。
- 需為現有 PHP 動態添加
openssl 擴展。
操作步驟
1. 確定當前 PHP 版本並下載對應源碼包
# 查看版本
/usr/local/bin/php -v
# 輸出示例:PHP 7.4.33 (cli) (built: Jan 15 2023 10:00:00)
# 下載同版本源碼(以 7.4.33 為例)
cd /usr/local/src
wget https://www.php.net/distributions/php-7.4.33.tar.gz
tar xzf php-7.4.33.tar.gz
cd php-7.4.33/ext/openssl
2. 修正配置文件並執行 phpize
# openssl 目錄下通常有 config0.m4,需重命名為 config.m4
mv config0.m4 config.m4
# 執行 phpize(使用當前 PHP 的 phpize)
/usr/local/bin/phpize
# 輸出應包含:
# Configuring for:
# PHP Api Version: 20190902
# Zend Module Api No: 20190902
# Zend Extension Api No: 320190902
3. 編譯安裝擴展
./configure --with-openssl --with-php-config=/usr/local/bin/php-config
make
make install
# 成功輸出示例:
# Installing shared extensions: /usr/local/php/lib/php/extensions/no-debug-non-zts-20190902/
4. 啟用擴展並重啟服務
# 找到 php.ini 路徑
/usr/local/bin/php --ini
# 輸出 Loaded Configuration File: /usr/local/php/etc/php.ini
# 編輯 php.ini 添加
extension=openssl.so
# 重啟 PHP-FPM / Apache
systemctl restart php-fpm
# 或
service httpd restart
5. 驗證安裝
/usr/local/bin/php -m | grep openssl
# 輸出 openssl 即成功
# 或查看 phpinfo()
php -r "phpinfo();" | grep -i openssl
常見問題排查
| 問題 | 原因 | 解決 |
Cannot find config.m4 | 源碼包中為 config0.m4 | mv config0.m4 config.m4 |
phpize: command not found | PHP 安裝路徑不在 PATH | 使用絕對路徑 /usr/local/bin/phpize |
編譯報錯 openssl/ssl.h not found | 系統缺少 openssl-devel | yum install -y openssl-devel 或 apt-get install libssl-dev |
| 安裝後不生效 | php.ini 路徑錯誤、未重啟服務、線程安全性不匹配 | 用 php --ini 確認 ini 文件、重啟 php-fpm、檢查 php -i | grep Thread Safety |
| 版本不匹配 | 下載源碼版本與運行 PHP 版本不一致 | 嚴格對應 php -v 版本下載 |
關鍵點總結
- 版本嚴格對應:源碼版本必須與
php -v 完全一致(包括小版本)。
- 使用運行時的 phpize/php-config:確保編譯出的 .so 與當前 PHP ABI 兼容。
- 系統依賴先裝:
openssl-devel / libssl-dev 提供編譯所需頭文件與庫。
- 動態擴展優於重編譯 PHP:不影響現有模組,風險可控。
驗證腳本(可放入項目健康檢查)
<?php
if (!extension_loaded('openssl')) {
die("OpenSSL 擴展未加載");
}
$config = openssl_get_cert_locations();
echo "OpenSSL 版本: " . OPENSSL_VERSION_TEXT . "\n";
echo "證書目錄: " . $config['default_cert_dir'] . "\n";
// 測試加解密
$data = 'test';
$private = openssl_pkey_new(['private_key_bits' => 1024]);
openssl_private_encrypt($data, $encrypted, $private);
openssl_public_decrypt($encrypted, $decrypted, openssl_pkey_get_details($private)['key']);
echo "加解密測試: " . ($data === $decrypted ? '通過' : '失敗') . "\n";