mac跑php测试环境应避开系统自带apache+php,因其版本老旧、模块不可靠;推荐方案为homebrew+nginx+php-fpm(主力)、docker分离部署(项目隔离)或xampp兜底,三者稳定可控且可复现。

Mac 上跑 PHP 测试环境,别碰系统自带的 Apache + PHP 组合——版本老旧(macOS 14+ 已移除 PHP)、模块加载不可靠、扩展难启用,php -v 显示版本 ≠ http://localhost/info.php 能执行。真正稳定、可控、可复现的方案只有三个:Homebrew + Nginx + php-fpm、Docker 分离部署、或 XAMPP 快速兜底。
用 brew 装 nginx + php-fpm(推荐主力方案)
这是开发中实际最常用、最易调试、又不污染系统的路径。Homebrew 安装的 php 默认带 php-fpm,Nginx 作为反向代理把 .php 请求转发过去,职责清晰,日志和错误定位直接。
- 先确认没冲突:
sudo apachectl stop停掉系统 Apache,避免端口占用(80 端口) - 安装命令(Apple Silicon):
brew install nginx php;Intel 机器同命令,路径自动适配 - 启动服务:
brew services start nginx和brew services start php - 关键配置在
/opt/homebrew/etc/nginx/nginx.conf(Apple Silicon)或/usr/local/etc/nginx/nginx.conf(Intel):
确保server块里有这段:
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
- 测试文件放在
/opt/homebrew/var/www/(默认根目录),访问http://localhost/index.php即可验证
用 docker-compose 快速拉起(项目级隔离首选)
当你需要多个项目用不同 PHP 版本、或带 MySQL/Redis、或不想本地留任何服务痕迹时,Docker 是唯一干净解法。它不改 PATH、不启全局服务、docker-compose down 一键清空。
- 新建
docker-compose.yml,核心两服务必须分离:web(nginx)和php(php-fpm),不能合在一个镜像里 - PHP 镜像选
php:8.2-fpm-alpine或php:8.3-cli-alpine,体积小、启动快 - 挂载代码务必用绝对路径或
.相对路径,避免./src:/var/www/html这类写法失效(Docker Desktop for Mac 对路径解析有缓存) - Nginx 配置中
fastcgi_pass php:9000(不是127.0.0.1:9000),因为容器间通信走内部网络 - 第一次运行前,
chmod -R 755 ./your-project,否则 PHP 容器可能因权限拒绝读取文件
绕开系统 Apache 的坑(为什么别碰 /etc/apache2/httpd.conf)
macOS 13(Ventura)起,系统 Apache 的 libphp.so 模块已被标记为 deprecated;14(Sonoma)及以后彻底移除。即使你手动编译或替换模块,也会遇到:
-
httpd -t报错:Cannot load modules/libphp.so into server—— 模块架构不匹配(arm64 vs x86_64) - 启用
LoadModule php_module后,apachectl restart成功,但浏览器打开 .php 文件直接下载,不解析 —— 缺少AddHandler application/x-httpd-php .php和正确的DirectoryIndex -
phpinfo()显示的Loaded Configuration File是/etc/php.ini,但 Homebrew 安装的扩展(如gd、opcache)默认装在/opt/homebrew/etc/php/8.3/conf.d/下,不会被系统 PHP 加载
验证环境是否真可用(别只信 php -v)
php -v 成功只是第一步。真实 PHP Web 环境要过三关:
- Web 服务器能否把请求正确交给 PHP 进程?看 Nginx error log:
tail -f /opt/homebrew/var/log/nginx/error.log,出现connect() failed (61: Connection refused) while connecting to upstream就是 php-fpm 没起来或端口不对 - PHP 是否能加载扩展?写个
test.php:<?php var_dump(extension_loaded('mysqli'));,返回bool(true)才算数 - 文件权限是否允许 Web 进程读取?Nginx worker 进程默认以
_www用户运行,你的项目目录需至少有o+rX权限(chmod -R o+rX /path/to/project) - 注意
php.ini实际生效路径:php --ini输出的 “Loaded Configuration File” 才是真实加载的文件,修改错位置等于白改
最常被跳过的一步:每次改完 Nginx 或 php-fpm 配置,必须分别 reload 两个服务,brew services restart nginx 不会自动 restart php,反之亦然。容器方案里,docker-compose up -d 后也要 docker-compose exec php php -v 进容器内确认扩展已装好——本地命令行看到的 PHP 和容器里跑的,根本不是同一个东西。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











