---
title: "OPcacheとは？読み方とPHP 8.5の変更点・設定・確認方法"
url: "https://www.issoh.co.jp/tech/details/7965/"
published: 2025-07-31
updated: 2026-10-15
categories: ["PHP"]
publisher: "株式会社一創"
---

# OPcacheとは？読み方とPHP 8.5の変更点・設定・確認方法

OPcacheは、PHPがリクエストのたびに繰り返しているコンパイルを省く仕組みです。実務で手が止まるのは、PHP 8.5に上げたら `apt install php8.5-opcache` が通らない、デプロイしたのに古いコードが返る、WordPressのサイトヘルスに「オペコードキャッシュが有効化されていません」と出る、といった場面です。この記事はそれらを起点に、PHP 8.5時点の一次情報と、PHP 8.5.8で実際に動かした結果をもとにOPcacheを整理します。

## まとめ

- **読み方**：公式の読み仮名はない。opcode cache の略で、「オーピーキャッシュ」「オプキャッシュ」と読まれ、訳語は「オペコードキャッシュ」。
- **PHP 8.5の変更**：OPcacheは**常にPHPバイナリへ組み込まれ、常にロードされる**。`zend_extension=opcache.so` を残すと警告が出る。`php8.5-opcache` パッケージは存在せず、入れる必要もない。
- **反映の遅れ**：既定（`validate_timestamps=1`・`revalidate_freq=2`）では、ファイルを書き換えても最大2秒は古いコードが返る。`validate_timestamps=0` なら、リセットするまで永久に古いまま。
- **既定値の実効値**：`max_accelerated_files` の既定10000は、内部でキー数の上限16229（素数）に切り上げて使われる。
- **JITは既定で無効**（PHP 8.4以降 `opcache.jit=disable`）。1,500ファイルを読み込む検証用ページでは、有効にしても速くならなかった。
- **WordPressの警告**：判定は `opcache_get_status()` の結果だけ。この関数が封じられたサーバーでは、OPcacheが動いていても警告が出る。

## OPcacheの読み方と、省略している処理

### 読み仮名の規定はなく、実勢は「オーピーキャッシュ」「オプキャッシュ」

OPcacheは正式には「Zend OPcache」という名前の拡張で、PHP 5.5から本体に同梱されています。公式ドキュメントに読み仮名の規定はなく、日本語では「オーピーキャッシュ」「オプキャッシュ」の両方が使われています。名称は「opcode cache」の短縮で、WordPressの日本語UIは「オペコードキャッシュ」と訳しています。「Zend OPcache」「オペコードキャッシュ」「OPcache」はすべて同じ機能を指します。

### キャッシュしているのはソースではなくバイトコード

PHPはリクエストのたびに、ソースを読み込み、字句解析・構文解析を経てオペコード（バイトコード）へコンパイルし、Zend VMで実行します。ソースが変わっていなくても、この変換は毎回走ります。OPcacheは変換結果を**共有メモリ**に置き、2回目以降は読み込みとコンパイルを飛ばします。

効果の大きさは、読み込むコードの量と、処理全体に占める読み込み・コンパイルの割合で決まります。1ファイル1クラス（メソッド10個）を1,500ファイル読み込んでインスタンス化するページを用意し、macOS（Intel）上のPHP 8.5.8のビルトインサーバーで、1回目のリクエストを捨てたあと50回計測しました。スクリプト内で `hrtime()` により測った読み込みと実行の時間の中央値は、OPcache無効で約280ms、有効で約3msでした。DB待ちが長いアプリでは、全体のレスポンスタイムに占める短縮の割合はこれより小さくなります。

共有メモリはPHP-FPMの全ワーカーが参照するため、あるワーカーがコンパイルした結果を別のワーカーが使えます。キャッシュされるのはオペコードとインターン文字列（クラス名・関数名・リテラルを1つの実体にまとめたもの）だけで、変数の値やDBの結果は対象外です。ページキャッシュやオブジェクトキャッシュとは層が違います。

## PHP 8.5でのOPcacheの変更点

### OPcache拡張の本体統合と常時ロード

PHP 8.5（2025年11月20日リリース）の[UPGRADING](https://github.com/php/php-src/blob/PHP-8.5/UPGRADING)には「The Opcache extension is now always built into the PHP binary and is always loaded.」とあります。もとになった[RFC「Make OPcache a non-optional part of PHP」](https://wiki.php.net/rfc/make%5Fopcache%5Frequired)は賛成30・反対0で可決されました。`--enable-opcache` と `--disable-opcache` のconfigureフラグは削除され、ビルドは `opcache.so` も `php_opcache.dll` も生成しません。`opcache.enable` と `opcache.enable_cli` は従来どおり効くので、無効にしたい場合はこれらを `0` にします。

影響が出るのは拡張の読み込み行です。8.4の `php.ini-production` には `;zend_extension=opcache` というコメント行があり、これを外して有効化する手順が一般的でした。8.5の `php.ini-production` からはこの行が消えています。8.4から持ち越したINIにこの行が残っていると、PHP 8.5.8では次の警告が出ます。警告のあとスクリプトは通常どおり動き、OPcacheも有効のままです。

```
$ php -d zend_extension=opcache.so -r 'echo "ok\n";'
Warning: Failed loading Zend extension 'opcache.so' (tried: /usr/local/Cellar/php/8.5.8/lib/php/20250925/opcache.so ...) in Unknown on line 0
ok
```

実害はないものの、起動のたびにログが汚れます。`conf.d` 配下も含めて、OPcacheを読み込む `zend_extension=opcache`（または `opcache.so`・`php_opcache.dll`）の行だけを削除してください。Xdebugなど他のZend拡張の `zend_extension` 行は残します。

### 「php8.5-opcache が見つからない」「php-opcache has no installation candidate」の正体

Debian・Ubuntu系で使われるOndřej Surý氏のリポジトリでは、8.4まで `php8.4-opcache` が独立したパッケージでした。2026年10月15日に [packages.sury.org](https://packages.sury.org/php/pool/main/p/php8.5/) のbookworm向けパッケージ一覧を確認したところ、`php8.4-opcache` はあり、`php8.5-opcache` はありませんでした。依存関係も変わっており、`php8.4-cli` は `php8.4-opcache` に依存していますが、`php8.5-cli`（8.5.11）の依存には現れません。本体に組み込まれたので、入れるべきパッケージがないのが正常です。

```
# 8.4までの手癖のまま実行すると失敗する
$ sudo apt install php8.5-opcache
E: Unable to locate package php8.5-opcache

# 8.5はベースパッケージだけでOPcacheが使える
$ sudo apt install php8.5-fpm
$ php -m | grep -i opcache
Zend OPcache
Zend OPcache
```

`php -m` で「Zend OPcache」が2行出るのは、\[PHP Modules\] と \[Zend Modules\] の両方の欄に載るためで、異常ではありません。

`apt install php-opcache` で「has no installation candidate」と出るのは別の理由です。`php-opcache` は実体のある独立パッケージではなく、`php8.4-opcache` などの版ごとのパッケージが提供する仮想パッケージです。apt は提供元が複数ある仮想パッケージを直接指定されると、どれか1つを選ぶよう求めてこのエラーで止まります。8.4以前なら版を付けた名前で入れ、8.5なら何も入れません。

RHEL系でRemi氏のSCL版を使っている場合も同じです。[php85-php-opcache](https://rpms.remirepo.net/enterprise/9/safe/x86%5F64/repoview/php85-php-opcache.html) は8.5.0alpha2（2025年7月15日）を最後に更新が止まっており、`php85-php-common` は8.5.11まで出ています。旧版の導入済みパッケージ一覧から新版の名前を機械的に作る移行スクリプトは、`-opcache` の1行が残るだけで全体が止まるので、除外してください。

### Docker公式イメージで docker-php-ext-install opcache が失敗する理由

公式PHPイメージでは、8.4以前は `docker-php-ext-install opcache` でOPcacheを組み込むのが定番でした。8.5ではこの行でビルドが落ちます。[docker-library/php #1605](https://github.com/docker-library/php/issues/1605) では `docker-php-ext-enable opcache` が `error: 'opcache' does not exist` で失敗すると報告され、保守者は「公式イメージでは既にOPcacheが有効なので、手動の有効化を削除すればよい」と回答して2025年8月13日にクローズしました。8.5でこれらのコマンドをエラーにしないよう求める [#1631](https://github.com/docker-library/php/issues/1631) は、2026年10月15日時点でオープンのままです。

```
FROM php:8.5-fpm
# RUN docker-php-ext-install opcache  ← 8.5では削除する（残すとビルド失敗）
COPY ./docker/php/opcache.ini /usr/local/etc/php/conf.d/opcache.ini
```

複数の版を同じDockerfileでビルドしている場合、`docker-php-ext-install opcache || true` で失敗を握りつぶす回避策も見かけます。ただしこれだと、8.4以前のビルドで本当に失敗したときも気づけません。ビルド引数で版を分岐させ、8.5以降はこの行を実行しない形にするほうが安全です。

### 8.5で追加・変更された設定と関数

- `opcache.file_cache_read_only` を新設。読み取り専用のファイルシステムにファイルキャッシュを置ける（手順は後述）。
- `opcache.jit_hot_loop` の既定値が64から**61（素数）**に変更。ループ回数の倍数と重なってJITの発火が偏るのを防ぐため。
- `opcache_is_script_cached_in_file_cache()` を追加。スクリプトがファイルキャッシュに入っているかを判定できる。
- 共有メモリの構築後に `opcache.memory_consumption` を変えた場合、これまでは黙って無視されphpinfoに誤った値が出ていたが、失敗として報告されるようになった。

OPcache以外の非互換もアップグレード時に同時に当たります。PHP 8.5全体の変更点は[PHP 8.5の変更点と新機能まとめ](/tech/details/8179/)で確認してください。

## 有効化と動作確認の手順

### php.iniの最小構成

PHP 8.5では拡張のロード指定は不要です。有効・無効と、アプリの規模に合わせたサイズだけを書きます。

```
; 本番環境の最小構成（php.ini もしくは conf.d/10-opcache.ini）
opcache.enable=1
opcache.enable_cli=0
opcache.memory_consumption=256
opcache.interned_strings_buffer=16
opcache.max_accelerated_files=32531
opcache.validate_timestamps=1
opcache.revalidate_freq=2
```

書き換えたらPHP-FPMをリロードします（`sudo systemctl reload php8.5-fpm`）。`opcache.enable` は `ini_set()` で実行中に有効化できません。PHP 8.5.8で試すと「Zend OPcache can’t be temporarily enabled (it may be only disabled until the end of request)」という警告が出て、値は `0` のままでした。

### php -m と opcache\_get\_status() での有効確認

```
# 組み込まれているか
$ php -m | grep -i opcache

# 設定値（CLI用のINIを見ている点に注意）
$ php -i | grep opcache.enable
```

稼働中のPHP-FPMの状態は、Web経由で実行するスクリプトで確認します。

```
<?php
if (!function_exists('opcache_get_status')) {
    exit("opcache_get_status() が使えない（disable_functions の可能性）\n");
}
$s = opcache_get_status(false);
if ($s === false) {
    exit("OPcacheが無効、または opcache.restrict_api で制限されている\n");
}
var_dump($s['opcache_enabled']);                          // true なら有効
var_dump($s['memory_usage']['free_memory']);              // 空き共有メモリ
var_dump($s['opcache_statistics']['num_cached_scripts']); // キャッシュ済みファイル数
var_dump($s['opcache_statistics']['num_cached_keys']);    // 使用中のキー数
var_dump($s['opcache_statistics']['max_cached_keys']);    // キー数の上限（実効値）
var_dump($s['opcache_statistics']['oom_restarts']);       // メモリ不足による全消し回数
```

このスクリプトや `phpinfo()` はパスや設定値を外部に見せるので、IP制限か認証をかけた場所に置き、確認が終わったら削除してください。`php -i` が表示するのはCLI用のINIです。`opcache.enable_cli` の既定値は `0` なので、CLIで `opcache_get_status()` が `false` を返しても、Web側が無効とは限りません。PHP-FPMが読んでいる値は、上のスクリプトか `phpinfo()` をWeb経由で実行して確かめてください。

## 主要ディレクティブの既定値と、実際の挙動

既定値は[php.netの実行時設定](https://www.php.net/manual/ja/opcache.configuration.php)によるものです。挙動の欄は、PHP 8.5.8のビルトインサーバー（`php -S`）で確かめた結果です。

| ディレクティブ                           | 既定値     | 確かめた挙動              |
| --------------------------------- | ------- | ------------------- |
| opcache.enable                    | 1       | 実行中の有効化は不可          |
| opcache.enable\_cli               | 0       | CLIでは無効             |
| opcache.memory\_consumption       | 128（MB） | 文字列領域を含む総量          |
| opcache.interned\_strings\_buffer | 8（MB）   | 総量の内側から確保           |
| opcache.max\_accelerated\_files   | 10000   | 実効16229             |
| opcache.validate\_timestamps      | 1       | 0で変更を一切検知しない        |
| opcache.revalidate\_freq          | 2（秒）    | 変更の反映が最大2秒遅れる       |
| opcache.file\_update\_protection  | 2（秒）    | 2秒以内に更新したファイルは格納しない |
| opcache.file\_cache               | 空（無効）   | 8.5で読み取り専用に対応       |
| opcache.jit                       | disable | 8.4から既定で無効          |

### validate\_timestamps と revalidate\_freq：変更が反映されるまでの秒数

`opcache.validate_timestamps=1` の間、OPcacheは `opcache.revalidate_freq` 秒ごとにファイルの更新時刻を確かめます。既定の2秒で、表示中のファイルを書き換えた直後にリクエストすると旧版が返り、3秒待つと新版が返りました。`validate_timestamps=0` では、書き換えて3秒待っても旧版のままで、Web経由で `opcache_invalidate()` を呼んだ時点で新版に変わりました。

```
# validate_timestamps=1, revalidate_freq=2（既定）
A1 v1
A2(書き換え直後) v1
A3(3秒後) v2-changed

# validate_timestamps=0
B1 v1
B2(書き換えて3秒後) v1
B3(Web経由でopcache_invalidate後) v2-changed
```

`revalidate_freq=0` にすると毎リクエストで更新時刻を確かめるので、開発中は保存した内容が即座に反映されます。その代わり、ファイル数に比例したコストがかかります。先の1,500ファイルのページでは、このMacで中央値が約3msから約14msに増えました。本番で `0` を選ぶのは、管理画面からPHPファイルを書き換えるCMSのように、保存した変更を即座に反映させる必要がある場合に限られます。デプロイ時にだけコードが変わる構成なら、既定の `2` で足ります。

### file\_update\_protection：更新から2秒以内のファイルの格納除外

見落としやすいのが `opcache.file_update_protection`（既定2秒）です。更新時刻が2秒以内のファイルは、書き込み途中の可能性があるため格納されません。ファイルを書いた直後にリクエストしたところ `opcache_is_script_cached()` は `false`、3秒後のリクエストでは `true` でした。デプロイ直後の数秒だけ遅い、ビルド直後に `opcache_compile_file()` でキャッシュを作ったのに何も残らない、という現象はこれで説明がつきます。

### max\_accelerated\_files：既定10000の実効値16229

`opcache.max_accelerated_files` は、固定の素数リスト（223、463、983、1979、3907、7963、16229、32531、65407…）のうち、設定値以上で最小のものに切り上げられます。`opcache_get_status()` の `max_cached_keys` で確かめた結果は次のとおりです。

```
max_accelerated_files=4000 → max_cached_keys=7963
max_accelerated_files=10000 → max_cached_keys=16229
max_accelerated_files=20011 → max_cached_keys=32531
max_accelerated_files=32531 → max_cached_keys=32531
max_accelerated_files=50000 → max_cached_keys=65407
```

既定の10000でも、ハッシュ表のキー数の上限は16229になります。ただしこれはファイル数の上限ではありません。php-srcの実装では `num_cached_scripts`（スクリプト数）と `num_cached_keys`（キー数）を別々に数えており、同じファイルが別のパス表記で読み込まれるとキーだけが増えます（先の1,500ファイルのページはどちらも1,502でした）。判断は `num_cached_keys` と `max_cached_keys` の比で行い、上限に近づいていたら1段上の値に上げます。書くなら素数リストの値をそのまま書くと、設定と実効値がずれません。

### memory\_consumption と interned\_strings\_buffer：総量と文字列領域の内訳

`opcache.interned_strings_buffer` は `memory_consumption` とは別枠ではなく、その内側から確保されます。総量128MBのまま文字列領域を8MBから32MBに増やすと、起動直後の使用量は8.7MBから32.7MBに増え、空きは119.3MBから95.3MBに減りました。先の1,500ファイルを読み込んだ後は、使用量24.4MB・文字列領域の使用3.27MBでした。文字列領域だけを増やすとオペコード用の領域が減るので、増やすときは総量も合わせて増やします。

### enable\_cli：CLIでは既定で無効

`opcache.enable_cli` の既定値は `0` です。`composer` や単発のバッチのように1回で終わるCLIコマンドでは、共有メモリに置いたキャッシュはプロセスとともに消え、次の実行には残りません。こうした用途で効かせたい場合は、後述のファイルキャッシュと組み合わせます。Laravelの `queue:work` のように長時間動き続けるCLIのワーカーは、同じファイルを繰り返し実行するので、`enable_cli=1` の効果が出る余地があります。

### 開発環境と本番環境の分け方

開発環境は `validate_timestamps=1` かつ `revalidate_freq=0` にします。本番は既定の `revalidate_freq=2` で十分速く、先の計測でも `validate_timestamps=0`（約3ms）との差は誤差の範囲でした。`validate_timestamps=0` は、デプロイのたびに確実にFPMをリロードできる場合にだけ選びます。

## file\_cache\_read\_only による読み取り専用ディレクトリへのキャッシュ同梱（8.5）

`opcache.file_cache` は共有メモリの外側に置く2段目のキャッシュで、プロセス再起動後もディスクから読み直せます。8.4までは、このキャッシュ用ディレクトリに書き込めることが前提で、読み取り専用のディレクトリには置けませんでした（書き込み可能なボリュームを別に用意する必要がありました）。8.5の `opcache.file_cache_read_only=1` を使うと、イメージのビルド時にキャッシュを作り、実行時は読み取り専用のディレクトリから読むだけにできます。[UPGRADING](https://github.com/php/php-src/blob/PHP-8.5/UPGRADING)は、`opcache.validate_timestamps=0`、`opcache.enable_file_override=1`、`opcache.file_cache_consistency_checks=0` との併用を推奨しています。

```
# ビルド時：キャッシュ用ディレクトリを先に作る（無いとFatal Errorで止まる）
$ mkdir -p /app/opcache
# キャッシュを作る（対象ファイルは2秒以上前に更新されている必要がある）
$ php -d opcache.enable_cli=1 -d opcache.file_cache=/app/opcache \
    -r 'var_dump(opcache_compile_file("/app/public/index.php"));'
bool(true)

# 実行時：読み取り専用で使う
$ php -d opcache.enable_cli=1 -d opcache.file_cache=/app/opcache \
    -d opcache.file_cache_read_only=1 \
    -r 'var_dump(opcache_is_script_cached_in_file_cache("/app/public/index.php"));'
bool(true)
```

キャッシュのディレクトリから書き込み権限を外しても、上の手順で読み出せました。失敗の仕方は2つあります。1つは `opcache.file_cache` を設定せずに `file_cache_read_only=1` だけを書いた場合で、「opcache.file\_cache\_read\_only is set without a proper setting of opcache.file\_cache」というFatal Errorで起動しません。もう1つは、キャッシュを作った環境と実行環境が違う場合です。UPGRADINGは、PHPのビルド・ファイルのパス・設定（読み込む拡張を含む）のどれかが違うと、キャッシュが無視されることがあると注記しています。ビルド用ステージと実行用ステージで同じベースイメージと同じINIを使ってください。

## JIT有効化の判断基準（8.4以降の既定は disable）

一般的なWebアプリ（WordPress、Laravel、社内API）では**JITを有効にする必要はありません**。PHP 8.4で `opcache.jit` の既定値は `tracing` から `disable` に変わり、`opcache.jit_buffer_size` の既定値は `0` から `64M` に変わりました。8.3以前も `jit_buffer_size=0` だったので既定では動いておらず、結果は同じです。注意が要るのは、`jit_buffer_size` にだけ値を入れてJITを有効にしていた環境で、8.4に上げた時点でJITが黙って止まります。続けるなら `opcache.jit` を明示します。8.4の他の変更は[PHP 8.4の新機能と変更点](/tech/details/4525/)にまとめています。

JITが効くのは、数値計算やループが中心の処理です。PHP 8.5.8で平方根を2,000万回足すループを3回ずつ動かすと、無効で1,309〜1,478ms、`opcache.jit=tracing` で536〜644msでした。一方、先の1,500ファイルを読む検証用ページでは、無効で約2.5〜3.2ms、有効で約2.8〜3.1msと差が出ませんでした。WordPressやLaravelそのものを測った結果ではありませんが、Webリクエストの時間の多くはファイルの読み込み、DB、ネットワーク待ちが占めており、JITが短くするのは計算の部分だけです。

```
; 数値計算バッチなど、CPUが律速の処理でだけ試す
opcache.jit=tracing
opcache.jit_buffer_size=64M
```

有効にするなら対象を絞り、前後のレスポンスタイムを測ってから本番に入れます。JITの仕組みや他言語との違いは[JITコンパイラとは？仕組み・AOTとインタプリタとの違い](/tech/details/3314/)で解説しています。リクエストごとの起動処理そのものを減らしたいなら、JITよりワーカー常駐型の実行環境が効きます。[FrankenPHP](/tech/details/7256/)や[Laravel Octane](/tech/details/17131/)が選択肢になります。

## OPcacheのデメリットと、実際に起きる事故

### デプロイ後に古いコードが返る症状と対処

最大のデメリットはこれです。`validate_timestamps=0` では、新しいコードを配置してもキャッシュが差し替わりません。デプロイ手順にキャッシュの破棄を組み込むことが前提になります。

```
# PHP-FPMをリロードすればキャッシュは作り直される（安全側）
$ sudo systemctl reload php8.5-fpm
```

よくある失敗が、デプロイジョブのCLIから `php -r 'opcache_reset();'` を実行して済ませる構成です。`enable_cli=1` にしたCLIで試すと、`opcache_reset()` は `true` を返したのに、Web側は古いコードを返し続けました（`enable_cli=0` のCLIでは `false` が返ります）。同じ処理をWeb経由のスクリプトで呼ぶと、その次のリクエストから新しいコードに切り替わりました。CLIとWebはSAPIが違い、共有メモリも別だからです。プロセスを落とさずに消したい場合は、認証とIP制限を付けたエンドポイントから呼びます。Laravelの `config:cache` などフレームワーク側のキャッシュは別物で、整理は[Laravelのキャッシュクリア](/tech/details/17121/)にまとめています。

### シンボリックリンク方式のデプロイとrealpathキャッシュ

`current` → `releases/20261015` のようにリンクを張り替えるデプロイでは、nginxがFPMへ渡す `SCRIPT_FILENAME` がリンク側のパス（`/var/www/current/index.php`）のままだと、PHPは**realpathキャッシュ**で実パスを解決します。`realpath_cache_ttl` の既定値は120秒で、その間はリンクを張り替えても古いリリースのパスが返り、OPcacheも古いコードを返します。デプロイ直後だけ旧版が混ざる事故の典型です。

```
# nginx: リンクを解決した実パスをFPMへ渡す
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT $realpath_root;
```

`$realpath_root` を使えばリリースごとに別のパスがキーになり、切り替えと同時に新しいコードがコンパイルされます。代わりに、切り替え直後は全ファイルが未キャッシュになり、リリースごとにキーが積み上がって `max_accelerated_files` を消費します。`opcache.revalidate_path`（既定 `0`）は `include_path` 上の同名ファイルの解決に関する設定で、この対策にはなりません。確実なのは、リンクを張り替えた後にPHP-FPMをリロードすることです。

### メモリ不足とキャッシュの全消し

共有メモリが埋まると新しいスクリプトを格納できなくなります。空きが足りず、更新で古くなったスクリプトが占める無駄な領域が `opcache.max_wasted_percentage`（既定5%）を超えていると、キャッシュ全体を捨てて作り直します。直後は全リクエストがコンパイルを伴うので、CPU使用率とレスポンスタイムが跳ねます。監視でヒット率だけを見ていると見逃すので、`oom_restarts` と `free_memory` も見てください。

## WordPressの「オペコードキャッシュが有効化されていません」への対処

この項目は、2026年5月20日公開の[WordPress 7.0](https://wordpress.org/documentation/wordpress-version/version-7-0/)でサイトヘルスに追加されました（[WP\_Site\_Health::get\_test\_opcode\_cache()](https://developer.wordpress.org/reference/classes/wp%5Fsite%5Fhealth/get%5Ftest%5Fopcode%5Fcache/)）。判定は単純で、`opcache_get_status(false)` の戻り値の `opcache_enabled` が `true` なら「良好」、それ以外はすべて「おすすめの改善」です。2026年10月15日時点の開発版（trunk）でも判定は変わっていません。7.0のその他の変更は[WordPress 7.0「Armstrong」の新機能・変更点](/tech/details/11971/)を参照してください。

警告の原因は、OPcacheが実際に無効な場合と、OPcacheは動いているのに状態を取得できない場合の2つに分かれます。どちらもプラグインでは解決できず、キャッシュ系プラグインを入れても、ページキャッシュや永続オブジェクトキャッシュの項目とは別なので消えません。

- **VPS・専用サーバー**：php.iniで `opcache.enable=1` にしてPHP-FPMをリロードする。PHP 8.5なら拡張のインストールは不要。
- **レンタルサーバー**：管理画面のPHP設定でOPcache（「PHPアクセラレータ」等の名称もある）を有効にする。提供がなければ消せない。
- **関数が封じられている**：`disable_functions` で `opcache_get_status` が無効にされている、または `opcache.restrict_api` で呼び出しが制限されていると、OPcacheが動いていても警告が出る。[Trac #65946](https://core.trac.wordpress.org/ticket/65946)（#65395の重複としてクローズ）がこの誤判定の報告。この場合は性能上の問題ではないので、警告を許容してよい。

本当に動いているかは、`phpinfo()` の `opcache.enable` と「Opcode Caching」の欄で確かめられます。PHPのバージョン切り替えやサーバー設定まで含めて手当てが必要な場合は、[WordPress保守・メンテナンス](/service/web/wordpress-support/)でも対応しています。

## よくある質問（FAQ）

### OPcacheの読み方は？

公式の読み仮名はなく、「オーピーキャッシュ」「オプキャッシュ」の両方が使われています。opcode cache の略で、WordPressの日本語UIでは「オペコードキャッシュ」と訳されています。

### php8.5-opcache をインストールできないのはなぜ？

PHP 8.5でOPcacheが本体に組み込まれ、独立したパッケージがなくなったためです。`php8.5-fpm` や `php8.5-cli` を入れれば使える状態になり、`php -m | grep -i opcache` で確認できます。移行スクリプトからは `-opcache` の行を削除してください。

### ファイルを更新したのに反映されないのはなぜ？

既定の `revalidate_freq=2` では、更新から最大2秒は古いコードが返ります。`validate_timestamps=0` の場合は、PHP-FPMのリロードかWeb経由の `opcache_reset()` をするまで反映されません。

### opcache\_reset() をCLIで実行してもキャッシュが消えないのはなぜ？

CLIとPHP-FPMはSAPIが違い、共有メモリを共有していないためです。CLIの `opcache_reset()` が成功しても、消えるのはCLI側のキャッシュだけです（CLIでOPcacheが無効なら `false` が返ります）。FPMのキャッシュは、FPMのリロードか、Web経由で実行するスクリプトから消します。

### JITは有効にすべき？

PHP 8.4以降、`opcache.jit` の既定値は `disable` です。DBやファイルの読み込みが中心のWebアプリでは効果が出にくく、既定のままで問題ありません。数値計算のバッチなどCPUが律速の処理に限り、測ってから有効にします。

## 関連記事

- [PHP 8.5の変更点と新機能まとめ｜リリース日・主要機能・非推奨と移行ポイント](/tech/details/8179/)
- [PHP 8.4の新機能と変更点｜プロパティフック・配列検索関数・非推奨対応を実行結果で確認](/tech/details/4525/)
- [JITコンパイラとは？仕組み・AOTとインタプリタとの違いと主要言語の実装](/tech/details/3314/)
- [FrankenPHPとは？PHP-FPMとの違い・ワーカーモードの仕組みと導入手順【v1.12対応】](/tech/details/7256/)
- [WordPress 7.0「Armstrong」の新機能・変更点と安全なアップデート手順](/tech/details/11971/)

---

出典: [OPcacheとは？読み方とPHP 8.5の変更点・設定・確認方法](<https://www.issoh.co.jp/tech/details/7965/>)（株式会社一創）
