PHPBrew 是一个构建、安装多版本 PHP 到用户根目录的工具。

PHPBrew 安装

MacOS 环境下载安装 PHPBrew,并进行初始化

  1. # 下载 phar 包 (类似于 Jar 包)
  2. curl -L -O https://github.com/phpbrew/phpbrew/releases/latest/download/phpbrew.phar
  3. # 添加执行权限
  4. chmod +x phpbrew.phar
  5. # 将文件移动到环境变量 $PATH 的某个子目录下
  6. sudo mv phpbrew.phar /usr/local/bin/phpbrew
  7. # 初始化 Bash Shell 脚本
  8. phpbrew init

.bashrc.zshrc 文件添加如下代码

# PhpBrew
[[ -e ~/.phpbrew/bashrc ]] && source ~/.phpbrew/bashrc
export PHPBREW_SET_PROMPT=1

设置用于查找库文件的默认前缀

# HomeBrew 用户执行
phpbrew lookup-prefix homebrew

配置 php.ini

# 指定 EDITOR 环境变量
export EDITOR=vim

# 配置 php.ini
phpbrew config

PHP 版本安装

安装 PHP 时建议配合 Variant 使用

# 列出已知 PHP 版本
phpbrew known

# 安装指定版本 PHP,输出调试信息
# 可在 ~/.phpbrew/php 目录找到已安装的PHP
phpbrew install -d 版本号

# 安装指定版本 PHP,编译完成后执行测试用例
phpbrew install --test 版本号

# 列出已安装的 PHP 版本
phpbrew list

# 切换默认 PHP 版本
phpbrew switch 版本号

# 临时切换 PHP 版本
phpbrew use 版本号

# 关闭 phpbrew
phpbrew off

Variant 安装

# 列出支持的 Variant 
phpbrew variants

# +default:使用默认参数编译安装 php
# +fpm:安装 php-fpm,位于 ~/.phpbrew/php/php-*/sbin 目录。配置文件位于 ~/.phpbrew/php/php-*/etc/php-fpm.d 目录
# +debug: 安装 xdebug 扩展
phpbrew install -d 版本号 +default +fpm +debug

Ext 扩展安装

对应的扩展文件安装于 ~/.phpbrew/build/php-版本号/ext 目录 安装扩展后,需要重启 pfm 服务才会生效

# 配置当前 PHP 版本的 php.ini 文件
phpbrew config

# --debug 输出安装过程
# 列出支持的扩展版本号
phpbrew --debug ext known 扩展名

# 安装扩展(注意不要 sudo)
# 不指定版本号是默认使用最新
phpbrew --debug ext install 扩展名 版本号

# 删除扩展(注意不要 sudo)
phpbrew --debug ext clean phalcon

Xdebug 配置

xdebug 默认监听 9003 端口

phpbrew 默认安装后,在 phpinfo 中已可以查看 xdebug 相关信息。默认并没有开启 Step Debugging ,需要配置 php.ini 并重启 php-fpm

# Xdebug2 版本,需要添加如下配置
[xdebug]
xdebug.remote_enable=1
xdebug.default_enable=0
xdebug.profiler_enable=0
xdebug.auto_trace=0
xdebug.coverage_enable=0

# Xdebug3 版本后,只需要添加一行配置
[xdebug]
xdebug.mode = debug

在 PhpStorm 的偏好设置中,找到 Languages & Frameworks > PHP > Debug 页面,校验 xdebug 是否有效
image.png

PHP-FPM

已安装的 php-fpm 位于 ~/.phpbrew/php/php-/sbin 目录 对应的 php-fpm.conf 文件位于 ~/.phpbrew/php/php-/etc/php-fpm.conf 目录

# 列出 php-fpm 模块
phpbrew fpm module

# 编辑 php-fpm 配置
phpbrew fpm config

# 测试 php-fpm 配置
phpbrew fpm test

# 启动 php-fpm
# 默认端口配置: ~/.phpbrew/php/php-版本号/var/run/php-fpm.sock
phpbrew fpm start

# 查找 php-fpm 所在的进程
ps -ef | grep php-fpm
# 查找 php-fpm 配置文件所在路径
ps -ef | grep php-fpm.conf
# 

# 停止 php-fpm
phpbrew fpm stop

PHP-FPM + Nginx

Nginx 的部分配置参考如下:

location ~ [^/]\.php(/|$) {
        # phpbrew 安装的 php-fpm 默认端口配置为: ~/.phpbrew/php/php-版本号/var/run/php-fpm.sock 。
    fastcgi_pass  unix:/Users/zed/.phpbrew/php/php-7.4.20/var/run/php-fpm.sock;
    fastcgi_index /index.php;

    include fastcgi_params;
    fastcgi_split_path_info ^(.+?\.php)(/.*)$;

    fastcgi_param PATH_INFO       $fastcgi_path_info;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}

# 配置 error_log 错误日志文件
error_log  /usr/local/etc/nginx/logs/域名.error.log;

Nginx 502 问题

在编译 php-fpm 时没有指定 fpm 用户,且在配置文件中也没有指定用户,则 sock 文件会由启动 php-fpm 的用户创建,其权限是 srw-rw——。若与启动 nginx 的用户不同,则可能导致无权限读取 sock 文件,造成 nginx 返回 502 错误。

2021/06/26 22:42:31 [crit] 3004#0: *1020 connect() to unix:/Users/zed/.phpbrew/php/php-7.4.20/var/run/php-fpm.sock failed (13: Permission denied) while connecting to upstream, client: 192.168.199.171, server: 34ia493387.zicp.vip, request: "GET /phpinfo.php HTTP/1.1", upstream: "fastcgi://unix:/Users/zed/.phpbrew/php/php-7.4.20/var/run/php-fpm.sock:", host: "34ia493387.zicp.vip"

解决办法是在配置文件中指定 listen 为具备相应权限的用户,修改后重启 php-fpm 生效

  • Linux环境下:nginx 一般由 nginx 用户启动
  • MacOS 环境下:
    • 执行 sudo 运行的,则由 root 用户启动
    • 没有执行 sudo 运行的, 则由当前登陆用户启动
  • 可查询 80 端口的使用情况,判断 nginx 的启动用户
    • lsof -i tcp:80 ,根据情况添加 sudo
      ; Set permissions for unix socket, if one is used. In Linux, read/write
      ; permissions must be set in order to allow connections from a web server. Many
      ; BSD-derived systems allow connections regardless of permissions. The owner
      ; and group can be specified either by name or by their numeric IDs.
      ; Default Values: user and group are set as the running user
      ;                 mode is set to 0660
      listen.owner = nginx
      listen.group = nginx
      listen.mode = 0666