Если вы когда-либо видели, как плагин "работает на вашем компьютере", а затем перестаёт работать, то, вероятно, вы уже видели, как он ломается. после небольшое обновление WordPressВы знаете настоящую проблему: скорее скрытые изменения в поведении, чем видимые новые особенности.
WordPress 6.9.x (а точнее, 6.9.4, стабильная версия которого выйдет в апреле 2026 года) продолжает явную тенденцию в ядре: повышение согласованности API, усиление безопасности и развитие блочного редактора (Gutenberg), которое в конечном итоге затрагивает ваши темы, ваши старые шорткоды и интеграцию с конструкторами страниц.
Что меняется
Изменения, «которые имеют значение» для разработчиков В версии 6.9.x это не какой-то один волшебный API. Это набор точек, которые в совокупности меняют способ предоставления функций: лучшая стандартизация ресурсов (скрипты/стили), повышение безопасности ввода/вывода (очистка/экранирование) и постепенное согласование классических тем с ограничениями редактирования сайта (FSE).
В частности, на сайтах с версией 6.9.x в продакшене я наблюдал три проблемы: некорректно объявленные скрипты (плохая загрузка, отсутствующие зависимости), чрезмерно лояльные REST-эндпоинты (capabilities/nonce) и «сниппеты», унаследованные от старых руководств, которые используют хуки не в то время.
- Ресурсы (JS/CSS): Требования к добавлению зависимостей в очередь (зависимости, стратегия загрузки, версии) стали более строгими. Проблемы типа "работает и без зависимостей" превращаются в периодически возникающие ошибки, особенно в отношении кэширования/конкатенации/минификации.
- REST API / безопасность: больше внимания к permission_callback, nonce-коды и проверки емкости. Сайты с несколькими редакторами (авторами, участниками) первыми оказываются застигнутыми врасплох.
- Темы и блоки: Экосистема все больше ориентируется на шаблоны, совместимые с FSE. Классические темы по-прежнему поддерживаются, но для "традиционных" интеграций (параметры темы, шорткоды макета) требуется отдельный тарифный план.
Для отслеживания изменений в поведении лучшими источниками информации являются основные заметки разработчиков и заявки в службу поддержки:
- Блог разработчиков (официальные заметки для разработчиков)
- Система отслеживания ошибок ядра WordPress (тикеты)
- Репозиторий wordpress-develop на GitHub (запросы на слияние и коммиты)
Методологическое замечание: я не утверждаю, что подверсия ".4" вносит существенные изменения, нарушающие совместимость. На практике такие изменения чаще возникают из-за накопления изменений (6.7 → 6.8 → 6.9) и из-за плагина/темы, основанных на устаревших предположениях. Цель анализа "6.9.4" — предоставить вам полезный обзор современного состояния дел. Maintenantс PHP 8.1+.
Краткое резюме
- В вашем коде должны быть установлены строгие требования к добавлению объектов в очередь. : явные зависимости, условная загрузка, отсутствие скриптов, жестко внедренных в нижний колонтитул.
- REST: permission_callback + nonces Если вы предоставляете доступ к действиям (даже внутренним), они перестают быть «необязательными».
- Зацепы с неудачным выбором момента. (init vs wp_loaded vs enqueue) становятся видимыми ошибками в работе кэша, редактора блоков и некоторых построителей.
- Классические темы: Они остаются жизнеспособными, но вам будет выгодно использовать шаблоны, совместимые с блоками (шаблоны, стили, варианты).
- Divi 5 / Elementor / Avada: Большинство проблем связано с ресурсами и условными операторами (не загружаются везде), а не с HTML.
- Необходимы незамедлительные действия. : быстрый аудит ваших ресурсов + REST-эндпоинты + фрагменты кода из «старых руководств».
До/После в коде
Рассмотрим реальный случай, который я часто устраняю: плагин (или functions.php), который внедряет JS/CSS «как и раньше», а затем в итоге возникают конфликты (jQuery загружается не вовремя, скрипты построителя загружаются позже, минификация переупорядочивает все).
Случай №1: Слишком "свободная" постановка ресурсов в очередь (проблемы с кэшем и сборщиками).
Ранее (частый антипаттерн)
<?php
// Mauvais exemple : injection directe, pas de dépendances, pas de version, pas de condition.
add_action('wp_footer', function () {
?>
<script>
// Code inline difficile à déboguer, souvent cassé par la minification
jQuery(function($){
$('.cta').on('click', function(){ alert('ok'); });
});
</script>
<?php
});
// Mauvais exemple : style chargé partout, même dans l'admin et le builder
add_action('wp_enqueue_scripts', function () {
wp_enqueue_style('mon-style', get_stylesheet_directory_uri() . '/assets/style.css');
});
Что происходит за кулисами: ваш скрипт предполагает наличие jQuery, но вы не указали эту зависимость. При использовании некоторых кэшей порядок загрузки меняется. В Divi/Elementor редактор загружает собственные пакеты и может задерживать выполнение некоторых скриптов. Результат: периодически возникающая ошибка, которую невозможно воспроизвести в реальных условиях.
После (надежный подход WordPress 6.9.4+)
<?php
/**
* Enqueue propre : dépendances, versioning, conditionnel, et inline script attaché au handle.
* Compatible WordPress 6.9.4+ / PHP 8.1+.
*/
add_action('wp_enqueue_scripts', function () {
// Exemple de condition : ne chargez pas sur tout le site si ce n'est utile que sur une page.
if ( ! is_page('contact') ) {
return;
}
$theme_version = wp_get_theme()->get('Version');
// CSS versionné
wp_enqueue_style(
'mon-style',
get_stylesheet_directory_uri() . '/assets/style.css',
array(),
$theme_version
);
// JS externe versionné + dépendances explicites
wp_enqueue_script(
'mon-cta',
get_stylesheet_directory_uri() . '/assets/cta.js',
array('jquery'),
$theme_version,
array(
'in_footer' => true,
)
);
// Inline script attaché au bon handle (évite l'injection "au hasard" dans le footer)
$inline = <<<JS
jQuery(function($){
$('.cta').on('click', function(){
alert('ok');
});
});
JS;
wp_add_inline_script('mon-cta', $inline, 'after');
}, 20);
Ключевые отличия:
- Явные зависимости Больше никаких "работает, пока...".
- Versioning : кэш корректно аннулирован после установки Тема/плагин обновлены.
- Conditionnel : повышение производительности + меньше конфликтов с пакетами сборщика.
- Встроенный в рукоятку : гарантированный порядок и простая отладка.
Случай №2: REST-интерфейс слишком лоялен (что в конечном итоге представляет реальный риск).
Ещё одна классическая ошибка: использование «внутренней» REST-конечной точки для запуска действия (очистка кэша, повторная синхронизация, импорт). Во многих забытых фрагментах кода отсутствует надёжный механизм обратного вызова для разрешений. Это не просто «хорошая практика», это уязвимое место для атаки.
Перед (опасным)
<?php
add_action('rest_api_init', function () {
register_rest_route('monplugin/v1', '/purge', array(
'methods' => 'POST',
'callback' => function () {
// Dangereux : aucune permission, aucune vérification
do_action('monplugin_purge_cache');
return array('ok' => true);
},
));
});
После (разрешения + одноразовый код + стандартизированный ответ)
<?php
add_action('rest_api_init', function () {
register_rest_route('monplugin/v1', '/purge', array(
'methods' => 'POST',
'callback' => 'monplugin_rest_purge_cache',
'permission_callback' => function (WP_REST_Request $request) {
// 1) Capacité : adaptez selon votre besoin (manage_options est volontairement strict).
if ( ! current_user_can('manage_options') ) {
return false;
}
// 2) Nonce REST : attendu via header X-WP-Nonce côté JS.
$nonce = $request->get_header('X-WP-Nonce');
if ( ! $nonce || ! wp_verify_nonce($nonce, 'wp_rest') ) {
return false;
}
return true;
},
));
});
/**
* Callback REST.
*/
function monplugin_rest_purge_cache(WP_REST_Request $request): WP_REST_Response {
do_action('monplugin_purge_cache');
return new WP_REST_Response(
array(
'ok' => true,
'message' => 'Cache purgé.',
),
200
);
}
Ключевые отличия:
- permission_callback Это не украшение: это ваша защита.
- Nonce wp_rest : это необходимо, если вы обращаетесь к конечной точке из административной панели (или защищенного экрана).
- WP_REST_Response Более стабильна для JS-клиентов (код состояния, структура).
Конкретное воздействие
Для блогеров (среднего уровня)
Вы особенно почувствуете это через свои расширения: обновление WordPress до версии 6.9.x + плагин, загружающий скрипты повсюду, может замедлить работу редактора, сломать кнопку или вызвать ошибки в консоли только на определенных страницах.
- Типичный симптом «Работает на странице А, но не на странице Б». Распространенные причины: отсутствие условных операторов, необъявленные зависимости, агрессивное кэширование.
- Ещё один симптом Сборщик загружается, но некоторые модули оказываются пустыми. Часто это связано с конфликтом JavaScript (порядок загрузки, дублирование версий библиотек).
Для разработчиков
Ваша работа смещается в сторону обеспечения надежности: объявляйте, изолируйте, тестируйте. «Быстрые» фрагменты кода по-прежнему возможны, но их необходимо размещать в правильном месте и использовать в качестве хука, с чистыми зависимостями. Я часто сталкивался с ошибками, возникающими из-за кода, скопированного не в тот файл (в functions.php родительской темы вместо дочерней, или в плагин для создания фрагментов кода без контроля версий).
- Существующие плагины Те, кто внедряет JavaScript непосредственно в код или предоставляет доступ к REST-конечным точкам без разрешения, находятся в зоне риска (ошибки + безопасность).
- Классические темы Если вы используете шорткоды макета, конструктор и пользовательский JavaScript, порядок загрузки становится критически важным.
- Темы оформления FSE (темы для блоков) Вы добьетесь единообразия, если переведете часть макета на использование шаблонов/блоков, но вам нужно научиться «думать о шаблонах», а не о «вариантах».
Влияние на Divi 5, Elementor, Avada.
Все три приложения объединяет одно: они загружают много ресурсов, иногда с определенными условиями, и имеют режимы редактирования/предварительного просмотра, которые работают не так, как интерфейс пользователя.
- Дива 5 Остерегайтесь скриптов, загружаемых только на is_admin() (Неудачный тест), потому что в Divi используются гибридные экраны. Лучше тестировать конкретные действия (например, добавление в очередь на выполнение). wp_enqueue_scripts + определение контекста при необходимости) и избегать внедрения JS через wp_footer без ручки.
- Elementor Если вы разрабатываете собственный виджет, загружайте ресурсы только тогда, когда виджет присутствует (или, по крайней мере, на страницах Elementor). Коллизии часто возникают из-за глобального скрипта, загружаемого на весь сайт.
- Авада Fusion Builder имеет собственную экосистему скриптов. Правило то же: явное указание зависимостей + версионирование + избегание повторной загрузки библиотек.
Диагностическая схема (когда «то работает, то ломается»)
| симптом | Причина вероятна | проверка | Решение |
|---|---|---|---|
| На некоторых страницах неактивна кнопка JavaScript. | Скрипт загружается до зависимости (jQuery/Bundle) или не загружается вообще. | В консоли браузера, во вкладке «Сеть», проверьте порядок и наличие файлов. | wp_enqueue_script with dependencies + conditional + wp_add_inline_script |
| REST-функция «Запрещена» после обновления | параметр permission_callback слишком строгий или отсутствует одноразовый код (nonce). | Проверьте запрос (заголовок X-WP-Nonce), проверьте значение current_user_can. | Добавить nonce wp_rest + соответствующую емкость + сообщенияошибка |
| Редактор Elementor/Div работает медленно. | Глобальные активы слишком велики и сосредоточены повсюду. | Профайлер (вкладка «Производительность»), временно отключите соответствующий плагин. | Загружайте только необходимые страницы/контексты. |
| Фрагмент кода "random", который перестаёт работать после обновления. | Неправильный хук (init против wp_loaded), функция вызвана слишком рано | WP_DEBUG_LOG + трассировка стека, проверьте порядок выполнения. | Переместите обработчик, отрегулируйте приоритет и убедитесь, что функция существует. |
| Изменения незаметны, несмотря на развертывание. | Кэш (плагин/CDN/браузер) + версия статических ресурсов | Очистить кэш + проверить версию строки запроса | Версию можно получить с помощью wp_get_theme()->get('Version') или filemtime. |
Риски, совместимость и моменты, требующие особого внимания
Что нового (тренд 6.7 → 6.9.4)
- Требования к чистоте Что касается ресурсов: WordPress и его экосистема (конструкторы сайтов, кэширование, оптимизация) менее терпимы к скриптам, «внедренным» вне рамок процесса.
- Неявное упрочнение То, что раньше происходило «случайно», теперь происходит реже.
- Больше зон отдыха (плагины, блоки, пользовательский интерфейс): поэтому существует больший риск, если ваши права доступа неясны.
Что меняется (и не объявляется "критическим")
- Исполнительный приказ Неправильно выбранные хуки могут привести к ошибкам. Классический пример — слишком ранняя регистрация скриптов (инициализация) и их слишком позднее добавление в очередь, или наоборот.
- Кэширование и минификация При использовании HTTP/2/3 и плагинов для объединения файлов предположения о порядке выполнения скриптов становятся ненадежными.
- Editeurs Административная панель больше не является «отдельным местом». Редактор сайта и конструкторы сайтов напоминают приложения, поэтому ваши глобальные скрипты будут взаимодействовать с ними.
Что потенциально может сломаться
- Код из старого урока : фрагменты кода 2017–2021 годов, которые внедряют встроенный JavaScript, используют приблизительные хуки или реализуют REST без разрешения.
- PHP слишком устарел. Если ваш хостинг-провайдер работает медленно, вы столкнетесь с фатальными ошибками (типизированные свойства, ошибка сопоставления и т. д.). Рекомендуется использовать WordPress 6.9.4 с PHP 8.1+. Проверьте это в вашей рабочей среде.
- Фрагменты кода в родительской теме Обновление темы = потеря кода = «он исчез». Это очень распространенный «инцидент».
График амортизации (прагматичный)
Основной код редко объявляется устаревшим внезапно, без льготного периода. Реальный риск заключается в том, что ваш код полагается на негарантированное поведение (порядок выполнения, неявные зависимости) и в конечном итоге ломается. По умолчанию рассматривайте это как объявление устаревшего.
Моя рекомендация на 2026 год: рассмотрите любой код, в котором ресурсы жестко закодированы (echo). ) comme “à migrer”, même s’il n’y a pas de notice officielle.
Как осуществить миграцию
Шаг 1: Быстрый аудит (30 минут, очень экономично)
- Найдите нужный плагин в разделе "Плагины/Темы":
wp_footer+<script>,echo '<script',admin-ajax.php,register_rest_routeбез обратного вызова разрешения. - Перечислите страницы, где ваши ресурсы действительно необходимы (зачастую это 10–20% сайта).
- Включить логирование в тестовой среде:
WP_DEBUG,WP_DEBUG_LOGИзбегайте выполнения этих действий в производственной среде без надзора (риск утечки информации).
<?php
// wp-config.php (staging uniquement)
define('WP_DEBUG', true);
define('WP_DEBUG_LOG', true);
define('WP_DEBUG_DISPLAY', false); // Évite d'afficher les erreurs aux visiteurs
Шаг 2: Перенесите ресурсы на соответствующие дескрипторы (и остановите несанкционированное внедрение).
Две надежные стратегии версионирования: версионирование темы/плагина (простое) или filemtime() (Точно, но следует остерегаться распределенных финансовых систем).
<?php
add_action('wp_enqueue_scripts', function () {
$file = get_stylesheet_directory() . '/assets/cta.js';
$url = get_stylesheet_directory_uri() . '/assets/cta.js';
// Attention : filemtime() peut être coûteux sur certains hébergements réseau.
$ver = file_exists($file) ? (string) filemtime($file) : wp_get_theme()->get('Version');
wp_enqueue_script(
'mon-cta',
$url,
array('jquery'),
$ver,
array('in_footer' => true)
);
});
Шаг 3: Обеспечьте безопасность REST (возможности + nonce) и задокументируйте её.
Если ваша конечная точка вызывается с фронтенда (посетителями), nonce-кода «wp_rest» не всегда достаточно (и это не общедоступный механизм аутентификации). В этом случае перейдите на токены приложений, подписи или строго ограничьте действия. Не разрешайте анонимный доступ к конечной точке «очистка/импорт».
Шаг 4: Проверьте обработчики событий и приоритеты (источник «призрачных» ошибок).
Реалистичные ошибки, которые я вижу:
- Используйте неправильный крючок : встать в очередь
initвместоwp_enqueue_scripts. - Конфликт приоритетов Ваш код выполняется до запуска построителя/кэша, а затем перезаписывается.
- Функция вызывается перед загрузкой. Вы используете функцию плагина, в то время как плагин еще не инициализировал свои классы.
<?php
// Exemple : si vous dépendez d'un plugin, évitez d'appeler ses classes trop tôt.
add_action('plugins_loaded', function () {
if ( ! class_exists('MaLib\Client') ) {
// Le plugin dépendant n'est pas chargé ou pas actif
return;
}
// Initialisation sûre ici
}, 20);
Шаг 5: Контрольный список совместимости (подготовительный этап)
- Обновите WordPress до версии 6.9.4 на тестовой платформе.
- Обновите Divi 5/Elementor/Avada + дополнения.
- Очистите кэш (кэш плагинов, серверный кэш, CDN) и кэш браузера (часто забывается).
- Тест: конструктор страниц в режиме редактирования, внешний интерфейс, мобильное устройство, пользователь без прав администратора.
- Проверьте постоянные ссылки (сохраните заново), если вы изменяете маршруты/правила перезаписи.
Действовать сейчас или подождать?
Действуйте сейчас если вы отметите хотя бы один пункт:
- У вас есть "старые" фрагменты кода (functions.php, плагин для создания фрагментов кода), которые давно не тестировались.
- Вы предоставляете REST-конечные точки или AJAX-запросы типа «admin-ajax» для выполнения конфиденциальных задач.
- Вы используете конструктор (Divi 5/Elementor/Avada) и у вас есть глобальные пользовательские скрипты.
- У вас есть сайт с несколькими ролями (авторы, участники): безопасность и возможности REST становятся обязательными.
Ты можешь подождать (несколько недель) если:
- На вашем сайте нет собственного кода (или он реализован только с помощью проверенных плагинов).
- У вас есть процесс подготовки и ежемесячного обновления.
- Вы не предоставляете доступ к каким-либо пользовательским REST/AJAX-интерфейсам.
По моему опыту, "ожидание" без предварительной подготовки в итоге обходится дороже. Правильный компромисс: регулярные обновления ядра, но целенаправленные проверки областей риска (активы + REST + хуки).
Советы по техническому обслуживанию
1) Стандартизируйте свой метод добавления кода.
- Избегайте вставки фрагментов кода в родительскую тему.
- Для реализации бизнес-логики предпочтительнее использовать мини-плагин для «сайта» (например, mu-plugin).
- Если вы используете плагин для создания фрагментов кода, версионируйте их (копируйте репозиторий в Git): я видел, как фрагменты кода деактивировались после ошибки PHP, и никто не знал, «что изменилось».
2) Минимальный набор тестов, которые необходимо запланировать для каждого обновления WordPress.
- Фронтенд: ключевые страницы, формы, отслеживание.
- Администрирование: редактор блоков, экран конструктора, медиафайлы.
- Роли: тестирование с использованием учетной записи автора (не администратора) для выявления ошибок, связанных с функциональностью.
- Консольный JavaScript: как минимум один быстрый проход (ошибки/предупреждения).
3) Производительность: Меньшая нагрузка, но лучшее качество.
- Уточните параметры ваших ресурсов (страница, тип контента, наличие шорткода/блока).
- Удалите библиотеки, которые загружаются дважды (часто это происходит при использовании плагинов для конструкторов и маркетинга).
- Правильно версионируйте, чтобы избежать «закрепленных патчей».
4) Безопасность: REST/AJAX и одноразовые коды (nonce).
- Каждое действие, которое что-либо изменяет, должно быть проверено. возможности + нунций.
- Не доверяйте параметрам на стороне клиента. Систематически проверяйте и очищайте их.
Полезный справочник по PHP: Хэширование паролей в PHP (если вы работаете с токенами) а со стороны WordPress — функции безопасности, перечисленные в руководстве.
Ресурсы
- Блог разработчиков (заметки для разработчиков WordPress)
- Ссылка на функцию wp_enqueue_script()
- Ссылка на функцию wp_add_inline_script()
- Справочник по REST API
- Ссылка на register_rest_route()
- Core Trac (система отслеживания изменений)
- GitHub wordpress-develop (PR/commits)
- Документация WordPress (для пользователей и разработчиков)
- Примечания к выпуску PHP 8.1
FAQ
1) Я скопировал фрагмент кода и получаю ошибку 500. Что мне делать в первую очередь?
Отключите фрагмент кода (или переименуйте файл, если вы используете его в плагине), затем посмотрите wp-content/debug.log При постановке сцен. Наиболее частой ошибкой остается отсутствие точки с запятой или неправильно закрытая фигурная скобка.
2) Куда размещать пользовательский код в 2026 году: functions.php, plugin, mu-plugin?
Для "бизнес-кода" (CTA, REST, внутреннее отслеживание) я рекомендую небольшой специализированный плагин. functions.php Это приемлемо в эстетических целях, но при смене тем вы рискуете потерять код.
3) Мой JavaScript работает на фронтенде, но не в Elementor/Divi. Почему?
Потому что редактор — это не фронтенд. Конструкторы загружают разные пакеты, иногда внутри iframe. Загружайте свои скрипты через wp_enqueue_scriptОбъявляйте зависимости и избегайте чрезмерно глобальных селекторов.
4) Нужно ли мне по-прежнему использовать jQuery?
Если ваш сайт (или ваш конструктор) уже зависит от него, то да, но объявите эту зависимость. Если вы создаёте новый модуль, используйте современный JavaScript без зависимостей и загружайте его условно.
5) Почему мой REST-эндпоинт возвращает ошибку 403, несмотря на то, что я являюсь администратором?
Часто потому что нунций wp_rest не отправляется (заголовок) X-WP-Nonce), или потому что вы тестируете из неаутентифицированного контекста (приватная вкладка, другой домен, кэш). Проверьте запрос на вкладке «Сеть».
6) Какой кэш нужно очистить после изменения скрипта?
Как минимум: кэш плагина (если есть) + кэш сервера/CDN + кэш браузера. Если версия ваших ресурсов не меняется, браузер сохранит старую копию, даже если вы "очистили кэш WordPress".
7) Мой код не запускается, но ошибок я не вижу.
Вероятно, вы выбрали не тот крюк, или же ваше состояние не соответствует действительности. is_page() / is_admin() Это не соответствует контексту. Добавьте временный лог (на тестовой площадке) и проверьте приоритет хука.
8) Действия против фильтров: могут ли они действительно навредить веб-сайту?
Да. Я видел, как разработчики это использовали. add_filter При использовании хука, который не присваивает значение и "ждёт возвращаемого значения", ничего не происходит. И наоборот, возврат значения при выполнении действия бессмысленен. Проверьте документацию по соответствующему хуку.
9) Требуется ли для WordPress 6.9.4 PHP 8.1?
WordPress по-прежнему прагматично относится к вопросам совместимости, но в 2026 году... Рекомендуемый минимальный уровень программирования — PHP 8.1 и выше. Для обеспечения стабильности и безопасности. Многие современные плагины уже предполагают использование версии 8.1.
10) Я изменил некоторые маршруты/постоянные ссылки, и теперь получаю ошибки 404.
Сохраните постоянные ссылки заново (Настройки → Постоянные ссылки → Сохранить) и проверьте правила перезаписи. Это очень распространенная ошибка, которую допускают после миграции или добавления типов записей.