PHPのOPcacheとは何か、仕組みや設定方法について

採用はこちら

PHPのOPcacheとは、PHPスクリプトをコンパイルした結果である「オペコード」をメモリ上にキャッシュし、PHPの実行を高速化するための仕組みです。

PHPは、ソースコードをそのまま直接実行しているわけではありません。

PHPファイルを読み込み、構文解析やコンパイルを行い、Zend Engineが実行できるオペコードへ変換してからプログラムを実行します。

OPcacheを利用していない場合、このコンパイル処理がリクエストのたびに発生します。

一方、OPcacheを有効にすると、一度コンパイルしたPHPスクリプトのオペコードを共有メモリに保存できます。

キャッシュが有効でPHPファイルに変更がなければ、次回以降のリクエストではコンパイル済みのオペコードを再利用できます。

その結果、PHPスクリプトの解析やコンパイルにかかる処理を減らし、Webアプリケーションのレスポンス向上やCPU負荷の軽減につなげられます。

WordPressやLaravelなど、多数のPHPファイルを読み込むWebアプリケーションでは特に重要な高速化機能です。

目次

PHPがコードを実行する基本的な仕組み

OPcacheを使わない場合

PHPでは、概略として次のような流れでPHPファイルを実行します。

PHPソースコード
      ↓
ファイルを読み込む
      ↓
字句解析・構文解析
      ↓
コンパイル
      ↓
オペコードを生成
      ↓
Zend Engineが実行
      ↓
結果を出力

例えば、次のようなPHPコードがあるとします。

<?php

echo 'Hello, World!';

PHPはこのコードを解析してオペコードへコンパイルし、そのオペコードをZend Engineで実行します。

OPcacheを利用していなければ、Webリクエストが発生するたびに同様の処理が必要になります。

OPcacheを使った場合

OPcacheが有効になっている場合、初回アクセスではPHPスクリプトをコンパイルし、その結果を共有メモリに保存します。

PHPファイル
    ↓
解析・コンパイル
    ↓
オペコード
    ↓
OPcacheへ保存
    ↓
実行

次回以降は、条件を満たしていればOPcacheに保存されているオペコードを利用します。

PHPファイル
    ↓
OPcacheを確認
    ↓
キャッシュ済みオペコードを利用
    ↓
実行

これによって、毎回同じPHPコードを解析・コンパイルする必要がなくなります。

ただし、PHPファイルが変更された場合やキャッシュが無効になった場合などには、再びコンパイルが行われます。

そのため、厳密には「2回目以降は必ずコンパイルされない」というわけではありません。

OPcacheを利用するメリット

PHPの実行速度を向上させやすい

OPcacheの最大のメリットは、PHPのコンパイル処理を減らせることです。

一般的なWebアプリケーションでは、1回のリクエストで複数のPHPファイルが読み込まれます。

WordPressであれば、WordPress本体、テーマ、プラグインなど、多数のPHPファイルが実行されます。

LaravelなどのPHPフレームワークでも、多数のクラスファイルやライブラリが読み込まれます。

OPcacheを利用すれば、これらのコンパイル済みオペコードを再利用できるため、処理効率を改善できます。

CPU負荷を軽減できる

PHPコードの解析やコンパイルにはCPUリソースが必要です。

OPcacheによってコンパイル処理の回数を減らせれば、CPU負荷の軽減も期待できます。

アクセス数が多いWebサイトほど、リクエストごとに発生する処理の削減効果が積み重なるため、OPcacheのメリットを得やすくなります。

PHPコードを変更せずに利用できる

OPcacheは基本的にPHPの実行環境側で設定する機能です。

そのため、OPcacheを有効にするためだけに既存のPHPコードを大幅に書き換える必要はありません。

多くの場合は、php.iniなどの設定ファイルを変更することで利用できます。

既存のWordPressサイトやPHPアプリケーションにも導入しやすい点が特徴です。

OPcacheとほかのキャッシュの違い

OPcacheはオペコードをキャッシュする

OPcacheがキャッシュする対象は、PHPのコンパイル済みオペコードです。

PHPコード
↓
コンパイル
↓
オペコード
↓
OPcache

つまり、PHPプログラムを実行する前段階の処理を効率化するためのキャッシュです。

ページキャッシュはHTMLなどを保存する

ページキャッシュでは、PHPなどによって生成されたHTMLを保存します。

PHPを実行
↓
HTMLを生成
↓
HTMLをキャッシュ

キャッシュ済みのHTMLをそのまま返せる場合は、PHPそのものを実行する必要がなくなることがあります。

そのため、ページキャッシュとOPcacheでは高速化するレイヤーが異なります。

オブジェクトキャッシュはデータを保存する

RedisやMemcachedなどを利用したオブジェクトキャッシュでは、アプリケーションで利用するデータをメモリ上へ保存します。

例えば、次のようなデータが対象になります。

  • データベースの問い合わせ結果
  • 設定情報
  • セッション関連データ
  • APIから取得したデータ
  • 計算結果

OPcacheはPHPのオペコードを対象としているため、オブジェクトキャッシュとは役割が異なります。

APCuとも役割が異なる

APCuは、PHPアプリケーションから任意のデータを共有メモリ上へキャッシュするための機能です。

OPcacheがPHPコードのコンパイル結果をキャッシュするのに対し、APCuはアプリケーション側のデータをキャッシュします。

そのため、OPcacheとAPCuは競合するものではなく、目的が異なる機能として考える必要があります。

OPcacheが利用できるPHPバージョン

PHP 5.5以降では標準でバンドルされている

OPcacheはPHP 5.5以降、PHPに標準でバンドルされています。

ただし、「PHPに含まれている」ことと「必ず有効になっている」ことは同じではありません。

PHPのバージョンやインストール方法、サーバー環境によって設定方法が異なる場合があります。

PHP 8.5ではOPcacheの扱いが変更された

PHP 8.5では、OPcache拡張がPHPバイナリに常に組み込まれ、ロードされる仕様になりました。

ただし、OPcacheのキャッシュ機能そのものが常に有効になるわけではありません。

次のような設定によって、有効・無効を制御できます。

opcache.enable=1
opcache.enable_cli=0

つまり、PHP 8.5ではOPcache拡張そのもののロード方法が変わりましたが、OPcacheを利用するかどうかを制御する設定は引き続き存在します。

OPcacheが有効か確認する方法

phpinfo()で確認する

ブラウザからOPcacheの状態を確認する場合は、phpinfo()を利用できます。

<?php

phpinfo();

表示されたページの中に「Zend OPcache」という項目があれば、OPcacheに関する設定を確認できます。

ただし、phpinfo()にはPHPのバージョン、パス、拡張機能、サーバー設定など、多くの内部情報が表示されます。

本番環境で誰でもアクセスできる状態にしておくことは避けましょう。

確認が終わったらファイルを削除するなどの対応が必要です。

php -mで確認する

CLI版PHPでは、次のコマンドで読み込まれているモジュールを確認できます。

php -m

一覧に次のような表示があれば、OPcacheが読み込まれています。

Zend OPcache

php -iで詳しい設定を確認する

Linuxなどでは、次のようにしてOPcache関連の設定を確認できます。

php -i | grep opcache

ただし、CLI版PHPとWebサーバー経由のPHPでは異なるphp.iniを読み込んでいる場合があります。

CLIで有効になっているからといって、PHP-FPMやApacheでも同じ設定になっているとは限りません。

OPcacheの基本的な設定方法

php.iniで設定する

OPcacheの設定は主にphp.iniで行います。

例えば、基本的な設定例として次のような構成があります。

[opcache]

opcache.enable=1
opcache.memory_consumption=128
opcache.interned_strings_buffer=8
opcache.max_accelerated_files=10000
opcache.validate_timestamps=1
opcache.revalidate_freq=2

ただし、上記はあくまで設定方法を理解するための一例です。

すべてのサーバーに最適な推奨値ではありません。

サーバーのメモリ容量、PHPファイル数、PHPバージョン、アプリケーションの規模、デプロイ方法などに合わせて調整する必要があります。

opcache.enableとは

OPcacheを有効・無効にする

opcache.enableは、Webサーバー側でOPcacheを有効にするための主要な設定です。

有効にする場合は次のように設定します。

opcache.enable=1

無効にする場合は次のようにします。

opcache.enable=0

一般的な本番Webサーバーでは、OPcacheを利用するために1を設定します。

なお、opcache.enableは無効になっている状態からini_set()を利用して実行時に有効化することはできません。

そのため、基本的にはPHPの設定ファイル側で有効化します。

opcache.enable_cliとは

CLI版PHPでOPcacheを使うか設定する

opcache.enable_cliは、CLI版PHPでOPcacheを有効にするかどうかを決める設定です。

opcache.enable_cli=1

とすると有効になります。

opcache.enable_cli=0

とすると無効になります。

CLI版PHPとは、次のようにコマンドラインから実行するPHPです。

php script.php

Webサーバー向けのopcache.enableとは別設定になっているため注意しましょう。

単発で短時間しか実行しないCLIスクリプトではOPcacheの効果が限定的な場合があります。

一方、長時間稼働するCLIプロセスなどでは状況が異なるため、用途に応じて判断する必要があります。

opcache.memory_consumptionとは

OPcache用の共有メモリ容量を設定する

opcache.memory_consumptionでは、OPcacheが使用する共有メモリの容量をMB単位で設定します。

例えば、128MBにする場合は次のようにします。

opcache.memory_consumption=128

より多くのPHPファイルをキャッシュする必要がある場合は、次のように増やすこともできます。

opcache.memory_consumption=256

ただし、大きくすれば必ず高速になるわけではありません。

PHPファイルを十分キャッシュできているのであれば、それ以上メモリを増やしても効果がほとんどない場合があります。

サーバー全体のRAM容量とのバランスを見ながら調整することが重要です。

opcache.interned_strings_bufferとは

Interned Strings用のメモリを設定する

opcache.interned_strings_bufferは、Interned Strings用の共有メモリ容量を設定する項目です。

例えば次のように指定します。

opcache.interned_strings_buffer=16

PHPでは、クラス名や関数名、配列キーなど、同じ文字列が繰り返し利用されることがあります。

Interned Stringsの仕組みでは、同一の文字列を効率的に共有することでメモリ使用量を抑えられます。

大規模なPHPアプリケーションでは、OPcache全体のメモリ使用量とあわせて確認するとよいでしょう。

opcache.max_accelerated_filesとは

キャッシュ対象となるPHPファイル数に関係する

opcache.max_accelerated_filesは、OPcacheがキャッシュできるPHPスクリプト数の上限に関係する設定です。

例えば次のようにします。

opcache.max_accelerated_files=10000

WordPressに多数のプラグインを導入している場合や、Laravelなどの大規模なアプリケーションではPHPファイル数が多くなることがあります。

値が小さすぎると、必要なPHPファイルを十分にキャッシュできない可能性があります。

ただし、単純にPHPファイル数と同じ値にすればよいわけではありません。

実際のOPcacheの使用状況を確認しながら設定することが大切です。

opcache.validate_timestampsとは

PHPファイルの更新を確認するか設定する

opcache.validate_timestampsは、PHPファイルが更新されたかどうかを確認するための重要な設定です。

opcache.validate_timestamps=1

にすると、OPcacheは一定の条件でPHPファイルの更新を確認します。

開発環境ではコードを頻繁に書き換えるため、通常はこちらの設定が扱いやすいでしょう。

一方、次のようにするとタイムスタンプによる変更確認を無効化できます。

opcache.validate_timestamps=0

変更確認を無効化すると、PHPファイルを書き換えても古いオペコードが利用され続ける場合があります。

そのため、本番環境でこの設定を利用する場合は、デプロイ時にOPcacheをリセットする、PHP-FPMを適切に再起動するなど、キャッシュを更新する仕組みを用意することが重要です。

opcache.revalidate_freqとは

PHPファイルの更新確認頻度を設定する

opcache.revalidate_freqは、opcache.validate_timestampsが有効な場合に、ファイル変更を確認する頻度に関係する設定です。

例えば次のように設定します。

opcache.revalidate_freq=2

また、次のように0を設定すると、基本的に各リクエストで更新確認を行う動作になります。

opcache.revalidate_freq=0

開発環境では、PHPコードの変更をすぐ反映させたい場合に利用されることがあります。

本番環境では、パフォーマンスやデプロイ方法とのバランスを考えて設定する必要があります。

開発環境でのOPcache設定例

コード変更を反映しやすくする

開発環境では、PHPコードを書き換えたときに変更がすぐ反映されることが重要です。

例えば次のような設定が考えられます。

opcache.enable=1
opcache.validate_timestamps=1
opcache.revalidate_freq=0

この設定であれば、OPcacheを利用しながらコード変更を比較的反映しやすくできます。

ただし、OPcacheそのものの影響を調査したい場合などは、開発環境で一時的に無効化することもあります。

本番環境でのOPcache設定例

デプロイ方式とセットで考える

本番環境ではパフォーマンスを重視するため、次のような設定を採用するケースがあります。

opcache.enable=1
opcache.validate_timestamps=0

ただし、この設定は「本番環境なら必ず推奨される」という意味ではありません。

opcache.validate_timestamps=0にするとPHPファイルの変更を自動的に検出しなくなるため、デプロイ時にOPcacheを確実に更新する仕組みが必要です。

適切なデプロイフローを用意していない環境では、古いPHPコードが実行され続ける原因になる可能性があります。

OPcacheのキャッシュをリセットする方法

opcache_reset()を利用する

OPcacheには、メモリ上のオペコードキャッシュをリセットするためのopcache_reset()関数があります。

<?php

opcache_reset();

関数が存在するか確認してから利用する場合は次のように書けます。

<?php

if (function_exists('opcache_reset')) {
    opcache_reset();
}

opcache_reset()を実行すると、メモリ上に保存されているオペコードキャッシュがリセットされます。

その後PHPファイルへアクセスすると、必要に応じて再びコンパイルとキャッシュが行われます。

ただし、opcache_reset()はOPcacheのファイルキャッシュまで削除する関数ではありません。

「OPcacheに関するすべてのデータを完全に削除する」と考えないようにしましょう。

また、不特定多数のユーザーがアクセスできるWebページにopcache_reset()を設置するのは危険です。

必要な場合は管理者だけが実行できる仕組みや、デプロイ処理の中で実行する方法を検討しましょう。

特定のPHPファイルだけキャッシュを無効化する方法

opcache_invalidate()を利用する

特定のPHPファイルだけキャッシュを無効化したい場合は、opcache_invalidate()を利用できます。

<?php

opcache_invalidate('/var/www/html/example.php', true);

OPcache全体をリセットする必要がなく、個別のPHPスクリプトを対象にできる点が特徴です。

複数のPHPファイルを更新する一般的なデプロイでは全体のキャッシュ更新を検討することが多いですが、特定ファイルだけを操作したい場合に利用できます。

OPcacheの状態を確認する方法

opcache_get_status()を利用する

OPcacheのメモリ使用状況やキャッシュ状態を確認したい場合は、opcache_get_status()を利用できます。

<?php

$status = opcache_get_status();

print_r($status);

取得できる情報には、OPcacheの有効状態、メモリ利用状況、キャッシュされているスクリプト数などが含まれます。

ただし、opcache_get_status()が返すのは主にメモリ上のOPcacheインスタンスに関する情報です。

ファイルキャッシュの状態を確認するための関数ではない点に注意しましょう。

opcache_get_configuration()を利用する

OPcacheの設定値を確認したい場合は、opcache_get_configuration()を利用できます。

<?php

$config = opcache_get_configuration();

print_r($config);

opcache_get_status()が稼働状態を確認するための関数なのに対し、opcache_get_configuration()は設定情報を確認するための関数と考えると分かりやすいでしょう。

php.iniを変更した後の注意点

PHP実行環境の再読み込みが必要になることがある

php.iniを変更しても、実行中のPHP環境へすぐ反映されるとは限りません。

PHP-FPMを利用している場合は、PHP-FPMの再読み込みや再起動が必要になる場合があります。

ApacheのモジュールとしてPHPを利用している場合は、Apache側の再起動が必要になるケースもあります。

Dockerなどのコンテナ環境では、コンテナの再起動や再作成が必要になる場合もあります。

どの処理が必要になるかはPHPの実行方式によって異なるため、使用しているサーバー環境に合わせて確認しましょう。

php –iniはCLI版の設定を表示する

CLI版PHPがどの設定ファイルを読み込んでいるか確認する場合は次のコマンドを利用できます。

php --ini

ただし、このコマンドで確認できるのはCLI版PHPの設定です。

例えば、同じサーバーでも次の環境で異なる設定ファイルが読み込まれている可能性があります。

CLI
PHP-FPM
Apache module

php.iniを変更したのにWebサイト側へ反映されない」という場合は、変更した設定ファイルが本当にWebサーバー側で使用されているか確認しましょう。

OPcacheとJITの違い

OPcacheはオペコードをキャッシュする

OPcacheは、PHPコードをコンパイルした結果であるオペコードを保存して再利用する仕組みです。

PHPコード
↓
コンパイル
↓
オペコード
↓
OPcacheへ保存

主な目的は、同じPHPコードを何度も解析・コンパイルする処理を減らすことです。

JITは一部の処理を機械語へ変換する

JITは「Just-In-Time compilation」の略で、実行時にコードの一部をネイティブな機械語へコンパイルする仕組みです。

概念的には次のように区別できます。

OPcache
→ コンパイル済みオペコードを保存して再利用する

JIT
→ 実行時に一部の処理をネイティブコードへ変換する

OPcacheとJITは関連する仕組みではありますが、目的は同じではありません。

一般的なWebアプリケーションでは、JITよりもOPcacheを適切に有効化することの方が基本的なパフォーマンス対策となるケースが多くあります。

WordPressでもOPcacheは効果的

多数のPHPファイルを利用するため恩恵を受けやすい

WordPressでは、ページを表示するときにWordPress本体だけでなく、テーマやプラグインなど多数のPHPファイルが読み込まれます。

OPcacheが有効になっていれば、それらのPHPファイルのコンパイル済みオペコードを再利用できます。

そのため、WordPressでもOPcacheはPHP実行環境を高速化するための有効な手段です。

ただし、OPcacheはWordPressそのものの機能ではありません。

PHP実行環境側で利用する機能です。

ページキャッシュやRedisとは併用できる

WordPressでは次のようなキャッシュ技術が利用されることがあります。

OPcache
ページキャッシュ
オブジェクトキャッシュ
CDN
ブラウザキャッシュ

それぞれキャッシュする対象が異なります。

OPcacheを有効にしたからといって、ページキャッシュやRedisなどが不要になるわけではありません。

複数のキャッシュ機能を適切に組み合わせることで、WordPress全体のパフォーマンス改善を図れます。

OPcacheを設定するときの注意点

PHPファイルの変更が反映されない場合がある

OPcache利用時によくあるトラブルのひとつが、「PHPファイルを更新したのに内容が変わらない」という問題です。

特に次の設定を使用している場合は注意が必要です。

opcache.validate_timestamps=0

この場合、PHPファイルを変更してもOPcacheが自動的に更新を検出しません。

デプロイ時にOPcacheをリセットする、PHP-FPMを再起動するなど、キャッシュを更新する運用が必要になります。

メモリ容量を大きくしすぎない

opcache.memory_consumptionを大きくすれば必ず高速になるわけではありません。

必要なPHPファイルを十分キャッシュできている場合、それ以上メモリを増やしてもメリットが小さい可能性があります。

サーバー全体のRAM使用量を確認しながら設定しましょう。

PHPファイル数も確認する

PHPファイル数が多いアプリケーションでは、opcache.max_accelerated_filesが不足する場合があります。

メモリ容量だけでなく、キャッシュされているスクリプト数についても確認するとよいでしょう。

CLIとWebサーバー側の設定を混同しない

CLIで次のコマンドを実行してOPcacheが有効になっていたとしても、

php -i

Webサイト側で同じ設定が使われているとは限りません。

PHP-FPMやApacheなど、実際にWebリクエストを処理しているPHP環境の設定を確認することが重要です。

OPcacheを安全に運用するポイント

本番環境ではデプロイ方法まで考える

OPcacheの設定は、単純に「高速な値を設定すればよい」というものではありません。

特に本番環境では、コードを更新したときに新しいPHPファイルが確実に反映される仕組みまで含めて設計する必要があります。

例えば、次のような流れを用意します。

新しいPHPコードを配置
↓
OPcacheを更新
↓
必要に応じてPHP-FPMを再読み込み
↓
動作確認

OPcacheのパフォーマンスだけでなく、安全にデプロイできることも重要です。

実際の使用状況を確認して調整する

OPcacheの設定値には、すべての環境で通用する絶対的な正解はありません。

サーバーのRAM容量、PHPファイル数、アプリケーションの規模、アクセス数などによって適切な値は変わります。

opcache_get_status()などを利用し、実際のメモリ使用量やキャッシュ状況を確認しながら調整するとよいでしょう。

PHPのOPcacheについてのまとめ

PHPのOPcacheとは、PHPスクリプトをコンパイルした結果であるオペコードを共有メモリに保存し、再利用するための高速化機能です。

OPcacheを利用すると、リクエストのたびにPHPファイルをゼロから解析・コンパイルする処理を減らせます。

そのため、PHPアプリケーションのレスポンス改善やCPU負荷の軽減が期待できます。

基本的な設定では、次のような項目を理解しておくことが重要です。

opcache.enable
opcache.enable_cli
opcache.memory_consumption
opcache.interned_strings_buffer
opcache.max_accelerated_files
opcache.validate_timestamps
opcache.revalidate_freq

特にopcache.validate_timestampsは、PHPファイルの変更をどのように反映するかに関わる重要な設定です。

本番環境でopcache.validate_timestamps=0を利用する場合は、デプロイ時にOPcacheを確実に更新できる仕組みを用意する必要があります。

WordPressやLaravelをはじめ、多数のPHPファイルを利用するWebアプリケーションでは、OPcacheは基本的なパフォーマンス改善策のひとつです。

ただし、単に有効化するだけでなく、メモリ容量やキャッシュ対象ファイル数、PHPファイルの更新方法まで含めて設定することで、安全かつ効率的に運用できます。

以上、PHPのOPcacheとは何か、仕組みや設定方法についてでした。

最後までお読みいただき、ありがとうございました。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次