WordPressのエクスポートでTypeErrorになる

PHP 8.3にバージョンアップしたところ、WordPressのコンテンツデータのエクスポートがエラーになった。

エラー内容

エクスポートを実行すると以下のようなFatal errorが発生する。

PHP Fatal error:  Uncaught TypeError: wp_is_valid_utf8(): Argument #1 ($bytes) must be of type string, null given called in wp-admin/includes/export.php on line 246

原因

PHP 8.3で型チェックが厳格化されたため、wxr_cdata()関数にNULLが渡された場合にFatal errorとなる。PHP 8.2まではwarningで済んでいたが、8.3で致命的エラーになった。

対処方法

wp-admin/includes/export.phpwxr_cdata()関数を修正し、NULLが渡された場合に空文字列として扱うようにする。

245行目付近のwxr_cdata()関数の先頭に以下のチェックを追加する。

function wxr_cdata( $str ) {
    if ( $str === null ) {
        $str = '';
    }

Docker ComposeでWordpressを利用している場合

Docker Composeで運用している場合は、以下のコマンドで対象のコンテナ(ここではwordpressというコンテナ名)に対して修正を適用できる。

docker compose exec wordpress sh -c '
sed -i "
/function wxr_cdata( \$str ) {/a\\
\\
    // PHP 8.3 compatibility fix\\
    if ( ! is_string( \$str ) ) {\\
        \$str = \"\";\\
    }\\
" /var/www/html/wp-admin/includes/export.php
'

注意点

WordPressのアップデート時にこの修正は上書きされるため、アップデート後に再発するようであれば、再度適用が必要になる。WordPress本体で修正されるまでの暫定対応として利用する。

Amazon Linux 2023にDocker Composeを入れる

まずは、dnfでdockerを入れます。

$ sudo dnf -y install docker

インストールしたら、dockerのサービスを有効にします。

$ sudo systemctl enable --now docker

次に、ec2-userでdockerコマンドを利用できるようにします。

$ sudo usermod -aG docker ec2-user

一度、ログアウトして、ログインし直します。

docker composeのリリースサイトを確認して、アーキテクチャを確認して、インストールします。今回は、x86_64版をインストールします。

$ sudo mkdir -p /usr/local/lib/docker/cli-plugins
$ sudo curl -SL https://github.com/docker/compose/releases/download/v2.21.0/docker-compose-linux-x86_64 -o /usr/local/lib/docker/cli-plugins/docker-compose
$ sudo chmod +x /usr/local/lib/docker/cli-plugins/docker-compose

あとは、docker composeが利用できるか確認します。

$ docker compose version

gpg: keyserver receive failed: Cannot assign requested address

docker buildしたら、Dockerfile内でのgpgコマンドが以下のようなエラーになる場合がある。

+ gpg --batch --keyserver ha.pool.sks-keyservers.net --recv-keys E3FF2839C048B25C084DEBE9B26995E310250568
gpg: keybox '/tmp/tmp.SUXH22yiuV/pubring.kbx' created
gpg: keyserver receive failed: Cannot assign requested address

どうやら、Docker内でha.pool.sks-keyservers.netにIPv6で接続しにいこうとして、失敗しているらしい。この場合は、Dockerfile内のha.pool.sks-keyservers.netをipv4.pool.sks-keyservers.netに置き換えて、IPv4で接続するようにしたら解決した。