zzxworld

在 Mac 系统上搭建 PHP 开发环境

我又在折腾 Mac 系统了,连续几天一直在不断尝试和调整相关的软件工具,只为完成一个在 macOS 上用起来比较舒适的工作环境。这篇文章是我折腾 PHP 开发环境的过程记录。

今年年中的时候其实折腾过一次,过程记录在《一台 Intel NUC 的黑苹果之旅》这篇文章中。当时也是因为对开发环境的效果不太理想,所以就换回 Linux 系统了,并表示不再折腾黑苹果,没想到这立马就自己打脸。

不过原因也不全在我这边。我是砸锅卖铁凑齐了预算,攥着钱等 Apple 秋季发布会上出 M2 版本 Mac Mini,哪知道它没出。而我现在有了越来越多与写代码无关的工作内容,在 Linux 系统上已经没办法很舒服的来完成这些工作。无奈之下只能再次选择黑苹果。

再见了,Docker 和 Podman

上次在 NUC 盒子上折腾黑苹果不满意的主要原因是频繁起飞的风扇,怕机器扛不住烧了。这次经过反复尝试,发现原因还是出在虚拟机上。这是在 Mac 系统上使用容器引擎必须要承担的硬件资源代价。不论是安装 Docker 还是 Podman 都会有这么个东西。而我以为这台配备了 32GB 内存加 M.2 接口固态硬盘的 NUC 性能应该也足以支撑 Mac 上容器引擎的虚拟机,事实证明这所谓的不再「挤牙膏」的 Intel 8 代 CPU 也不过如此。

我现在搭建开发环境很依赖 Docker 和 Podman,但我同样很想用回 Mac 系统,体验更加舒适的桌面工作环境。二者目前不可兼得,综合考虑,只能舍弃容器引擎所带来的便利。

不用容器引擎了该如何搭建开发环境呢?答案是回到 Docker 还没出现时的时候,用 Homebrew,和源码编译。源码编译是个苦力活儿,需要自己解决软件依赖问题,能不用就不用。所以主要还是靠 Homebrew。

安装 Homebrew

Homebrew 在 Mac 电脑是必备,关于它的安装方式,可以参考我前面一篇专门介绍它的文章:

安装好 Homebrew 后,后面一切就简单了。

安装 Nginx

Nginx 用来作为本地开发环境的 Web 服务。使用 brew 命令安装 Nginx:

brew install nginx

然后启动 Nginx 服务:

brew services start nginx

使用 brew servicesstart 子命令启动的软件服务在开机时也会自动启动,所以后面就不用管了,每次开机 Nginx 都会自动启动起来。

安装 PHP

PHP 是我目前的主要编程语言,而且因为有不同时期多个项目的原因,横跨了三个版本。分别是 7.2, 7.4, 8.1。所以我需要安装 3 个版本的 PHP,并且同时运行。使用 brew search php 命令可以查看 Homebrew 提供的所有 PHP 版本:

❯ brew search php
==> Formulae
brew-php-switcher   php@7.2             phplint             pcp
php                 php@7.3             phpmd               pup
php-code-sniffer    php@7.4             phpmyadmin
php-cs-fixer        php@8.0             phpstan
php-cs-fixer@2      phpbrew             phpunit

==> Casks
eclipse-php         phpstorm            phpwebstudy         pop

当前时间(2022-11-14)下,php 是 8.1 版本,php@7.2php@7.4 分别是 7.2 和 7.4 版本。所以我只要直接安装这几个软件包就可以了:

brew install php@7.2 php@7.4 php

结果发现 php@7.2 无法安装,报如下错误:

Error: php@7.2 has been disabled because it is deprecated upstream!

看来是版本太老,直接废弃了。所以我只能选择源码编译,或是把用 PHP7.2 的项目升级到 7.4。想了想还是选择后者吧,这技术债早就该还了。

使用上面命令安装的 PHP 默认也已创建好了相应的 PHP FPM 服务。使用 brew services 命令可以查看:

❯ brew services
Name    Status  User     File
nginx   started zzxworld ~/Library/LaunchAgents/homebrew.mxcl.nginx.plist
php
php@7.4

在开始启动它们之前,需要先调整一下它们各自的服务端口,因为它们的默认端口都是 9000,直接启动会发生冲突。

配置文件位于 /usr/local/etc/php/ 目录下,有两个版本号目录。进去后打开 php-fpm.d/www.conf 文件,并找到如下内容:

listen = 127.0.0.1:9000

我把 7.4 的改成了 listen = 127.0.0.1:9074,8.1 版本的改为了 listen = 127.0.0.1:9081。这样在 Nginx 配置中根据项目只需要设置不同的端口号就能使用不同的 PHP 版本了。

完成修改后保存,然后可以启动服务了:

brew services start php
brew services start php@7.4

安装 NVM

Web 项目离不开前端开发,而现在前端开发自然也少不了支撑打包的底层技术 Node.js。和 PHP 一样,我手里的项目对 Node.js 也存在不同版本的依赖需求。有的用 10,有的是 17。不过和 PHP 不同的是,Node.js 有一个版本管理神器:NVM,可以用来管理各种不同版本的 Node.js。

安装 NVM 的命令:

brew install nvm

然后就可以使用 nvm 命令来安装制定版本的 Node.js 了:

nvm install 10
nvm install 17

在不同的项目中,使用 nvm use 命令就可以指定需要使用的版本:

nvm use 10

安装数据库

最后需要安装的是和数据存储相关的服务:MySQL 和 Redis。它们因为项目和版本的依赖关系不大,所以安装最新版本也没问题:

brew install mariadb redis

安装后启动它们:

brew services start mariadb
brew services start redis

后记

在舍弃容器化引擎的开发环境搭建方案后,我这台基于 NUC 的黑苹果目前显得安静了许多。风扇完全没有上次尝试时那么「狂躁」。不过我还不太确定是不是和气温有关系,毕竟现在环境温度本身就比较低。但有一点是可以确定的,项目在开发环境下的的整体运行性能提升了许多。

我用其中一个项目的前端打包来测试了一下,使用容器方式的运行时间如下:

bin/npm run dev  0.04s user 0.02s system 0% cpu 1:20.24 total

不使用容器的运行时间如下:

npm run dev  7.58s user 0.47s system 151% cpu 5.328 total

相同的项目,在容器内打包耗时 1 分 20 秒,不用容器只要 5 秒。就冲这差距,在 macOS 上放弃容器作为开发环境还是值得的。

2 条评论

  1. Sammy
    对于新手有点不友好,还是用集成开发环境比较方便。 比如ServBay,集成了各个版本的PHP,包括最新版的,比MAMP还方便。只要下载安装,3分钟就能开始写代码。甚至可以快速的在不同版本间进行切换以及同时运行多个版本的PHP,极大的方便调试。 这个软件不会污染系统环境,因为数据都在独立的目录下备份或者更换电脑的话,直接把文件夹打包拷贝走就可以。 不是广子,但真心推荐使用
    • zzxworld
      集成开发环境的确是一个方便快捷的开发环境搭建选择,适合自己就好。