Запрос формы $_POST с admin-post
Я попытался использовать форму со следующей разметкой, используя действие admin-post.php
<form method='post' action='admin-post.php'>
Я использую хук действия рекомендованный WordPress для обработки параметров $_POST, и это работает нормально. Однако после выполнения я получаю пустую страницу без перенаправления обратно на страницу плагинов. Конечно, я мог бы установить пользовательское перенаправление с помощью referer, но является ли это нормальным поведением?
Обходное решение - использовать action=""
и получать запрос в моем обычном коде плагина.

Возможно, немного поздно, но я наткнулся на это, когда у меня были проблемы с пониманием, поэтому решил поделиться своими находками для будущих читателей.
Я обнаружил, что основные принципы заключаются в том, чтобы иметь скрытое поле ввода с именем action
и его значением в виде пользовательского идентификатора. Например:
<input name='action' type="hidden" value='custom_form_submit'>
С этим полем ввода и указанием admin-post.php
в атрибуте action
формы можно установить действие. Мы задаем это действие с помощью admin_post_custom_form_submit
.
Чтобы усложнить, мы можем использовать wp_nonce_field
, который, как я понимаю, является базовой мерой безопасности. По сути, он добавляет случайное значение в $_POST. Логично.
Далее мы хотим установить наше действие следующим образом:
add_action('admin_post_custom_form_submit','our_custom_form_function');
Таким образом, когда форма отправляется на admin-post.php
и содержит значение action custom_form_submit
, будет вызвана функция our_custom_form_function
! :D
function our_custom_form_function(){
//print_r($_POST);
//здесь вы можете получить доступ к значениям $_POST, $GET и $_REQUEST
wp_redirect(admin_url('admin.php?page=your_custom_page_where_form_is'));
//по завершении, судя по всему, требуется die();
}
Теперь вы говорите, что получаете белую страницу. Это потому, что нам нужно перенаправить обратно на нашу форму. Я использовал простой wp_redirect()
.
Надеюсь, это помогло :) Я попробую разобраться, как можно добавить валидацию и вернуть ошибки на нашу форму редиректа. Думаю, самый простой вариант — использовать значение $_GET
и найти его на нашей странице, но это не идеально, правда?
Я также обнаружил, что после отправки $_POST
очищается!! DX Вероятно, это связано с редиректом. Я поищу в Google и посмотрю, что смогу найти :d
Надеюсь, это помогло :)
ОБНОВЛЕНИЕ
Я продолжил работу и понял, что единственный реальный способ вернуть значения — использовать переменную $_GET. Таким образом, вы можете повторно ввести любые POST-значения. Только не забудьте использовать urlencode()
, чтобы специальные символы, такие как '@' и другие, были учтены.
У меня было больше одной страницы в моей работе, поэтому я сделал два разных редиректа на разные страницы и включил ошибки и прочее. Затем проверил их перед формой.
Еще одна полезная функция: http_build_query()
может преобразовывать массивы в 'безопасные для URL' строки, чтобы их можно было передавать через $_GET-запросы и т.д.

Привет, брат, спасибо, это работает для меня..!
Но есть одна проблема: как я могу установить ошибку на странице admin.php?page=your_custom_page_where_form_is
?
Я использовал add_settings_error()
для отображения ошибки, но она не отображается, потому что страница перенаправляется..!
Можешь, пожалуйста, помочь с этим..?
Спасибо

Привет @BhavikHirani, я больше не использую WordPress, но, думаю, тебе нужно выполнить валидацию до вызова функции wp_redirect и добавить условие if, чтобы проверить, прошла ли валидация, перед перенаправлением. Надеюсь, это поможет?

После отправки формы я хочу показать сообщение об успехе на странице 'admin.php?page=your_custom_page_where_form_is'. Как это возможно?

У каждого метода есть свои сценарии использования. Этот метод передает данные в URL через $_GET
. Это подходит для базовой информации, например, для отображения имени или email пользователя, или для передачи флага ?success=true
, который запускает сообщение об успехе. Однако он не подойдет для возврата больших объемов данных после отправки формы, например, если пользователь отправляет форму и ожидает получить данные из API.

Перед перенаправлением вы можете сохранить любые ошибки валидации и значения полей в transient. Эти значения сохранятся после перенаправления URL.
Именно так ядро WordPress делает это для Settings API при возврате ошибок.
Итак:
- проверить данные формы
- сохранить данные формы в transient с помощью set_transient()
- сохранить любые ошибки в transient
- перенаправить на страницу с формой
- проверить наличие ошибок в transient
- загрузить сохраненные значения полей формы из transient
Вместо transient вы могли бы использовать сессии или Options API.
Я экспериментировал с различными способами обработки отправки форм как на фронтенде, так и в админке. Не уверен, что admin_post_{action} настолько удобен, из-за необходимости сохранять данные и ошибки после перенаправления. Использование хуков init или admin_init для проверки отправки формы может быть проще. Также вы можете просто отправить форму обратно на ту же страницу и обработать данные до отображения формы.

Примечание: set_transient()
имеет максимальную длину 172 символа. Это разумный вариант, если вы не используете или не можете использовать GET-переменные, и если данных не слишком много. Насколько мне известно, WordPress по умолчанию не использует сессии, поэтому для плагина это может быть неподходящим решением. Options API был бы ужасным выбором. -- Последний вариант, если вам нужно обращаться к API и возвращать большое количество данных, это отправка POST-запроса на сам сайт/страницу. -- admin-post.php
имеет ограничения и, вероятно, не подходит, если вам нужно вернуть большой объем данных.

Короткий ответ: вам нужно выполнить всю работу самостоятельно: сохранить пользовательские данные в базе данных, проверить наличие ошибок или успешное выполнение, и перенаправить пользователя куда угодно по завершении.
Если вы хотите перенаправить обратно на форму, вы можете использовать поле, сгенерированное функцией wp_nonce()
, которое включено в массив $_POST
, отправляемый вашей формой: $_POST['_wp_http_referer']
В завершение вы можете выполнить перенаправление и отправить сообщение об успехе или ошибке, используя функции wp_safe_redirect()
, esc_url_raw()
и add_query_arg()
.
add_action( 'admin_post_my-action', 'my_save_form_function' );
add_action( 'admin_post_nopriv_my-action', 'my_save_form_function' );
function my_save_form_function() {
if ( ! empty( $_POST['_wp_http_referer'] ) ) {
$form_url = esc_url_raw( wp_unslash( $_POST['_wp_http_referer'] ) );
} else {
$form_url = home_url( '/' );
}
if ( isset( $_POST['name'] )
&& isset( $_POST['description'] )
&& isset( $_POST['my-nonce'] )
&& wp_verify_nonce(
sanitize_text_field( wp_unslash( $_POST['my-nonce'] ) ),
'my-action'
)
) {
// Сохраняем данные формы...
// Всё прошло успешно?
wp_safe_redirect(
esc_url_raw(
add_query_arg( 'my_status', 'success', $form_url )
)
);
exit();
} else {
wp_safe_redirect(
esc_url_raw(
add_query_arg( 'my_status', 'error', $form_url )
)
);
exit();
}
}
