BETA

WordPressの自作プラグインで警告`Illegal offset type in isset or empty`が記録される

投稿日:2020-03-27
最終更新:2020-03-27

表題のように、自作プラグインを有効化して設定画面を設定画面を開いたら、ログに以下のような警告が記録されていました。

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' ) {  
?>  

これで警告は記録されなくなりました。

分かってしまえば何てことはないのですが、少し躓いたのでメモしておきます。

参考

技術ブログをはじめよう Qrunch(クランチ)は、プログラマの技術アプトプットに特化したブログサービスです
駆け出しエンジニアからエキスパートまで全ての方々のアウトプットを歓迎しております!
or 外部アカウントで 登録 / ログイン する
クランチについてもっと詳しく

この記事が掲載されているブログ

アルム=バンドのQrunch

よく一緒に読まれる記事

0件のコメント

ブログ開設 or ログイン してコメントを送ってみよう