WP_DEBUG_BACKTRACE_SUMMARY(): Полное руководство исполь��ования

## WP_DEBUG_BACKTRACE_SUMMARY() │ WP 3.4.0

Эта функция возвращает строку, содержащую список функций, которые были вызваны до текущей точки в коде, разделённый запятыми.

- **1 раз** — 0.000001 сек (скорость света) 
- **50000 раз** — 0.23 сек (очень быстро) 
- PHP 7.1.11, WP 4.9.8

### Возвращаемое значение

Функция может вернуть:
- **Строку** — это строка, содержащая список вызовов, разделённых запятыми, записанных в обратном порядке.
- **Массив** — массив отдельных вызовов.

### Использование

```php
wp_debug_backtrace_summary( $ignore_class, $skip_frames, $pretty );

Параметры

  • $ignore_class (строка) — класс, вызовы функций внутри которого нужно игнорировать. Полезно, если вы хотите получить информацию только о вызывающей функции.
    • По умолчанию: null.
  • $skip_frames (число) — количество кадров стека, которые нужно пропустить. Полезно для отката к источнику проблемы.
  • $pretty (true|false) — если вы хотите получить строку, разделенную запятыми, вместо сырого массива.
    • По умолчанию: true.

Примеры

Пример 1: Демо вывода функции

Подключитесь к хуку pre_get_posts и посмотрите, что возвращает wp_debug_backtrace_summary() с разными параметрами:

add_filter( 'pre_get_posts', 'my_function' );

function my_function() {
    $backtrace = wp_debug_backtrace_summary();
    /*
    Это пример вывода:
    require('/sites/test.ru/wp-blog-header.php'), wp, WP->main, WP->query_posts, WP_Query->query,
    WP_Query->get_posts, do_action_ref_array, WP_Hook->do_action, WP_Hook->apply_filters, my_function
    */

    // Убираем методы класса 'WP_Hook'
    $backtrace = wp_debug_backtrace_summary( 'WP_Hook' );
    /*
    require('/sites/test.ru/wp-blog-header.php'), wp, WP->main, WP->query_posts, WP_Query->query,
    WP_Query->get_posts, do_action_ref_array, my_function
    */

    // Убираем последние 5 элементов
    // Параметр $ignore_class не учитывается при подсчете элементов.
    $backtrace = wp_debug_backtrace_summary( 'WP_Hook', 5 );
    //>  require('/sites/test.ru/wp-blog-header.php'), wp, WP->main, WP->query_posts, WP_Query->query

    // Получаем м��ссив
    $backtrace = wp_debug_backtrace_summary( 'WP_Hook', 5, false );
    /*
    Array(
        [0] => WP_Query->query
        [1] => WP->query_posts
        [2] => WP->main
        [3] => wp
        [4] => require('/sites/test.ru/wp-blog-header.php')
    )
    */
}

Пример 2: Изменение формата времени в виджете «Недавние записи»

К сожалению, в виджете «Недавние записи» нет специальных хуков для изменения формата отображения даты и времени, но мы можем использовать следующий трюк:

add_filter( 'pre_option_date_format', function ( $pre_option ) {
    $backtrace = wp_debug_backtrace_summary( null, 0, false );

    if ( in_array( 'WP_Widget_Recent_Posts->widget', $backtrace ) ) {
        return 'G:i'; // формат времени
    }

    return $pre_option;
} );

Пример 3: Добавление цепочки вызовов в лог

Допустим, нам нужно добавить сообщение об ошибке в наш лог. В этом случае удобно иметь стек вызовов функций/методов, которые привели к ошибке, вместе с сообщением об ошибке:

function some_function() {
    // некоторый код, где может возникнуть ошибка

    if ( is_wp_error() ) {
        $logger->error( 'Сообщение об ошибке.', [ 'backtrace' => wp_debug_backtrace_summary() ] );
        return;
    }

    // выполнение других задач
}

Заметки

  • Функция была добавлена в версии 3.4.0.

Код функции

Функция wp_debug_backtrace_summary реализована в файле wp-includes/functions.php:

function wp_debug_backtrace_summary( $ignore_class = null, $skip_frames = 0, $pretty = true ) {
    static $truncate_paths;

    $trace       = debug_backtrace( false );
    $caller      = array();
    $check_class = ! is_null( $ignore_class );
    ++$skip_frames; // Пропустим эту функцию.

    if ( ! isset( $truncate_paths ) ) {
        $truncate_paths = array(
            wp_normalize_path( WP_CONTENT_DIR ),
            wp_normalize_path( ABSPATH ),
        );
    }

    foreach ( $trace as $call ) {
        if ( $skip_frames > 0 ) {
            --$skip_frames;
        } elseif ( isset( $call['class'] ) ) {
            if ( $check_class && $ignore_class === $call['class'] ) {
                continue; // Фильтруем вызовы.
            }

            $caller[] = "{$call['class']}{$call['type']}{$call['function']}";
        } else {
            if ( in_array( $call['function'], array( 'do_action', 'apply_filters', 'do_action_ref_array', 'apply_filters_ref_array' ), true ) ) {
                $caller[] = "{$call['function']}('{$call['args'][0]}')";
            } elseif ( in_array( $call['function'], array( 'include', 'include_once', 'require', 'require_once' ), true ) ) {
                $filename = isset( $call['args'][0] ) ? $call['args'][0] : '';
                $caller[] = $call['function'] . "('" . str_replace( $truncate_paths, '', wp_normalize_path( $filename ) ) . "')";
            } else {
                $caller[] = $call['function'];
            }
        }
    }
    if ( $pretty ) {
        return implode( ', ', array_reverse( $caller ) );
    } else {
        return $caller;
    }
}

Связанные функции

DEBUG

  • _doing_it_wrong()
  • get_num_queries()
  • wp_debug_mode()
  • wp_get_development_mode()
  • wp_get_environment_type()
  • wp_is_development_mode()

Leave a Reply

Ваш адрес email не будет опубликован. Обязательные поля помечены *