PHPBrew:編譯 PHP 的各種踩雷紀錄
PHPBrew 是由 C9S 大神產出來的神作,一直以來都用它維護伺服器上的 PHP 版本,但時常會有一些小問題要解決。這次剛好要裝到新機器上,就順便記錄一下遇到的一些狀況。
系統環境
新開的 VPS 主機,作業系統為 CentOS 7.5,已經用 yum update 更新到最新環境,有啟用 epel-release repository。
Requirement
先安裝官方 Wiki 指定的基本套件,使用的是以下段落:
https://github.com/phpbrew/phpbrew/wiki/Requirement#fedoracentos-requirements
這頁面的另一個段落(CentOS Requirement)親身實驗確定已失效,repoforge.org 已經掛很久啦!!
yum install make automake gcc gcc-c++ kernel-devel
yum install php php-devel php-pear bzip2-devel yum-utils bison re2c libmcrypt-devel libpqxx-devel libxslt-devel pcre-devel libcurl-devel libgsasl-devel openldap-devel
yum-builddep php
yum install httpd-devel
以及我自己需要裝的相依,注意 readline
是有包含在 +default
的,如果你也是指定 +default
,記得安裝。
yum install readline-devel ImageMagick-devel libmemcached-devel
Installing PHPBrew into System wide Environment
參考資料:https://github.com/phpbrew/phpbrew/wiki/Installing-PHPBrew-into-System-wide-Environment
如果想要讓編譯的 PHP 可以給所有使用者使用,就使用 root 來編譯吧。
sudo -i # 切換成 root 身份
phpbrew init
增加環境變數到 PHPBrew 的 bashrc
vim ~/.phpbrew/bashrc
增加 PHPBREW_ROOT
和 PHPBREW_HOME
環境變數到開頭。
# /.phpbrew/bashrc
export PHPBREW_ROOT=/opt/phpbrew # php dist files and build files are stored here
export PHPBREW_HOME=/root/.phpbrew # your configuration files.
重新載入
source ~/.phpbrew/bashrc
設定登入自動執行檔
接著設定所有使用者的登入自動執行檔,讓大家可以使用同一個 PHP 版本。
這裡註記一下,官方 Wiki 建議放在 /etc/profile.d/phpbrew
是錯的。系統預設只會載入 *.sh
的腳本,所以應該要命名為 phpbrew.sh
。
vim /etc/profile.d/phpbrew.sh
增加 PHPBREW_ROOT
和 PHPBREW_HOME
環境變數到開頭。
# /etc/profile.d/phpbrew.sh
export PHPBREW_ROOT=/opt/phpbrew
export PHPBREW_HOME=$HOME/.phpbrew
[[ -e ~/.phpbrew/bashrc ]] && source ~/.phpbrew/bashrc
官方 Wiki 的 Cookbook 把 PHPBREW_HOME
寫錯了,source bashrc 的檔案則是 Cookbook 和 Installing PHPBrew into System wide Environment 都錯,詳情請看下方的錯誤紀錄。
Setting up
參考資料:https://github.com/phpbrew/phpbrew#setting-up
更新一下 PHP 的版本列表
phpbrew update
Starting Building Your Own PHP
參考資料:https://github.com/phpbrew/phpbrew#starting-building-your-own-php
來開始編譯 PHP 吧
phpbrew install 7.1.7 +default +pdo +mysql +gd=shared +fpm -- --with-fpm-systemd --with-libdir=lib64
將系統 PHP 切換到我們編譯的 php-7.1.7
phpbrew switch php-7.1.7
然後安裝需要的擴充模組
phpbrew ext install imagick
phpbrew ext install memcached
phpbrew ext install redis
phpbrew ext install gd -- --with-gd=shared --enable-gd-native-ttf --with-jpeg-dir=/usr/lib64 --with-png-dir=/usr/lib64
PHP 設定
接著就可以編輯一些設定了
設定 php.ini
例如想要修改 php.ini 設定 expose_php
為 Off 把版本號資訊隱藏
只要執行以下命令就可以打開當前版本的 php.ini
phpbrew config
就會用預設的編輯器(如 nano)開啟 php.ini
如果你想要使用 Vim 等其他編輯器開啟
記得指定 EDITOR
環境變數
例如在 ~/.bashrc 中加入
export EDITOR=vim
設定 php-fpm.conf
如果想要設定如 max_children
等針對 FPM 的設定
也是有簡單的指令即可開啟當前版本的 php-fpm.conf
phpbrew fpm config
錯誤紀錄
稍微紀錄一下編譯與安裝時遇到的錯誤。
configure: error: Cannot find OpenSSL’s libraries
如果要讓編譯的 PHP 支援 OpenSSL,在 Fedora/Centos 64-Bit 系統需要加上 --with-libdir=lib64
來編譯。可以參考以下資料:
- https://github.com/phpbrew/phpbrew/wiki/Cookbook#openssl-support
- https://github.com/phpbrew/phpbrew/wiki/Extension-Installer#fedoracentos-64-bit
- https://github.com/phpbrew/phpbrew/issues/785#issuecomment-243427848
configure: error: Please reinstall readline - I cannot find readline.h
如果你是使用 +default
選項,就會需要先安裝 readline-devel
。參考資料:
PHPBrew 安裝成全域(system-wide),重登入卻沒抓到
文件建議把環境變數放在 /etc/profile.d/phpbrew
,這部分寫錯了。
/etc/bashrc
預設只會載入 /etc/profile.d/*.sh
,所以應該要命名為 /etc/profile.d/phpbrew.sh
。
-bash: /opt/phpbrew/bashrc: No such file or directory
Cookbook 和 Installing PHPBrew into System wide Environment 都這樣指定,卻沒有這個檔案,不知道為什麼。我暫時改為 [[ -e ~/.phpbrew/bashrc ]] && source ~/.phpbrew/bashrc
。參考以下資料:
module ‘某擴充模組’ already loaded in unknown on line 0
我遇到的是 module 'curl' already loaded in unknown on line 0
,通常是因為編譯的時候重複指定了 Variants,例如我原本沒發現 +default
裡面有 curl 就又多寫了一個 +curl
。這個解決方法我找不到,只能刪除重新編譯了。
如何移除某一版本 PHP?
這個文件裡面沒有寫,但 phpbrew help
以及 一些 Issue 中有提到。
phpbrew remove [php-version]
phpbrew purge [php-version]
要注意的是,php-version
要填完整名稱,不能像 phpbrew switch
可以只填版本號。例如 phpbrew remove php-7.1.7
。
從 phpbrew help
的說明可以看出 remove
和 purge
是有點差異的。
remove Remove installed php build.
purge Remove installed php version and config files.
另外前者會有確認提示:
phpbrew remove php-7.1.7
# Are you sure to delete php-7.1.7? [Y/n]
# php-7.1.7 is removed. I hope you're not surprised. :)
後者則是直接刪除:
phpbrew purge php-7.1.7
# php version: php-7.1.7 is removed and purged.
PHP Warning: PHP Startup: Invalid library (maybe not a PHP library) ‘curl.so’ in Unknown on line 0
這是因為已經用 +default
把 curl 編譯進去了,如果又再用 phpbrew ext install curl
安裝擴充模組就會造成錯誤。解決方法是停用 curl 外掛:
phpbrew ext disable curl
參考資料:
但我也有執行 phpbrew ext install gd
,不知道為什麼沒有報錯就是了⋯⋯
PHP Warning: touch(): Unable to create file /opt/phpbrew/bin/composer because No such file or directory in phar:///usr/local/bin/phpbrew/src/PhpBrew/Downloader/BaseDownloader.php on line 43
執行 phpbrew app get composer
安裝 Composer 的時候,不知道為什麼它不能自己 mkdir,錯誤訊息是 RuntimeException: Target path (/opt/phpbrew/bin/composer) is not writable!
理論上 ~/.phpbrew/bashrc
會幫你自動建好 /opt/phpbrew/bin
目錄,所以可能是你的 ~/.phpbrew/bashrc
沒有設定好。
之後要執行的話就是使用以下指令
php composer command [options] [arguments]
還要多打一個 php 有點麻煩,所以我還是移除改成 Composer 官方的安裝方式了。
終於裝完了
歷經好幾個小時(淚