В WordPress есть два встроенных способа отправки серверных запросов: admin-post.php и admin-ajax.php. Они похожи, но служат разным целям.
Вот подробное сравнение:
| Критерий | admin-post.php | admin-ajax.php |
|---|---|---|
| 🔧 Назначение | Обработка форм и действий в админке | Обработка AJAX-запросов (JS ↔ PHP) |
| 📥 Как вызывается | Через form action="/wp-admin/admin-post.php" | Через JS-функции (fetch, jQuery.ajax, XMLHttpRequest) |
| 📄 Возвращает HTML | ✅ Да (по умолчанию — страница) | ❌ Нет (возвращает JSON, текст, и т.д.) |
| 🚀 Асинхронность | ❌ Нет (обычный POST/GET-запрос) | ✅ Да (асинхронный вызов из JS) |
| 📡 Подходит для | Файлов, CSV-экспорта, редиректов | AJAX в админке или на фронте |
🔒 Для гостей (nopriv) | admin_post_nopriv_{action} | wp_ajax_nopriv_{action} |
| 🧠 Хуки | admin_post_{action} | wp_ajax_{action} |
| 📍 URL вызова | /wp-admin/admin-post.php | /wp-admin/admin-ajax.php |
Пример: admin-post.php — форма и редирект
🔧 Цель:
Пользователь заполняет форму, и при сабмите мы сохраняем сообщение и редиректим назад с уведомлением.
PHP (в functions.php или плагине):
// Обработка формы (только для залогиненных пользователей)
add_action('admin_post_submit_feedback', function () {
if (!current_user_can('manage_options')) {
wp_die('Access denied');
}
$message = sanitize_text_field($_POST['feedback'] ?? '');
// Можно сохранить в БД, отправить email и т.п.
error_log("Feedback: $message");
// Редирект обратно с сообщением
wp_redirect(admin_url('tools.php?page=feedback&sent=1'));
exit;
});
📄 HTML (в админке или кастомной странице):
<form method="post" action="<?php echo admin_url('admin-post.php'); ?>">
<input type="hidden" name="action" value="submit_feedback">
<textarea name="feedback" placeholder="Your feedback..."></textarea>
<button type="submit">Send</button>
</form>
<?php if ($_GET['sent'] ?? '' == '1') : ?>
<div class="notice notice-success"><p>Feedback sent!</p></div>
<?php endif; ?>
Если ты используешь admin-post.php, то без скрытого поля action он просто не поймёт, что запускать.
Внутри admin-post.php WordPress делает очень простую вещь: берёт $_REQUEST['action']. Если его нет – он не знает, какой хук вызывать. А вся магия завязана именно на этом имени.
<input type="hidden" name="action" value="submit_feedback">
Связка строится строго по строке add_post.
add_action('admin_post_submit_feedback', function () { ...
Пример: admin-ajax.php — AJAX-запрос без перезагрузки
🔧 Цель:
Скрипт на странице делает запрос и получает JSON с текущим временем.
📄 PHP:
add_action('wp_ajax_get_server_time', function () {
echo json_encode([
'success' => true,
'time' => current_time('mysql')
]);
wp_die(); // важно!
});
JS (на фронте или в админке):
<button id="load-time">Get Server Time</button>
<div id="time-result"></div>
<script>
document.getElementById('load-time').onclick = function () {
fetch('/wp-admin/admin-ajax.php?action=get_server_time')
.then(res => res.json())
.then(data => {
document.getElementById('time-result').innerText = "Time: " + data.time;
});
};
</script>
Разница по сути:
admin-post.php | admin-ajax.php | |
|---|---|---|
| Вызов | Через HTML-форму (обычный POST) | Через JS (AJAX, fetch, jQuery, и т.д.) |
| Ответ | HTML или файл (CSV, редирект) | JSON, текст, HTML (без перезагрузки) |
| Пример использования | Экспорт, форма обратной связи | Кнопка “лайк”, авто-поиск, живые фильтры |