読者です 読者をやめる 読者になる 読者になる

ITの隊長のブログ

ITの隊長のブログです。PythonとRを使って仕事しています。最近は機械学習をさわりはじめたお(^ω^ = ^ω^)

【WordPress】「 Warning: Missing argument 3 for _post_format_get_terms()」とか「Warning: strpos() expects parameter 1 to be string, array given in」のエラー

スポンサードリンク

WordPress4.2ぐらいのバージョンで発生した事件です。

WordPressはエラーを画面に表示することは設定を変更すればいけます。んで、本番では発生していないように見えて、デバッグ設定が入っている開発環境でエラーが発覚するということは多々ありました。今回もそんな類のやつでした。

Warning: Missing argument 3 for _post_format_get_terms() xxx in plugins.php: 213

まずひとつ。

WordPressを利用している日本ユーザーは多いほうだと思うので、だいたいググったらわかりますが、こういうのは長期戦となります。

まず、エラーを読んでみると引数の3つ目がありません。とのエラーです。ということは何か関数の使い方が間違っているのでは?と推測できます。

しかし、そのような箇所は見当たりませんでした。

ソースの変更をgitで管理しているのならラッキーです。一旦過去のコミットに戻って、このような症状が発生しているか確認してみましょう。

過去を見てもだめでした。おお。なんということでしょう。リリースしたときから発生していたようです。。。困った。

最終手段で一番最初からやるべきこととしては、「処理を追って、コードを読むこと」です。コードを読み慣れている人は最初からやったほうが原因がつかみやすいと思います。(めんどくさいからあんまやりたくないけど)

PHPの場合だとスタックトレースが表示されるので、どのファイルのphpのどのメソッドへ飛んだかというのが書いてありますので、それを追ってコードを読んでみました。

すると、今回の原因はここで発生しているようです。

  • ~/wp-includes/plugins.php
<?php

// ...
    do {
        foreach( (array) current($wp_filter[$tag]) as $the_ )
            if ( !is_null($the_['function']) ){
                $args[1] = $value;
                $value = call_user_func_array($the_['function'], array_slice($args, 1, (int) $the_['accepted_args']));
            }

    } while ( next($wp_filter[$tag]) !== false );

209行目あたりにあるこのdo whileループの中に、call_user_func_arrayという関数があります。これで_post_format_get_terms()を呼んでいるようですが、呼ぶときに3つ目の引数が必要なのに、うまく渡せていないようです。

で、エラー箇所から順序よくエラーを確認した結果、カスタムタクソノミーのslug名がtermsという名前だったのが原因でした。WordPressの予約言語ようなこのtermsをカスタムタクソノミーで利用すると、WordPressのデフォルトの処理と勘違いしてしまい、他の名前で登録したカスタムタクソノミーが入るはずのない処理に取り込まれて動作してしまいました。使い方のミスですね。

ここからわかったことで、次のアクションとしては、既存のタクソノミー名を変更してあげれば良いということです。

ただ、注意点としては、カスタムタクソノミーの名前を変更するのはDBから変更して上げなければいけません。

下記URLを参考にしました。

WordPressテーマの作り方 » タクソノミーの名前を変更する

これでエラーが無くなりました。( ´ー`)フゥー...

「Warning: strpos() expects parameter 1 to be string, array given in」とか色々諸々のエラー

Warning: strpos() expects parameter 1 to be string, array given in

Warning: preg_split() expects parameter 2 to be string, array given in

Warning: Invalid argument supplied for foreach() in

わー、エラーがいっぱい。

これはエラーを見る限り、「stringを入れるところに、arrayが入っている」だったり、「foreachへの引数がない」のようなエラーですね。

上で対処したことを参考に、今回もソースを読むことを先にしました。

  • wp-includes/query.php
<?php
// ...
               if ( strpos($term, '+') !== false ) {
                    $terms = preg_split( '/[+]+/', $term );
                    foreach ( $terms as $term ) {
                        $tax_query[] = array_merge( $tax_query_defaults, array(
                            'terms' => array( $term )
                        ) );
                    }
                } else {
                    $tax_query[] = array_merge( $tax_query_defaults, array(
                        'terms' => preg_split( '/[,]+/', $term )
                    ) );
                }

1871行目あたりにこのコードがあります。ちょうど、strpos()のほうでエラーが発生しているようですね。

このコードを囲む関数はparse_tax_query()という関数です。調べてみると。「カンマ区切りのtaxonomyをパースして、検索するパラメータにしてくれる」ような関数なようです。

ちょっとこの件はややこしかったです。ちゃんと理解できたわけではありませんが、どうやら原因としては、「拡張した検索のクエリパラメータで、カスタムタクソノミー名と同じkeyを利用すると、不可解な動きをする」ということがわかりました。

どゆことかというと、発生している箇所がWordPressの検索を拡張したphpのところでした。通常検索する場合はs=という値をクエリパラメータにセットすれば、WordPressはそのリクエストを検索と認識し動作するようになります。

んで、それに乗っかるように、自分で作成したPHPを書きました。単純にフォームにカスタムタクソノミーの一覧を表示して、nameをslugにする。そして、それをgetでリクエストして、検索側でquery_posts()へ値をセットして、検索する。という流れです。

この時、nameをslugにするにすると、keyがslug名となります。これがダメなようですね。

これをやってしまうと、何故か画面いっぱいにエラーが発生します。。。疲れたよ。

解決としては、クエリパラメータに利用するkeyの名前をslug名以外にすればおkです。php内部ではslug名を指定してあげなければ、検索はできませんが、くクエリパラメータ上では違う名前にするって話ですね。

んー。でも経験としては、過去このように組んだサイトって結構あったような気がしていて、そのときはそんなエラーは発生しなかった覚えがあります。バージョンのせいなのかな?

よくわかっていませんが、とりあえず2日ぐらい悩ませたエラーは修正できたので良しとします。