表題のように、自作プラグインを有効化して設定画面を設定画面を開いたら、ログに以下のような警告が記録されていました。
PHP Warning: Illegal offset type in isset or empty in /PATH/TO/WORDPRESS/wp-includes/taxonomy.php on line 290
これが設定画面を1度開くごとに4行ずつ増えていく、と。
この警告メッセージは連想配列のキーに「配列」を指定すると発生するとのことです。この時点ではまだ原因は特定できず。
ちなみに、自作プラグインの設定画面では各投稿タイプごとのタクソノミーが階層構造にしているかどうかを判定するようになっています。
<?php
$postTypes = get_post_types( [], 'objects' );
foreach ( $postTypes as $postType ) {
//各投稿タイプに紐付けられているタクソノミーを取得
$termsObjs = get_object_taxonomies( $postType->name, 'objects' );
foreach ( $termsObjs as $termsObj ) {
//階層構造になっているか、`the_posts`の`category`であるかのどちらかならば`if`内の処理を実行
if( is_taxonomy_hierarchical( $termsObj ) || $termsObj->name === 'category' ) {
?>
<!-- 略 -->
<?php
}
}
}
?>
こんなイメージです。
これに対して、wp-includes/taxonomy.php
の290行目はどうなっているのかというと関数taxonomy_exists
で引数を$taxonomy
として、isset( $wp_taxonomies[ $taxonomy ] );
でオブジェクトの有無を判定しています。
この関数taxonomy_exists
は同ファイルの中でそこそこ使われていて、その中に関数is_taxonomy_hierarchical
があります。
is_taxonomy_hierarchical
は上述のコードの中で使用していますね。
そこでis_taxonomy_hierarchical
の詳細をCodexで確認します。
引数の$taxonomy
はタクソノミーオブジェクトの名前、つまり文字列で指定とあります。
……あ、オブジェクトを渡している。ということで以下のように改修。
<?php
$postTypes = get_post_types( [], 'objects' );
foreach ( $postTypes as $postType ) {
//各投稿タイプに紐付けられているタクソノミーを取得
$termsObjs = get_object_taxonomies( $postType->name, 'objects' );
$termsObjsNames = get_object_taxonomies( $postType->name, 'names' );
foreach ( $termsObjs as $termsObj ) {
//階層構造になっているか、`the_posts`の`category`であるかのどちらかならば`if`内の処理を実行
if( is_taxonomy_hierarchical( $termsObjsNames ) || $termsObj->name === 'category' ) {
?>
しかし警告は消えず。おかしいな、と思いつつ今度はタクソノミーを取得する関数get_object_taxonomies
を確認します。
上記からは例えば次のような出力が得られます:
Array
(
[0] => category
[1] => post_tag
[2] => post_format
)
何……だと……。
言われてみれば確かにそうですが、第一引数の投稿タイプに紐付いたタクソノミーは複数あるので、名前の一覧……つまり、配列になるわけですね。
これだと、is_taxonomy_hierarchical
に配列が渡ってしまうので警告は変わらず記録されるわけです。
そこで、最終的には以下のようになりました。
<?php
$postTypes = get_post_types( [], 'objects' );
foreach ( $postTypes as $postType ) {
//各投稿タイプに紐付けられているタクソノミーを取得
$termsObjs = get_object_taxonomies( $postType->name, 'objects' );
foreach ( $termsObjs as $termsObj ) {
//階層構造になっているか、`the_posts`の`category`であるかのどちらかならば`if`内の処理を実行
if( is_taxonomy_hierarchical( $termsObj->name ) || $termsObj->name === 'category' ) {
?>
これで警告は記録されなくなりました。
分かってしまえば何てことはないのですが、少し躓いたのでメモしておきます。