結論
get_option( $name, $default )の$defaultは、オプションがデータベースに存在しないときだけ返ります(公式の記載)。空文字''や0が保存されていれば、その値が返り、既定値にはなりません。- 「空なら既定値」にしたいときは、
$value = get_option( 'x' ); if ( '' === $value || false === $value ) { ... }のように、自分で判定します。 - 値が
falseかどうかで「存在しない」を判断するのは危険です。falseを保存すると、空文字として保存・取得される場合があります。 - 設定を
register_setting()で登録するなら、default引数で既定値を一元化できます。
原因・仕組み
get_option() は、キャッシュ(alloptions など)を確認し、なければDBを読みます。DBに行がなければ、$default(省略時は false)を返します。行があれば、保存された値を返します。
| 状態 | get_option( 'x', 'D' ) の結果 |
|---|---|
| 行がない | 'D' |
''(空文字)が保存済み |
'' |
false が保存済み |
空文字または false(保存方法による) |
0 が保存済み |
0 |
特に初心者が詰まるのは、「保存した空文字が既定値に戻らない」ことと、「|| や ?: で 0 を既定値に置き換えてしまう」ことです。
手順(サンプルコード)
「存在しない」と「空」を区別したい場合は、センチネル(目印)値を使います。
// 1) 存在しないときだけ既定値
$limit = get_option( 'myplug_limit', 10 );
// 2) 空文字・0 も「未設定」とみなして既定値にしたい(0 を許可しない場合)
$limit = (int) get_option( 'myplug_limit', 10 );
if ( $limit <= 0 ) {
$limit = 10;
}
// 3) 0 や false も有効な値として扱いたい → 存在確認にセンチネルを使う
$raw = get_option( 'myplug_flag', '__none__' );
if ( '__none__' === $raw ) {
// まだ一度も保存されていない
}
設定の既定値を複数箇所に書くと、ズレます。register_setting() の default か、既定値を返す専用の関数にまとめます。
function myplug_get_options() {
$defaults = array( 'title' => '', 'count' => 10 );
return wp_parse_args( (array) get_option( 'myplug_opts', array() ), $defaults );
}
動作確認(検証環境と結果)
WordPress 7.1.2(ja)、PHP 8.2.12。php run.php get-option-default.php で確認しました(テスト用のオプションは最後に削除)。
missing, default 'x': string(1) "x"
missing, no default: bool(false)
stored '', default 'x': string(0) ""
stored false, default 'x': bool(false)
stored 0 -> int(0)
?: with 0 -> int(5)
stored true -> bool(true)
missing -> uses sentinel: bool(true)
- 存在しないオプションは、既定値
'x'が返りました。 - 空文字
''をadd_option()で保存した場合は、既定値を渡しても''が返りました。 add_option( 't_false', false )の後、既定値'x'を渡してもbool(false)が返りました(既定値は使われません)。0を保存した場合はint(0)が返りますが、?:で受けると5に化けました。- 保存したばかりの値の型は、保存時の型のままでした。ただし、別のリクエストでDBから読むと、数値や真偽値は文字列で返る場合があります(レビュー時に別々の実行で確認したところ、
0を保存→次のリクエストでstring(1) "0"、trueを保存→string(1) "1"でした)。このため(int)や(bool)の変換をしてから使います。
get_option の既定値が効かない原因の注意点
- 公式は、オプションを初期化せずに
falseを戻り値として使うのは悪い実践としています。未設定のたびにDBアクセスが発生することがあるためです。有効化時にadd_option()で初期値を入れておく方法が安定します。 - 保存した直後と別リクエストで型が変わりうるため、
===による比較には注意が必要です。 pre_option_{$option}フィルターで値を差し替えられるため、他のプラグインが影響している可能性があります。- 配列は、一部のキーだけが欠けることがあります。
wp_parse_args()で既定値とマージします。
get_option の既定値が効かない原因でよくあるミス
get_option( 'x', 'default' )と書いて、空欄で保存したのに既定値に戻らないと悩む。if ( ! get_option( 'x' ) )で、0や空文字を「未設定」にしてしまう。- 既定値を、読む箇所ごとに別の値で書いてしまう。
- 文字列の
'0'と整数の0を===で比較して、不一致になる。
get_option の既定値が効かない原因のチェックリスト
- 「存在しない」と「空」を区別する必要があるか決めたか。
- 既定値の定義は、1箇所にまとまっているか。
- 数値・真偽値は、読んだ後に型変換しているか。
- 有効化時に、初期値を
add_option()で入れているか。
get_option の既定値が効かない原因のFAQ(よくある質問)
Q. get_option が毎回DBを読むのは遅くないですか?
A. 自動読み込み(autoload)されるオプションは、起動時にまとめて取得されキャッシュされます。サイズの大きな値は autoload を false にします。
Q. get_option と get_site_option の違いは?
A. 後者はマルチサイトのネットワーク全体の設定です(get_site_option() の使い方|説明・引数・注意点)。
Q. 既定値を変えたら、既存のサイトにも反映されますか?
A. 保存済みの値には反映されません。保存されていないサイトだけが新しい既定値になります。
筆者の見解(get_option の既定値が効かない原因)
get_option() の既定値は、「未設定」と「空」を混ぜない設計をする、という前提で使う関数だと考えます。使う側で毎回既定値を書くより、1つの取得関数に包んでしまう方が、後から既定値を変えるときも楽です。
get_option の既定値が効かない原因の関連項目
- get_option() の使い方|説明・引数・注意点
- update_option() の使い方|説明・引数・注意点
- add_option() の使い方|説明・引数・注意点
- delete_option() の使い方|説明・引数・注意点
- get_site_option() の使い方|説明・引数・注意点
