web-dev-qa-db-ja.com

class-wp-query.phpのコア関数is_page()&is_singularで通知警告をトレースする方法

私は本番サイトでこれらでオーバーランしています:

PHP Notice:  Trying to get property of non-object in /public_html/wp-includes/class-wp-query.php on line 3728
PHP Notice:  Trying to get property of non-object in /public_html/wp-includes/class-wp-query.php on line 3730
PHP Notice:  Trying to get property of non-object in /public_html/wp-includes/class-wp-query.php on line 3732
PHP Notice:  Trying to get property of non-object in /public_html/wp-includes/class-wp-query.php on line 3863

上記の行は、is_page()およびis_singular()関数にあります。

これらの関数がどこで間違って使用されているのかわかりません。イライラするのは、ステージングサイト(本番サーバーと同じサーバー)またはローカルホストでこれらを再現できないことです。また、すべてのプラグインを簡単に無効にしたり、テーマを切り替えたりすることはできません。何百人ものユーザーがサインインし、何千人ものユーザーがサインインしていないためです。

リポジトリでis_page()およびis_singular()のインスタンスを検索し、それらが正しく呼び出されていることを確認しようとしました。明らかに私は失敗しました。

これらのPHP通知をトリッピングしているものを把握するにはどうすればよいですか?

記録のために、質問を送信する前に、ポップアップした「類似の質問」を参照しました。

1
Max

独自のカスタムエラーハンドラを作成し、エラーログにスタックトレースを追加できます。

set_error_handler('wpse_288408_handle_error');

function wpse_288408_handle_error( $errno, $errstr, $errfile, $errline ) {

    if( $errno === E_USER_NOTICE ) {

        $message = 'You have an error notice: "%s" in file "%s" at line: "%s".' ;
        $message = sprintf($message, $errstr, $errfile, $errline);

        error_log($message);
        error_log(wpse_288408_generate_stack_trace());
    }
}
// Function from php.net http://php.net/manual/en/function.debug-backtrace.php#112238
function wpse_288408_generate_stack_trace() {

    $e = new \Exception();

    $trace = explode( "\n" , $e->getTraceAsString() );

    // reverse array to make steps line up chronologically

    $trace = array_reverse($trace);

    array_shift($trace); // remove {main}
    array_pop($trace); // remove call to this method

    $length = count($trace);
    $result = array();

    for ($i = 0; $i < $length; $i++) {
        $result[] = ($i + 1)  . ')' . substr($trace[$i], strpos($trace[$i], ' ')); // replace '#someNum' with '$i)', set the right ordering
    }

    $result = implode("\n", $result);
    $result = "\n" . $result . "\n";

    return $result;
}

コードのどこかにtrigger_errorを追加することで、これが機能しているかどうかを確認できます。

trigger_error('Annoying notice');

エラーログは次のようなものを出力するはずです:

2017/01/02 12:00:00 [error] 999#999: *999 FastCGI sent in stderr: "PHP message: You have an error notice: "Annoying notice" in file "/var/www/test/wp-content/plugins/test/test.php" at line: "99".
PHP message:
1) /var/www/test/index.php(17): require('/var/www/test/w...')
2) /var/www/test/wp-blog-header.php(13): require_once('/var/www/test/w...')
3) /var/www/test/wp-load.php(37): require_once('/var/www/test/w...')
4) /var/www/test/wp-config.php(93): require_once('/var/www/test/w...')
5) /var/www/test/wp-settings.php(305): include_once('/var/www/test/w...')
6) /var/www/test/wp-content/plugins/test/test.php(99): trigger_error('Annoying notice')
7) [internal function]: wpse_288408_handle_error(1024, 'Annoying notice', '/var/www/test/w...', 99, Array)" while reading response header from upstream, client: 192.168.33.1, server: test.dev, request: "GET / HTTP/1.1", upstream: "fastcgi://127.0.0.1:9070", Host: "test.dev"

この種のメッセージを使用すると、問題の場所を簡単に見つけることができます。

3
kierzniak

StageとProdは同じサーバー上にあるかもしれませんが、同じバージョンのPHP用に構成されていますか?

Wordpressデバッグプラグインmightは追加情報を提供します。 Query Monitor https://en-gb.wordpress.org/plugins/query-monitor/#description は、PHP Notices and Errorsの呼び出しスタックを提供します。有効化後:管理者ユーザーとして、問題のあるページに移動します。明らかではありませんが、上部のリボンに秒とKBが表示され、これにカーソルを合わせてエラーをクリックします(私は思う)。私のサイト(通知のみ-エラーなし):

Query Monitor ribbon

[エラー]をクリックすると、mightが役立つ呼び出しスタックを含む詳細が表示されます。

PHP 7が問題の場合-WPプラグインディレクトリのどこかに互換性チェッカーがあり、便利かもしれません。誤検出を与えます。プラグインは、PHP 7がサーバーによって使用されていないことを確認した後、廃止された関数のみを使用する場合でも、互換性がないとマークされる場合があります。

1
scytale