markdown

はじめに (対象読者・この記事でわかること)

この記事は、CentOS/AlmaLinux/Rocky Linux 8系・9系でPHP 8.2をRemiリポジトリからインストールし、OPcacheを有効にしようとしているが「Unable to load dynamic library 'opcache.so'」というエラーに遭遇した方を対象としています。

この記事を読むことで、以下のことがわかります。 - なぜ「opcache.so: cannot open shared object file」が発生するのか - php-intlとphp-opcacheを同時に入れると起きる依存関係の問題 - エラーを回避するための正しい手順とyum/dnfの使い方 - 既存環境を壊さずにOPcacheを有効化するコマンド

前提知識

この記事を読み進める上で、以下の知識があるとスムーズです。 - Linux(CentOS/Alma/Rocky)の基本的なコマンド操作 - PHP-FPMをyum/dnfでインストールした経験 - php.iniの有効化/無効化の概念

RemiリポジトリでPHP8.2を入れた直後、OPcacheだけがロードできないワケ

Remiリポジトリは、RHEL系ディストリで最新のPHPを使いたいときに欠かせない存在です。2025年6月現在、Remiは8.2系をメンテナンスしており、多くのVPS/クラウドイメージでデフォルト有効になっています。

ところが、以下のように「最低限必要そう」なモジュールを一括インストールしようとすると、OPcacheだけがロードできないという現象が起きます。

Bash
# よくある一括インストール例 sudo dnf install -y php82-php-cli php82-php-fpm php82-php-mysqlnd php82-php-intl php82-php-opcache

これを実行してphp-fpmを再起動すると、php -m | grep OPcacheが空振りし、php -vを実行すると

PHP Warning:  PHP Startup: Unable to load dynamic library 'opcache.so' (tried: /usr/lib64/php/modules/opcache.so)

というエラーが表示されます。なぜ他の拡張は問題なくてOPcacheだけが「ファイルが見つからない」のか?答えは依存解決の順序にあります。

具体的な手順と、なぜ「opcache.soが見つからない」のか

ステップ1:事象の再現とエラーログの確認

まず、以下のコマンドで事象を再現してみます。

Bash
# 環境確認 cat /etc/redhat-release # AlmaLinux release 9.4 (Veronica) dnf repolist | grep remi # remi-safe, remi-php82が有効 # PHP 8.2 関連パッケージの一括インストール sudo dnf install -y php82-php-cli php82-php-fpm php82-php-common php82-php-intl php82-php-opcache # エラーが出るか確認 php82 -v

すると以下のような警告が出ます。

PHP Warning:  PHP Startup: Unable to load dynamic library 'opcache.so' (tried: /usr/lib64/php/modules/opcache.so

この時点で/usr/lib64/php/modules/opcache.soを確認すると、ファイル自体は存在しています。ではなぜ見つからないのか?エラーをよく見ると

libicuio.so.71: cannot open shared object file: No such file or directory

と書かれています。これはintl拡張が必要とするlibicuのバージョンが、opcache.soのビルドに使われたものと一致しないため、opcache.soがロードできないという副作用が起きているのです。

ステップ2:正しい順序でインストールし直す

解決策は簡単:依存関係を満たしてからOPcacheを入れ直します。

Bash
# 1. 一度OPcacheをアンインストール sudo dnf remove php82-php-opcache # 2. intlが要求するlibicuをインストール sudo dnf install libicu71 # 3. OPcacheを再インストール sudo dnf install php82-php-opcache # 4. 有効化(Remiではデフォルトで有効) sudo phpenmod opcache # Ubuntu系はphp82-php-opcacheで自動有効 # 5. 確認 php82 -m | grep -i opcache # Zend OPcache

これで無事にOPcacheがロードされるはずです。

ハマった点:「opcache.soが存在するのに見つからない」は初歩的に見えるが検索しても日本語記事が少ない

このエラー、英語圏では「PHP OPcache libicu version mismatch」などで検索するとIssueがいくつか出てきますが、日本語では「opcache.soが見つからない」で検索しても、パスが通っていない、typo、セルフコンパイル時のMakefileミスといった話題ばかりが出てきます。

さらに痛いのは、dnf remove php82-php-opcache && dnf install php82-php-opcacheで直るケースが多いため、「たまたま直った」で終わって根本原因を特定できていない、という状況が散見されることです。

解決策:インストール順序を守る+libicuを明示的に合わせる

  1. Remiリポジトリを使う場合、先にintl拡張を入れてlibicuを固定してからOPcacheを入れる
  2. 逆にOPcacheだけ先に入れてしまった場合は、一旦アンインストールしてからdnf install libicu<version>を実行してから再インストール
  3. 将来的に「libicu.so.XY not found」が出たら、まず「opcache.soより先に依存を解決しているか」をチェック

これをCIや構築スクリプトに組み込むと、次回以降同じハマりを回避できます。

Bash
# サンプル:インストールスクリプトの一部 PKGS="php82-php-cli php82-php-fpm php82-php-common php82-php-intl" sudo dnf install -y $PKGS # libicuバージョンを合わせてからOPcache sudo dnf install -y libicu71 sudo dnf install -y php82-php-opcache

まとめ

本記事では、Remiリポジトリ経由でPHP 8.2にOPcacheを入れる際に「Unable to load dynamic library 'opcache.so'」が出る原因と、それを回避する手順を解説しました。

  • 原因:intl拡張が要求するlibicuのバージョンと、OPcacheがビルドされたlibicuのバージョンが食い違う
  • 回避策:OPcacheを一度アンインストールし、libicuを明示的にインストールしてからOPcacheを再インストール
  • 今後:インストール順序を守るだけで、同じエラーを起こさない

この記事を通して、依存関係の解決順序を意識することで、パッケージマネージャーで「存在するのに見つからない」という初歩的に見えるが意外とハマるエラーを回避できることがわかりました。

次回は、同じ現象がphp-gdやphp-imagickでも起きうるケースと、Dockerfileに落とし込む際のTipsを紹介します。

参考資料