admin-post.php vs admin-ajax.php
Glossary overview

admin-post.php vs admin-ajax.php

В WordPress есть два встроенных способа отправки серверных запросов: admin-post.php и admin-ajax.php. Они похожи, но служат разным целям.

Вот подробное сравнение:

Критерийadmin-post.phpadmin-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.phpadmin-ajax.php
ВызовЧерез HTML-форму (обычный POST)Через JS (AJAX, fetch, jQuery, и т.д.)
ОтветHTML или файл (CSV, редирект)JSON, текст, HTML (без перезагрузки)
Пример использованияЭкспорт, форма обратной связиКнопка “лайк”, авто-поиск, живые фильтры