2026年8月10日

2026年8月10日

PHP の disable_functions とは|php.ini での設定の確認と、WordPress で「Call to undefined function」が出るときの対処

disable_functions は、PHP の設定(php.ini)で指定した関数を使えなくする機能です。exec や shell_exec のように外部コマンドを動かす関数を止めるために、サーバー会社や管理者が設定していることがあります。WordPress のプラグインやテーマがこうした関数を使っていると、サイトが表示されなくなったり、特定の機能だけが失敗したりします。この記事では、原因の特定から設定の直し方までを説明します。内容は2026年10月時点のもので、PHP 8.3 で動作を確認しています。

PHP 8 では「Call to undefined function」になる

PHP の公式マニュアルによると、PHP 8.0 以降は disable_functions に書いた関数の定義そのものが取り除かれます。そのため、無効にされた関数を呼ぶと、存在しない関数を呼んだときと同じ致命的エラーになります。

PHP Fatal error:  Uncaught Error: Call to undefined function exec() in /var/www/html/wp-content/plugins/example-plugin/includes/backup.php:120

function_exists( 'exec' ) も false を返します。PHP 8.0 より前は、関数の定義は残ったまま実行だけが止められていたため、エラーの出方が異なります。

WordPress 側では、致命的エラーが起きると「重大なエラーが発生しました」という趣旨の画面が表示されます。原因がプラグインやテーマの場合は、サイト管理者のメールアドレスに、リカバリーモードでログインするためのリンクが付いた通知が送られます(メールを送れるサーバーの場合)。プラグインの有効化の直後なら、有効化そのものが失敗します。

本体よりもプラグイン・テーマが原因になりやすい

WordPress 本体は、set_time_limit、ini_get、exec、curl_exec などを使う前に、多くの箇所で function_exists() で関数があるかを確かめています。そのため、これらが無効にされていても本体の処理は止まらないことが多く、エラーになるのは、確かめずに呼んでいるプラグインやテーマのコードであることがほとんどです。

ステップ1:エラーログで関数名とファイルを特定する

まずエラーの内容を確認します。サーバーのエラーログが見られない場合は、wp-config.php の「編集が必要なのはここまでです」という行より前に次を書き、WordPress のデバッグログを有効にします。

define( 'WP_DEBUG', true );
define( 'WP_DEBUG_LOG', true );
define( 'WP_DEBUG_DISPLAY', false );

エラーを起こした操作をもう一度行い、wp-content/debug.log を開いて Call to undefined function を探します。ログには次の2つが書かれています。

  • 関数名:exec() のように、使えなかった関数
  • ファイルのパス:wp-content/plugins/ の次のフォルダー名が原因のプラグイン、wp-content/themes/ ならテーマ

原因がわかったら、デバッグの設定は元に戻します(debug.log は外から読める場所にできるため、消しておきます)。

ステップ2:本当に disable_functions が原因か確かめる

「Call to undefined function」は、disable_functions 以外でも出ます。たとえば mb_ で始まる関数は mbstring、imagecreatetruecolor() は GD、curl_ で始まる関数は curl という PHP の拡張機能が入っていないと同じエラーになります。どちらなのかを、Web サーバーで動いている PHP 自身に確かめさせます。

WordPress のフォルダーに、推測されにくい名前(例 check-7f3a9c.php)で次のファイルを置き、ブラウザで開きます。確認が終わったらすぐに削除してください。

<?php
// 確認が終わったらすぐ削除する
header( 'Content-Type: text/plain; charset=UTF-8' );

echo 'PHP: ', PHP_VERSION, "\n";
echo 'SAPI: ', PHP_SAPI, "\n";
echo 'php.ini: ', php_ini_loaded_file(), "\n";
echo 'disable_functions: ', ini_get( 'disable_functions' ), "\n\n";

// ログに出た関数名をここに書く
$names = array( 'exec', 'shell_exec', 'proc_open', 'popen', 'set_time_limit' );

foreach ( $names as $name ) {
	echo $name, ': ', function_exists( $name ) ? 'available' : 'NOT available', "\n";
}

見るところは次のとおりです。

  • 関数名が disable_functions の一覧にあれば、disable_functions が原因です
  • 一覧に無いのに NOT available なら、その関数を含む拡張機能が入っていない可能性があります
  • php.ini: の行は、Web で動く PHP が読んでいる php.ini の場所です。ステップ3で直すのはこのファイルです

SSH で php -i を実行して確かめる方法は使わないでください。コマンドラインの PHP(CLI)は、Web で動く PHP(PHP-FPM や Apache のモジュール)とは別の php.ini を読むことが多く、結果が一致しません。WP-CLI ではエラーにならないのに、管理画面ではエラーになる、ということも起こります。

注意:PHP-FPM のプール設定で disable_functions を指定している場合、ini_get( 'disable_functions' ) にはプールの値だけが表示され、php.ini 側で無効にした関数は表示されないことがあります(PHP 8.3 で確認)。関数が使えるかどうかは、function_exists() の結果で判断してください。

ステップ3:対処する

レンタルサーバーの場合

共用のレンタルサーバーでは、disable_functions は利用者が変えられないことがほとんどです。disable_functions は php.ini でしか設定できない項目で、.htaccess や .user.ini、プログラムの中の ini_set() では変更できません。次の順に検討します。

  1. 原因のプラグインの設定に、外部コマンドを使わない方式が用意されていないか確認する(プラグインの説明やサポートフォーラム)
  2. 同じ目的で、その関数を使わない別のプラグインに替える
  3. サーバー会社のサポートに、その関数を使える設定やプランがあるか問い合わせる

サイトが表示されないままなら、FTP で wp-content/plugins/ の原因のプラグインのフォルダー名を変える(例 example-plugin を example-plugin-off にする)と、そのプラグインは無効になり、サイトが表示されるようになります。

VPS で php.ini を直す場合

Ubuntu で PHP 8.3 を使っている例です。PHP のバージョンや OS が違う場合は、ステップ2で表示された php.ini のパスに読み替えてください。

# PHP-FPM が読む設定の中から disable_functions を探す(php.ini とプール設定の両方)
grep -rn 'disable_functions' /etc/php/8.3/fpm/

# Apache のモジュール(mod_php)で動かしている場合
grep -rn 'disable_functions' /etc/php/8.3/apache2/

見つかった行から、必要な関数だけを消します。一覧ごと空にはしないでください。

; 変更前
disable_functions = exec,passthru,shell_exec,system,proc_open,popen

; 変更後(proc_open だけ使えるようにした例)
disable_functions = exec,passthru,shell_exec,system,popen

保存したら、PHP を再起動して設定を読み込ませます。

# PHP-FPM の場合
sudo systemctl restart php8.3-fpm

# Apache のモジュールの場合
sudo systemctl restart apache2

PHP-FPM のプールごとに分けたい場合

1台のサーバーで複数のサイトを動かしていて、1つのサイトだけで関数を使えるようにしたい場合は、プール設定の php_admin_value を使います。

; /etc/php/8.3/fpm/pool.d/example.conf(サイトごとのプール)
php_admin_value[disable_functions] = exec,passthru,shell_exec,system,popen

ここで気をつけたいのは、php.ini で無効にした関数は、プール設定では使えるように戻せないことです。PHP 8.3 で確かめたところ、php.ini に exec、プールに shell_exec を書くと、両方が無効になりました。プールごとに分けるときは、php.ini の disable_functions からその関数を外し、使わせたくないプールすべての php_admin_value[disable_functions] に書きます。

ステップ4:動作を確認する

ステップ2の確認用ファイルをもう一度開き、関数が available になったことを確かめてから、ファイルを削除します。次に、エラーが出ていた操作(プラグインの有効化、バックアップの実行など)を行い、debug.log やサーバーのエラーログに新しいエラーが出ないことを確認します。

関数を使えるようにする前に考えること

  • exec、shell_exec、system、passthru、proc_open、popen は、サーバー上でコマンドを実行できる関数です。サイトが改ざんされた場合、攻撃者もこれらを使えるようになるため、使えるようにするのは必要な関数とサイトに絞ります
  • PHP の公式マニュアルは、disable_functions は回避される可能性があり、共用サーバーの安全対策としてこれだけで十分と考えるべきではない、と注意しています。ファイルの権限や、プラグイン・テーマの更新などと組み合わせてください
  • プラグインが外部コマンドを使わない方式を用意しているなら、関数を使えるようにするより、そちらに切り替えるほうが安全です

まとめ

  • PHP 8 では、disable_functions で無効にした関数を呼ぶと「Call to undefined function」の致命的エラーになる
  • エラーログで関数名とファイルのパスを見れば、原因のプラグインやテーマがわかる
  • 拡張機能が入っていない場合も同じエラーになるため、Web で動く PHP の ini_get( 'disable_functions' ) と function_exists() で確かめる
  • レンタルサーバーでは変えられないことが多いので、プラグインの設定変更や別のプラグインを検討する
  • VPS では php.ini から必要な関数だけを外して PHP を再起動する。php.ini で無効にした関数は、PHP-FPM のプール設定では戻せない

関連記事:

お気軽にご相談ください

お見積りへ お問い合わせへ
▲