doing_it_wrong_trigger_errorхук-фильтрWP 3.1.0

Позволяет прерывать генерацию ошибки при вызове _doing_it_wrong().

Используется для контроля и обработки ситуаций, когда вызывается функция или используется функционал, который считается устаревшим или неправильно используемым.

Позволяет:

  • Отслеживать ошибки:
    Если функция вызывается некорректно или если используется устаревший метод, WordPress через функцию _doing_it_wrong() запускает этот хук. Это помогает разработчикам обнаруживать потенциальные ошибки и улучшать код.

  • Логировать ошибки:
    Хук можно использовать для записи этих ошибок в файл логов, базу данных или другой источник. Это особенно полезно на этапе разработки и тестирования.

  • Изменять поведение:
    Разработчики могут изменить поведение по умолчанию при обнаружении ошибок или устаревшего функционала. Например, можно вместо генерации ошибки показывать уведомление в административной панели или отправлять уведомление разработчику.

Как это работает?

Работает только при включенной опции (константе) WP_DEBUG.

При вызове функции _doing_it_wrong() проверяется, нужно ли генерировать ошибку. За эту проверку отвечает этот хук:

  • Если хук вернет true, то будет сформировано сообщение об ошибке и вызовется функция wp_trigger_error(), которая по умолчанию вызовет стандартную PHP функцию trigger_error().

  • Если хук вернет false, то WP не будет никак обрабатывать такой тип ошибки.

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

add_filter( 'doing_it_wrong_trigger_error', 'wp_kama_doing_it_wrong_trigger_error_filter', 10, 4 );

/**
 * Function for `doing_it_wrong_trigger_error` filter-hook.
 * 
 * @param bool   $trigger       Whether to trigger the error for _doing_it_wrong() calls.
 * @param string $function_name The function that was called.
 * @param string $message       A message explaining what has been done incorrectly.
 * @param string $version       The version of WordPress where the message was added.
 *
 * @return bool
 */
function wp_kama_doing_it_wrong_trigger_error_filter( $trigger, $function_name, $message, $version ){

	// filter...
	return $trigger;
}
$trigger(true|false)
Генерировать ошибку (true) или нет (false).
По умолчанию: true
$function_name(строка)
Функция, которая была вызвана.
$message(строка)
Сообщение, объясняющее, что было сделано неправильно.
$version(строка)
Версия WordPress, в которой было добавлено это сообщение.

Примеры

1

#1 Простой пример использования

// Отключаем дефолтный обработчик ошибок
add_filter( 'doing_it_wrong_trigger_error', '__return_false' );
// Логируем сообщение по-своему
add_action( 'doing_it_wrong_run', function ( $function, $message, $version ) {
	error_log( "Функция: $function — Ошибка: $message (с версии: $version)" );
} );

Или тоже самое поведение с использование только фильтра:

add_filter( 'doing_it_wrong_trigger_error', function ( $trigger, $function, $message, $version ) {
	// Логируем сообщение вместо вывода ошибки
	error_log( "Функция: $function — Ошибка: $message (с версии: $version)" );

	return false; // Отключаем стандартное поведение trigger_error
}, 10, 4 );

Когда это может быть полезно:

  • В процессе миграции на новую версию WordPress, чтобы отслеживать использование устаревших функций.
  • При разработке сложных плагинов или тем, где важно соблюдать современные стандарты.
  • Для настройки централизованного логирования всех нарушений правил кода.

Использование этого хука позволяет сделать код более устойчивым и соответствующим лучшим практикам WordPress.

0

#2 Подавление notice функции load_textdomain_just_in_time()

Если вам надоели ошибки подобной этой?

PHP Notice:  Function _load_textdomain_just_in_time was called <strong>incorrectly</strong>. 
Translation loading for the <code>sg-cachepress</code> domain was triggered too early. 
This is usually an indicator for some code in the plugin or theme running too early. 
Translations should be loaded at the <code>init</code> action or later. 
Please see <a href="https://developer.wordpress.org/advanced-administration/debug/debug-wordpress/">Debugging in WordPress</a> for more information. 
(This message was added in version 6.7.0.) in G:\server\www\site.loc\wp-includes\functions.php on line 6114

Этот код подавит подобные notice у функции _load_textdomain_just_in_time()

add_filter( 'doing_it_wrong_trigger_error', function ( $bool, $function_name ) {
	if ( '_load_textdomain_just_in_time' === $function_name ) {
		return false;
	}

	return $bool;
}, 10, 2 );
0

#3 Найдем из какого места в коде была вызвана функция _doing_it_wrong()

К сожалению, по логам (см. Отладка в Wordpress) от _doing_it_wrong() не ясно, в каком месте была сгенерирована ошибка, например:

[05-Dec-2022 15:34:53 UTC] PHP Notice:  Функция WP_Scripts::localize вызвана неправильно.
Параметр $l10n должен быть массивом. Для передачи произвольных данных в скрипты используйте
функцию wp_add_inline_script(). Дополнительную информацию можно найти на странице
<a href="https://ru.wordpress.org/support/article/debugging-in-wordpress/">Отладка в WordPress</a>.
(Это сообщение было добавлено в версии 5.7.0.) in F:\server\www\site.edit\wp-includes\functions.php on line 5835

Логирование (дебаг) этой ошибки на первый взгляд непростая задача, потому что по самой ошибке непонятно, что её вызвало.

Чтобы найти место в коде, где появилась ошибка doing_it_wrong, можно использовать такой код:

add_filter( 'doing_it_wrong_trigger_error', 'doing_it_wrong__add_debug_backtrace' );

/**
 * Логирует ошибки от _doing_it_wrong().
 *
 * @param bool $trigger
 *
 * @return bool mixed
 */
function doing_it_wrong__add_debug_backtrace( $trigger ) {
	if ( true === $trigger ) {
		error_log(
			print_r( wp_debug_backtrace_summary( null, null, false ), true )
		);
	}

	return $trigger;
}

Теперь, кроме описания ошибки в логах, мы также увидим весь стек вызовов, который привел к этой ошибке:

[05-Dec-2022 15:34:53 UTC] Array
(
	[0] => doing_it_wrong_trigger_error_logger
	[1] => WP_Hook->apply_filters
	[2] => apply_filters('doing_it_wrong_trigger_error')
	[3] => _doing_it_wrong
	[4] => WP_Scripts->localize
	[5] => wp_localize_script
	[6] => WPML_ST_Theme_Plugin_Localization_Resources->enqueue_scripts
	[7] => WP_Hook->apply_filters
	[8] => WP_Hook->do_action
	[9] => do_action('admin_enqueue_scripts')
	[10] => require_once('wp-admin/admin-header.php')
)

[05-Dec-2022 15:34:53 UTC] PHP Notice:  Функция WP_Scripts::localize вызвана неправильно.
Параметр $l10n должен быть массивом. Для передачи произвольных данных в скрипты используйте
функцию wp_add_inline_script(). Дополнительную информацию можно найти на странице
<a href="https://ru.wordpress.org/support/article/debugging-in-wordpress/">«Отладка в WordPress»</a>.
(Это сообщение было добавлено в версии 5.7.0.) in F:\server\www\site.edit\wp-includes\functions.php on line 5835

Сразу видно в каком классе и его методе что-то не так. С помощью не долгих поисков находим проблемный участок кода:

// ...

wp_enqueue_style(
	'wpml-theme-plugin-localization-scan',
	WPML_ST_URL . '/res/css/theme-plugin-localization/theme-plugin-localization.css',
	array(),
	WPML_ST_VERSION
);

wp_localize_script(
	'wpml-theme-plugin-localization-scan',
	'wpml_groups_to_scan',
	get_option( WPML_ST_Themes_And_Plugins_Updates::WPML_ST_ITEMS_TO_SCAN )
);

wp_enqueue_script(
	'wpml-st-tracking-all-strings-as-english-notice',
	WPML_ST_URL . '/res/js/tracking-all-strings-as-english-notice.js',
	array( 'jquery' ),
	WPML_ST_VERSION
);

// ...

Он находится в файле:

wp-content/plugins/wpml-string-translation/classes/menus/theme-plugin-localization-ui/class-wpml-st-theme-plugin-localization-resources.php

Вы можете скофигурировать wp_debug_backtrace_summary() как-то по-своему. Или можно использовать функции трассировки PHP: debug_print_backtrace() или debug_backtrace().

Можно также добавить дополнительную логику, чтобы не показывать подобную трассировку при каких-либо условиях. Например, не будем генерировать такое в некоторых функциях (методах):

add_filter( 'doing_it_wrong_trigger_error', 'doing_it_wrong__add_debug_backtrace' );

/**
 * Логирует ошибки от _doing_it_wrong().
 *
 * @param bool $trigger
 *
 * @return bool
 */
function doing_it_wrong__add_debug_backtrace( $trigger ) {
	if ( $trigger ) {
		$excludes  = [ 'WPML_ST_Theme_Plugin_Localization_Resources->enqueue_scripts', 'some_other_function' ];
		$backtrace = wp_debug_backtrace_summary( null, null, false );
		$hide      = array_intersect( $excludes, $backtrace );

		if ( $hide ) {
			$trigger = false;
		} else {
			error_log( print_r( $backtrace, true ) );
		}
	}

	return $trigger;
}

Список изменений

С версии 3.1.0 Введена.
С версии 5.1.0 Added the $function_name, $message and $version parameters.

Где вызывается хук

_doing_it_wrong()
doing_it_wrong_trigger_error
wp-includes/functions.php 6023
if ( WP_DEBUG && apply_filters( 'doing_it_wrong_trigger_error', true, $function_name, $message, $version ) ) {

Где используется хук в WordPress

wp-includes/rest-api.php 248
add_filter( 'doing_it_wrong_trigger_error', '__return_false' );