今天我将我的网络服务器从 Debian Buster 升级到了 Bullseye,这实际上是一次相当简单的升级。一切似乎都正常,直到我尝试访问服务器上的几个 WordPress 网站。起初我收到一些有关缺少 MySQL 模块的错误。我从 PHPMyAdmin 收到的错误消息给了我一个更好的线索:它说它缺少 mysqli 模块。
因此我安装了它 apt install php7.4-mysqli
,事实上它让我的 WordPress 网站再次运行起来。
然而,现在唯一的问题是我无法更新 Wordpress。每次我尝试更新 WordPress 时,都会收到错误:
我怀疑我需要安装 suphp。但在安装之前,有人能确认确实如此吗?或者从 Buster 升级到 Bullseye 后我需要做其他事情吗?
编辑: 我花了很长时间才弄清楚到底发生了什么。现在我知道了,但我不知道如何解决这个问题。
WP 给出的错误消息实际上是不正确的。事实证明,它是能够在正确的文件夹中顺利解压更新。但当它检查文件是否已解压时,就会出错。问题出在更新-core.php:
foreach ( $roots as $root ) {
if ( $wp_filesystem->exists( $from . $root . 'readme.html' )
&& $wp_filesystem->exists( $from . $root . 'wp-includes/version.php' )
) {
$distro = $root;
break;
}
}
if ( ! $distro ) {
$wp_filesystem->delete( $from, true );
return new WP_Error( 'insane_distro', __( 'The update could not be unpacked.' ) );
}
它在这里所做的只是检查刚刚解压 zip 文件的文件夹中是否存在两个文件。这失败了。原因如下:
我使用 FTP 方法安装更新。因此,当我告诉它更新时,它首先找出应该将 zip 文件下载到的文件夹。此文件夹存储在$工作目录并从那一刻起用于其余的更新过程。服务器上的真实路径是,/domains/domainname.com/htdocs/wp-content/upgrade/
但由于 FTP 用户已 chroot,/htdocs/wp-content/upgrade/
因此 WP 会查找并存储。更新文件将下载到此文件夹,然后解压。
接下来,它会进行上述检查。但检查失败了,因为它试图在 中查找文件,/htdocs/wp-content/upgrade/
而真实位置是/domains/domainname.com/htdocs/wp-content/upgrade/
。
我理解为什么它可以顺利下载软件包(因为 FTP 用户是 chrooted)。但我不明白为什么它之后解压不会失败,但在检查文件是否存在时却会失败……
我检查了所有 php 设置,没有发现与 Debian 升级之前的设置有任何不同……
答案1
我花了一段时间才弄清楚到底发生了什么,但实际上是 WordPress 的问题。Bullseye 安装了 PureFTPd 1.0.49 版本,而 Buster 安装了 v1.0.47。根据 PureFTPd 的更新日志这里,在 v1.0.48 中,通配符已从 NLST 命令中删除(这是有道理的,因为根据 RFC,它实际上是不允许的)。
WordPress 开发人员已意识到此问题并已修补了 exist() 函数。补丁已发布这里;如果您使用 PureFTPd 版本 1.0.48 或更高版本并且无法通过 FTP 升级,则应用它是升级 WordPress 的两种方法之一。
您也可以自己替换函数/wp-admin/includes/class-wp-filesystem-ftpext.php(或者/wp-admin/includes/class-wp-filesystem-ftpsockets.php如果您使用 FTPSockets),请使用以下命令(这实际上是我自己对该函数的实现):
public function exists( $file ) {
$retval = false;
$list = ftp_nlist( $this->link, $file );
if( ! empty( $list ) ) {
// if ftp_nlist returns *something*, the file or directory exists, on any FTP server
$retval = true;
} else {
// if ftp_nlist returns nothing, either the file/dir doesn't exist or it's a file and
// the FTP server's NLST command doesn't support globbing (i.e. Pure-FTPD > v1.0.47)
// Check if it'a file
if( ftp_size( $this->link, $file ) >= 0 ) {
$retval = true;
}
}
return $retval;
}
WordPress 6.0 将默认拥有该新功能。