上周,我做了一些系统更新,然后决定编译最新的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:添加了断点,因此完整的帖子不会显示在列表中。