上周,我做了一些系统更新,然后决定编译最新的PHP版本。多年来,我一直使用phpbrew来管理多个PHP版本,安装新版本是相当常规的事情。
除了这一次,它不是。由于我安装的更新,我首先在编译GD扩展时遇到错误,然后在使用ext-intl时遇到错误:
-
如果您想在ext-gd中支持Freetype,您需要安装软件包libfreetype-dev。在Ubuntu上,这现在安装了libfreetype6-dev,它不再包含PHP的
configure脚本用来确定它支持哪些功能的freetype-config二进制文件。 -
同样,ext-intl依赖于软件包libicu-dev。Ubuntu的软件包现在不包含PHP用来确定功能支持的
icu-config二进制文件。
我搜索了很长时间才找到可以解决这些问题的软件包。我本可以找到源代码并编译它并链接到它,但这意味着要在我的PHP安装中保持最新。
我什至查看了ondrej/phpPPA,因为该存储库已经有多个PHP版本,包括源包。
然后我想:为什么不尝试使用它们而不是phpbrew?
这篇文章的其余部分是我如何完成这项工作的。
我使用Ubuntu作为我的操作系统。我在此处提供的说明适用于任何基于Debian的系统,但您的情况可能会有所不同。如果您使用基于RPM的系统,
yum将是您的朋友,但我不知道如何在该系统中添加存储库,也不知道update-alternatives是否可用。因此,这些说明可能对您有帮助,也可能没有帮助。没关系。我写它们主要是为了帮助未来的我。
我使用Ubuntu作为我的操作系统。我在此处提供的说明适用于任何基于Debian的系统,但您的情况可能会有所不同。如果您使用基于RPM的系统,
yum将是您的朋友,但我不知道如何在该系统中添加存储库,也不知道update-alternatives是否可用。因此,这些说明可能对您有帮助,也可能没有帮助。没关系。我写它们主要是为了帮助未来的我。
注册PPA
首先,我必须将PPA添加到系统中:
$ sudo add-apt-repository ppa:ondrej/php
然后是通常的:
$ sudo apt update
安装方法
我首先确定了我通常安装的扩展,将它们与PPA中的包相匹配,并制作了一个列表。我知道我会在我想要的所有PHP版本上安装相同的扩展,所以我想我可以稍微编写脚本。
从那里,我从CLI执行了以下命令:
$ for VERSION in 5.6 7.0 7.1 7.2 7.3;do
for> for EXTENSION in {listed all extensions here};do
for for> sudo apt install php${VERSION}-${EXTENSION}
for for> done
for> done
这抓住并安装了我需要的每个PHP以及我想要的所有扩展。
版本切换
要在版本之间切换,您有两个选择:
-
使用版本特定的二进制文件:
/usr/bin/php5.6、/usr/bin/php7.0等。 -
通过
update-alternatives设置默认值:$ sudo update-alternatives --set php /usr/bin/php5.6
如果如果您不确定自己安装了什么,请使用:
$ sudo update-alternatives --config php
这将为您提供一个列表,并且可以选择要使用的那个。
无根替代品
如果您不想成为root用户来切换默认版本怎么办?幸运的是,update-alternatives允许指定备用配置和管理目录。
在您的shell配置中定义以下别名:
alias update-my-alternatives='update-alternatives \ --altdir ~/.local/etc/alternatives \ --admindir ~/.local/var/lib/alternatives'
此外,确保将$HOME/.local/bin添加到$PATH中;由于定义$PATH会根据您使用的shell而有所不同,我会把它留给您来完成。
如果你打开一个新的shell,别名现在就可用了;或者,获取您定义它的文件以使其立即生效。
完成后,您可以根据已安装的PHP版本运行以下命令:
$ for VERSION in 5.6 7.0 7.1 7.2 7.3;do
for> update-my-alternatives --install $HOME/.local/bin/php php /usr/bin/php${VERSION} ${VERSION//./0}
for> done
这将为您自己的用户创建本地的备选条目,并按版本对它们进行优先级排序;因此,默认的自动选择版本将是最近安装的。
您可以通过运行update-my-alternatives--configphp来验证这一点:
There are 5 choices for the alternative php (providing $HOME/.local/bin/php). Selection Path Priority Status ------------------------------------------------------------ * 0 /usr/bin/php7.3 703 auto mode 1 /usr/bin/php5.6 506 manual mode 2 /usr/bin/php7.0 700 manual mode 3 /usr/bin/php7.1 701 manual mode 4 /usr/bin/php7.2 702 manual mode 5 /usr/bin/php7.3 703 manual mode Press <enter> to keep the current choice[*], or type selection number:
使用别名在版本之间切换:
-
切换到特定的已知版本:
$ update-my-alternatives --set php /usr/bin/php{VERSION} -
切换回默认版本(优先级最高的版本):
$ update-my-alternatives --auto php
-
列出可用版本:
$ update-my-alternatives --list php
-
当您不确定可用的版本时,交互式地选择一个版本:
$ update-my-alternatives --config php
- https://serverfault.com/a/811377
- https://williamdemeo.github.io/linux/update-alternatives.html
- https://serverfault.com/a/811377
- https://williamdemeo.github.io/linux/update-alternatives.html
/ul>
以上内容拼凑自:
以上内容拼凑自:
PECL
当您安装了多个PHP版本时,编译和安装您自己的扩展会变得有点痛苦,主要是因为只安装了一个PECL二进制文件。
首先,您需要安装一些包,包括包含PEAR的包(PECL使用PEAR安装程序),以及您使用的每个PHP版本的开发包(因为它们包含编译扩展所需的工具,包括phpize和php-config):
$ sudo apt install php-pear
$ for VERSION in 5.6 7.0 7.1 7.2 7.3;do
for> sudo apt install php${VERSION}-dev
for> done
编译扩展
从那里,您需要:
- 确保选择了正确的
phpize和php-config。 - 安装扩展。
- 告诉PECL在其自己的注册表中注销该扩展。
通常,您可以通过执行以下操作来完成第一点:
$ sudo update-alternatives --set php /usr/bin/php7.3 $ sudo update-alternatives --set php-config /usr/bin/php-config7.3 $ sudo update-alternatives --set phpize /usr/bin/phpize7.3
请注意,以上内容不使用上一节中详述的
update-my-alternatives别名。这是因为扩展必须安装在系统级别。也就是说,上面的内容不是必需的,正如我在下面详述的那样。
请注意,以上内容不使用上一节中详述的
update-my-alternatives别名。这是因为扩展必须安装在系统级别。也就是说,上面的内容不是必需的,正如我在下面详述的那样。
但是,PECL现在有一个非常好的配置标志,php_suffix,它允许指定一个字符串附加到每个php、phpize和php-configbinary名称。因此,例如,如果我指定pecl-dphp_suffix=7.3,则字符串7.3将附加到那些字符串,以便它们成为php7.3、phpize7.3和php-config7.3。这可确保在构建过程中调用正确的脚本,并将扩展安装到正确的位置。
至于该编号列表中的最后一点,它是能够在多个PHP版本中安装扩展的关键;否则,每次后续尝试,即使使用不同的PHP版本,都会导致PECL指示它已安装。-r开关告诉PECL从它自己的注册表中删除包,但不删除任何构建工件。
作为一个完整的例子:
$ sudo pecl -d install php_suffix=7.3 swoole && sudo pecl uninstall -r swoole
注册扩展
从那里,您仍然需要注册,并可选择配置扩展。为此,将以扩展名命名的文件放入/etc/php/${PHP_VERSION}/mods-available/${EXTENSION}.ini,内容如下:
; configuration for php ${EXTENSION} module
; priority=20
extension=${EXTENSION}.so
现在已经到位,启用它:
$ sudo phpenmod -v ${PHP_VERSION} -s cli ${EXTENSION}
(要禁用它,请改用phpdismod。)
想法
在考虑phpbrew时:
-
像
phpbrew一样,您可以通过简单地参考其路径来临时选择一个替代的PHP二进制文件。对于phpbrew,这类似于~/.phpbrew/php/php-{PHP_VERSION}/bin/php。使用ondrejPPA,它变成了/usr/bin/php{PHP_MINOR_VERSION}。(例如~/.phpbrew/php/php-7.2.36/bin/php将变成/usr/bin/php7.2。)/li>
-
没有等同于
phpbrew使用。该功能只会在当前终端会话期间更改符号链接。打开一个新的终端会话将恢复到之前的选择。使用update-alternatives,要么全有要么全无。我主要使用phpbrewuse来确保我的默认PHP没有改变,以防我忘记再次调用它。 -
update-alternatives的使用更像是phpbrewswitch,因为它会影响当前和所有以后的终端会话。一旦切换,该选择将一直使用,直到您再次切换它。这意味着我必须记住切换到我的默认版本。但是,在我的shellprofile中添加一行以调用update-my-alternatives--autophp相对容易。
基本上,如果您可以直接使用二进制文件,但不想将其用作默认值,请通过绝对路径引用它。如果您使用的命令将使用当前环境的PHP,请先使用update-my-alternatives切换PHP版本。
我看到的另一个问题是,如果我想针对特定PHP版本进行测试,我仍然需要自己编译它—这让我回到了最初的问题第一名。当我到达它时,我会穿过那座桥。在那之前,我有一个可行的解决方案——最终我可以在以后需要再次记住时参考一个文档,而不是从多个来源拼凑它!
更新
- 2020-04-16:修复了将PPA添加到系统的命令中对PPA的引用。
- 2019-05-01:添加了断点,因此完整的帖子不会显示在列表中。
