Wordpress

將 Debian Buster 升級到 Bullseye 後,Wordpress 站點不再更新

  • March 8, 2022

今天我將我的網路伺服器從 Debian Buster 升級到 Bullseye,這實際上是一個非常簡單的升級。在我嘗試訪問伺服器上的幾個 WordPress 站點之前,一切似乎都正常。起初我收到一些關於缺少 MySQL 模組的錯誤。我從 PHPMyAdmin 收到的錯誤消息給了我一個更好的線索:它說它缺少 mysqli 模組。

所以我安裝了它, apt install php7.4-mysqli 這實際上讓我的 WordPress 網站再次執行。

然而,現在唯一的問題是我無法更新 Wordpress。每次我嘗試更新 WordPress 時,都會出現錯誤:

WordPress 更新錯誤

我懷疑我需要安裝suphp。但在我這樣做之前,任何人都可以確認情況確實如此嗎?還是在從 Buster 升級到 Bullseye 後我需要做其他事情?

編輯: 我花了很長時間才弄清楚到底發生了什麼。現在我知道了,我不知道如何解決這個問題。

WP給出的錯誤消息實際上是不正確的。事實證明,它能夠在正確的文件夾中很好地解壓縮更新。但是當它檢查文件是否真正解包時,它會出錯。問題在於update-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 方法安裝更新。因此,當我告訴它更新時,它首先會確定應該將 zipfile 下載到的文件夾。此文件夾儲存在**$working_dir**中,並從那時起用於其餘的更新過程。伺服器上的真實路徑是,/domains/domainname.com/htdocs/wp-content/upgrade/但是由於 FTP 使用者是 chroot 的,WP 會查找並儲存/htdocs/wp-content/upgrade/。更新文件下載到此文件夾,然後解壓縮。

接下來它會進行上述檢查。這失敗了,因為它試圖在/htdocs/wp-content/upgrade/真實位置為/domains/domainname.com/htdocs/wp-content/upgrade/.

我理解為什麼它可以很好地下載軟體包(因為 FTP 使用者是 chroot 的)。但我不明白為什麼它在解壓之後沒有失敗,但是在檢查文件是否存在時它確實失敗了……

我檢查了所有 php 設置,並沒有發現與 Debian 升級之前的設置有什麼不同……

我花了一段時間才弄清楚到底發生了什麼,但這實際上是 WordPress 的問題。Bullseye 在安裝了 Buster v1.0.47 的地方安裝了 PureFTPd 1.0.49 版。根據此處PureFTPd 的變更日誌,萬用字元已從 v1.0.48 中的 NLST 命令中刪除(這是有道理的,因為根據 RFC 實際上是不允許的)。

WordPress 開發人員已經意識到了這個問題並修補了 exists() 函式。該更新檔可在此處獲得;如果您使用 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 預設會有這個新功能。

引用自:https://serverfault.com/questions/1094992