前言

2021年第一篇,最近想用 PHP 搞个项目玩玩,但万万没想到倒在了环境搭建这一步。

首先在网上冲浪一番后,你会发现PHP的搭建方式其实挺多(但有时候选择多并不是一件好事),目前常见的搭建方式有:Homestead(基于虚拟机)、XAMPP、MAMP、Laradock(基于Docker)等,但这些都比较重量级;轻量级的也有,比如 Valet,但之前试过 Valet 发现它会修改本地配置,典型如Nginx,而且在卸载的时候还不小心把Nginx配置全删了,顿时觉得不太可控,所以最后选择的方案是 Nginx + php-fpm,足够可用,同时也不会太重量级。

注:本文基于 Mac 环境。

安装流程

  • 1.检查 php 是否安装
  • 2.检查 composer 是否安装
  • 3.检查 laravel 是否安装
  • 4.检查 php-fpm 是否安装
  • 5.检查 nginx 是否安装
  • 6.设置多版本共存
  • 7.创建 laravel 项目并测试

检查php是否安装

现在比较新的 Mac 系统都会自带php以及php-fpm,如下:

# 版本$ php -vPHP 7.3.11 (cli) (built: Jun  5 2020 23:50:40) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.3.11, Copyright (c) 1998-2018 Zend Technologies# 执行路径$ which php/usr/bin/php# 配置文件$ ls /etc/php-fpm.conf/etc/php-fpm.conf# 实际的配置文件,因为 /etc/php-fpm.conf 使用了include关键字$ ls /private/etc/php-fpm.dwww.conf         www.conf.default复制代码

检查composer是否安装

composer 是php的包管理器,类似 pip,这个Mac系统就没有自带,需要自己安装。

# 安装$ brew install composer$ composer --versionComposer version 1.9.0 2019-08-02 20:55:32复制代码

检查laravel是否安装

这个不是非必须,主要是后面会创建laravel项目,来测试php环境是否搭建成功,建议安装,后续你也会用到。

# 安装$ composer global require laravel/installer# 测试$ laravel --versionLaravel Installer 4.1.1复制代码

检查nginx是否安装

由于我搭建php环境选择的方案是 nginx + php-fpm,所以这里必须安装nginx(其实不管啥方案都会用到nginx,区别是自己安装,还是别人帮你安装好)。

# 安装$ brew install nginx# 测试$ nginx -vnginx version: nginx/1.19.5复制代码

多版本共存

由于历史原因,很多项目的php版本并没有一个统一的标准,项目版本可能会在php5.6、php7.2,甚至php8.0之间跳跃,而版本的不一致则带来语法的不一致,导致出现一些奇怪的问题,所以多版本共存就显得非常重要。

本次通过homebrew实现多版本并存,实现起来也比较简单,首先我们弃用Mac自带的php,全部使用brew安装的。

安装php5.6

# 安装$ brew install php@5.6# 配置环境变量 (可通过 brew info php@5.6 查看)echo 'export PATH="/usr/local/opt/php@5.6/bin:$PATH"' >> ~/.zshrc
echo 'export PATH="/usr/local/opt/php@5.6/sbin:$PATH"' >> ~/.zshrc复制代码

安装php7.2

# 安装$ brew install php@7.2# 配置环境变量 (可通过 brew info php@7.2 查看)echo 'export PATH="/usr/local/opt/php@7.2/bin:$PATH"' >> ~/.zshrc
echo 'export PATH="/usr/local/opt/php@7.2/sbin:$PATH"' >> ~/.zshrc复制代码

php-fpm 配置不同端口

多版本共存的核心是启动不同版本的 php-fpm,所以就要避免端口占用。

为啥需要 php-fpm 呢?这也是我一开始疑惑的地方,这是因为PHP不像Javascript,可以直接被浏览器解析,所以当用户请求PHP程序时,会先经过Nginx,Nginx会通过php-fpm将请求转发到php解释器,并进行处理,具体可以参考这里

# 配置文件路径可通过 brew info php@5.6 或者 brew info php@7.2 得到# php5.6 监听9001端口$ vim /usr/local/etc/php/5.6/php-fpm.conflisten = 127.0.0.1:9001 
# php7.2 监听9002端口$ vim /usr/local/etc/php/7.2/php-fpm.d/www.conflisten = 127.0.0.1:9002复制代码

启动服务

# 启动php5.6brew services start shivammathur/php/php@5.6# 启动php7.2brew services start php@7.2# 查看$ ps -ef | grep php-fpm501 12981     1   0 11:35上午 ??         0:00.15 /usr/local/opt/php@5.6/sbin/php-fpm --nodaemonize
501 12988 12981   0 11:35上午 ??         0:00.74 /usr/local/opt/php@5.6/sbin/php-fpm --nodaemonize
501 12989 12981   0 11:35上午 ??         0:00.00 /usr/local/opt/php@5.6/sbin/php-fpm --nodaemonize
501 13141     1   0 11:35上午 ??         0:00.14 /usr/local/opt/php@7.2/sbin/php-fpm --nodaemonize
501 13148 13141   0 11:35上午 ??         0:00.17 /usr/local/opt/php@7.2/sbin/php-fpm --nodaemonize
501 13149 13141   0 11:35上午 ??         0:00.00 /usr/local/opt/php@7.2/sbin/php-fpm --nodaemonize复制代码

此时php多版本搭建完毕,通过后面的测试可以查看搭建是否成功。

项目部署及测试

本次我们会通过部署两个版本的laravel项目,从而测试上述多版本的正确性,以及让朋友们知道如何部署php项目。

1.创建项目

# 创建项目# laravel 5.2 要求的php版本最低是 5.5.9composer create-project laravel/laravel=5.2.* php56 --prefer-dist# laravel 5.6 要求的php版本最低是 7.1.3composer create-project laravel/laravel=5.6.* php72 --prefer-dist复制代码

2.创建 blog56 的配置

vim /usr/local/etc/nginx/servers/php56.conf

server {
        # 监听的端口,也就是我们访问的端口
        listen       6001 default_server;
        server_name  127.0.0.1;

        # 默认网站根目录(www目录)
        root        /Users/xxx/PhpstormProjects/php56/public;
        access_log /Users/xxx/PhpstormProjects/php56/access.log;
        error_log /Users/xxx/PhpstormProjects/php56/error.log;

        location / {
            try_files $uri /index.php?$query_string;
        }

        error_page 404 /404.html;
            location = /40x.html {
        }

        error_page 500 502 503 504 /50x.html;
            location = /50x.html {
        }

        # PHP 脚本请求全部转发到 FastCGI处理. 使用FastCGI协议默认配置.
        location ~ \.php$ {
            # 这个是我们上述设置的端口,9001会交由 php5.6 处理
            fastcgi_pass   127.0.0.1:9001;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
            include        fastcgi_params;
        }
    }复制代码

3.创建 blog72 的配置

vim /usr/local/etc/nginx/servers/php72.conf

server {
        # 监听的端口,也就是我们访问的端口
        listen       6002 default_server;
        server_name  127.0.0.1;

        # 默认网站根目录(www目录)
        root        /Users/xxx/PhpstormProjects/php72/public;
        access_log /Users/xxx/PhpstormProjects/php72/access.log;
        error_log /Users/xxx/PhpstormProjects/php72/error.log;

        location / {
            try_files $uri /index.php?$query_string;
        }

        error_page 404 /404.html;
            location = /40x.html {
        }

        error_page 500 502 503 504 /50x.html;
            location = /50x.html {
        }

        # PHP 脚本请求全部转发到 FastCGI处理. 使用FastCGI协议默认配置.
        location ~ \.php$ {
            # 这个是我们上述设置的端口,9002会交由 php7.2 处理
            fastcgi_pass   127.0.0.1:9002;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
            include        fastcgi_params;
        }
    }复制代码

4.访问测试: 浏览器访问 http://localhost:6001/ 以及 http://localhost:6002/ 可以看到欢迎界面

踩坑总结

1.Nginx配置一定要加上 access_log 和 error_log,这样出错的时候才能定位到,因为很多情况下都是Nginx配置出问题!!!

2.注意浏览器代理问题,很多人包括我习惯性在浏览器测试(GET请求),但有时候由于代理问题,请求会失败,这时可尝试在命令行,或者其他浏览器执行(个人经验)

3.之前一开始配置时参考过一篇文章[《Laravel 项目部署,php-fpm 及 nginx 配置》],但是配置后会出现"访问直接下载index.php文件"的情况,原因是该文的Nginx配置有点问题:

# 作者的配置(不能说他配置有问题,只能说大家环境不同)location / {
        try_files $uri $uri/ /index.php?$query_string;
    }# 实际的配置location / {
        try_files $uri /index.php?$query_string;
    }复制代码

解决方案参考:https://stackoverflow.com/questions/19285355/nginx-403-error-directory-index-of-folder-is-forbidden

提醒:这里要给个提醒,很多人由于配置不正确(权限或者路径问题),导致访问失败,所以切记一定要加上 access_log 和 error_log,才能知道报了什么错!!另外,有时候可能由于代理问题,在浏览器直接测试可能会不成功。