在同一服务器上运行两个不同版本的PHP

39

我在本地服务器上有两个项目,一个是运行PHP5.6的,另一个是运行PHP7.0的。现在是否有可能基于这两个项目启用这两个版本? 我已经尝试在其中一个项目的htaccess中添加 AddHandler application/x-httpd-php7 .php,但它没有起作用。目前,在服务器上已安装了PHP7.0和PHP5.6-fpm。下面是 phpinfo() 的截图。

图片描述


你的 Apache 目录中 mod-enabled 的输出是什么?你确定你在那里启用了 php5.x 和 php7.0x 两个版本吗? - hassan
请问如何安装并轻松切换两个版本的PHP? - Vasil Rashkov
嗨@HassanAhmed,只有php7.0和php5.6-fpm被启用。当我启用php5.6时,Apache崩溃了。也许它不知道该获取哪个版本。 - etcz0ne
看一下 Docker。 - yBrodsky
看看这个非常详细的回答,针对Debian / Apache: https://dev59.com/w1cO5IYBdhLWcg3w7lvq - erwan
8个回答

37

经过一整天在Google上的搜索,我终于设法在不同的PHP版本上以FastCgi的方式运行了我的两个项目。感谢这个论坛的各位。

我卸载了包括Apache在内的所有东西,然后重新开始。以下是我用来在本地服务器上启用两个版本的PHP所使用的步骤。顺便说一句,我的电脑运行在Linux Mint 18系统上。

  1. 假设您已经安装了Apache,为这两个项目创建了虚拟主机,并添加了必要的PHP PPAs。我们将称这两个项目分别为site56.localsite70.local。通过运行以下命令安装php5.6-fpmphp7.0-fpm

     sudo apt-get install php5.6-fpm
     sudo apt-get install php7.0-fpm
    
  2. /usr/lib/cgi-bin/下创建两个文件(老实说我不知道这一步是否仍然必要),并保存:

  3.  sudo nano /usr/lib/cgi-bin/php56-fcgi
     sudo nano /usr/lib/cgi-bin/php70-fcgi
    
  4. 打开php56配置文件 /etc/apache2/conf-available/php5.6-fpm.conf,添加以下配置并保存:

  5.  <IfModule mod_fastcgi.c>
         AddHandler php56-fcgi .php
         Action php56-fcgi /php56-fcgi
         Alias /php56-fcgi /usr/lib/cgi-bin/php56-fcgi -socket /var/run/php/php5.6-fpm.sock -pass-header Authorization
         Action php70-fcgi /php70-fcgi
         Alias /php70-fcgi /usr/lib/cgi-bin/php70-fcgi -socket /var/run/php/php7.0-fpm.sock -pass-header Authorization
     </IfModule>
     <Directory /usr/lib/cgi-bin>
         Require all granted
     </Directory>
    
  6. 现在启用新的Apache配置:

     sudo a2enconf php5.6-fpm
    
  7. 如果您安装了php5.6和php5.7,请确保禁用这两个版本并重新启动Apache:

  8.  sudo a2dismod php5.6 php7.0
     sudo systemctl restart apache2
    
  9. Create a .htacces file on the project that should run on php7.0 and add this handler:

     AddHandler php70-fcgi .php
    
  10. 现在在这两个项目上创建一个phpinfo文件,如果您看到类似于以下内容的信息,则表示恭喜!

PS:确保您在apache2.confhttpd.conf中启用.htaccess

site56.local/phpinfo.php

site70.local/phpinfo.php


如果您想要安装 PHP 5.5.9 而不是 PHP 5.6,则需要安装 php5-fpm。此外,php5-fpm.conf 文件的内容应与此链接中的内容相同:https://pastebin.com/3UgdxNV7 - accord_guy
我还需要运行 sudo apt-get install php5.6-mbstring php5.6-mcrypt php5.6-mysql php5.6-xml,如这里所述的被接受的答案。 - Pawel
2
我不知道你是否逐步正确地尝试了你的解决方案,因为在启用php5.6-fpm conf后重新启动Apache时,我遇到了这个错误:Alias takes 1-2 arguments, a fakename and a realname, or a realname in a Location - Morgan
太棒了!但我需要适用于CentOS的版本。 - Ray
有人知道我是否可以默认为所有虚拟主机使用mod_php,并且对于特定的<Directory>使用php-fpm(不同版本)吗?SetHandler应该有优先级,但不幸的是对我来说不起作用(PHP模块总是接管)。 - undefined

8

首先,运行以下命令确保所有与PHP相关的配置都已禁用:

# ls -la /etc/apache2/conf-enabled | grep php

# ls -la /etc/apache2/mods-enabled | grep php

为特定网站设置不同版本的PHP-FPM:

将以下行添加到现有的VirtualHost文件中。

Include "conf-available/php7.2-fpm.conf"

例如,
# 编辑 /etc/apache2/sites-enabled/symfony.local.conf 文件
<VirtualHost *:80>
    ServerName symfony.local

    Include "conf-available/php7.2-fpm.conf"

    ServerAdmin webmaster@localhost
    DocumentRoot /var/www/symfony.local/curr/public

    <Directory /var/www/symfony.local/curr/web>
        AllowOverride All
    </Directory>
</VirtualHost>

我在本地机器上安装了php7和php5。但是当我像你建议的那样运行“ls -la /etc/apache2/conf-enabled | grep php”时,输出为空。我错过了什么吗?谢谢。 - abc
预期结果是空输出。可以在此处找到可用配置和模块列表:“ls -l /etc/apache2/conf-available/”和“ls -l /etc/apache2/mods-available/”。 - Jun Hsieh

3

对于Debian 9 Stretch,它无法正常工作。我花了一些时间才搞清楚该怎么做,但最终我找到了一个看起来更加简单的解决方案:

sudo apt-get install php5.6-fpm

sudo apt-get install php7.0-fpm

sudo a2enconf php5.6-fpm

如果您安装了php5.6和php5.7,请确保将这两个版本禁用并重新启动apache。
sudo a2dismod php5.6 php7.0

sudo systemctl restart apache2

目前,您的所有网站都必须在php 5.6上运行。

对于需要php 7的网站,请在vhost中添加以下行:

ProxyPassMatch "^/(.*\.php(/.*)?)$" "unix:/var/run/php/php7.0-fpm.sock|fcgi://localhost/path/to/my/main/file"

它应该能解决问题 :)

2

我尝试实现Makubex的解决方案,它起作用了。只有一个问题是在新安装的LAMP中,fastcgi没有启用。我使用以下脚本重新安装了php,并在之后启用了fastcgi。

sudo apt-get install libapache2-mod-fastcgi php5.6-fpm php5.6 php5.6-dev php5.6-mcrypt php5.6-mbstring php5.6-mysql php5.6-zip php5.6-gd php5.6-xml php7.1-fpm libapache2-mod-fastcgi php7.1-fpm php7.1 php7.1-dev php7.1-mbstring php7.1-mysql php7.1-zip php7.1-gd php7.1-xml php7.1-curl php7.1-intl php7.1-json php7.1-mcrypt

然后:

a2enmod actions
a2enmod fastcgi

在此之后,该解决方案完美运行。 我从使用php-fpm和xdebug在Ubuntu 16.04上运行多个PHP版本的同一服务器中获取了上述两个信息。

2

有很多答案像这样是不准确的,因为有两个版本的PHP同时存在:问题说:“我在本地服务器上有两个项目,一个项目正在运行PHP5.6,另一个项目正在运行PHP7.0”。使用 update-alternatives 会有到处都是符号链接 (ln -fs),例如 /run/php/php8.2-fpm.sock -> /run/php/php-fpm.sock 或者 /run/php/php5.6-fpm.sock -> /run/php/php-fpm.sock - phili_b
Õ£¿/lib/systemd/system/php5.6-fpm.serviceÕÆî/lib/systemd/system/php8.2-fpm.serviceõ©¡õ¢┐þö¿ExecStartPost=....install /run/php/php-fpm.sock´╝îÕì│ÕÉîµùµîçÕÉæþø©ÕÉîþÜäÞÀ»Õ¥äÒÇéõ©ñõ©¬þëêµ£¼þÜäphpõ║îÞ┐øÕêµûçõ╗Âõ╣ƒµÿ»Õªéµ¡ñÒÇé - phili_b

1

你可以使用.htaccess文件来实现这一点。

首先,您需要使用以下命令安装所需的FPM:

sudo apt install php7.2-fpm

然后运行以下命令

sudo a2enmod actions alias proxy_fcgi fcgid

然后重新启动您的服务器。
sudo systemctl restart apache

然后在.htaccess文件中进行以下更改

 <FilesMatch \.php$>
   # Apache 2.4.10+ can proxy to unix socket
      SetHandler "proxy:unix:/var/run/php/php7.2-fpm.sock|fcgi://localhost/"
 </FilesMatch>

这是一个在启用PHP 5.6的情况下运行PHP 7.2的示例。

谢谢!我从curl得到了一个错误:"[ErrorException] Use of undefined constant CURLOPT_HTTPGET - assumed 'CURLOPT_HTTPGET' (this will throw an Error in a future version of PHP) "。所以我运行了sudo apt-get install php7.2-curl来修复它,看起来它已经解决了。 - Paul Preibisch

0

由于所有的Linux软件包都会使这个过程变得更加困难,因此这变得更加困难了。简单的手动、系统独立的方法:

从源代码构建您的2个PHP版本。您将在模块目录中拥有libphp7.so和libphp5.so。只需为每个运行一个单独的httpd.conf文件即可。我已经使用5和7运行了多年:

httpd-php7.conf
httpd-php5.conf

那么,只需在php5配置中放置无法运行7的虚拟主机,然后手动启动它们或创建rc.d文件或任何您的系统用于启动的文件。


0

在尝试按照您的指示操作后,我发现了一种可能更简单的方法来实现相同的结果。

通过添加以下行:

ProxyPassMatch "^/php70project/.*\.php(/.*)?$" "fcgi://localhost:9070/var/www/" enablereuse=on

在Apache虚拟主机配置中,您可以更改位于vhost根目录/var/www下的php70project目录中的PHP版本为运行速度更快的7版本FastCGI。
以下方法适用于使用Unix套接字。
ProxyPassMatch "^/php70project/.*\.php(/.*)?$" "unix:/var/run/php70fpm.sock|fcgi://localhost/var/www"

代码没有按预期工作。 不幸的是,我找不到正确的代码来使其工作,但由于该页面https://httpd.apache.org/docs/2.4/mod/mod_proxy_fcgi.html上没有关于在子文件夹中使用Unix套接字的示例,这可能是不可能的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接