Запрос формы $_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() для отображения ошибки, но она не отображается, потому что страница перенаправляется..!
Можешь, пожалуйста, помочь с этим..?
Спасибо
Bhavik Hirani
Привет @BhavikHirani, я больше не использую WordPress, но, думаю, тебе нужно выполнить валидацию до вызова функции wp_redirect и добавить условие if, чтобы проверить, прошла ли валидация, перед перенаправлением. Надеюсь, это поможет?
bashleigh
После отправки формы я хочу показать сообщение об успехе на странице 'admin.php?page=your_custom_page_where_form_is'. Как это возможно?
Rijo
У каждого метода есть свои сценарии использования. Этот метод передает данные в URL через $_GET. Это подходит для базовой информации, например, для отображения имени или email пользователя, или для передачи флага ?success=true, который запускает сообщение об успехе. Однако он не подойдет для возврата больших объемов данных после отправки формы, например, если пользователь отправляет форму и ожидает получить данные из API.
CyberPunkCodes
Перед перенаправлением вы можете сохранить любые ошибки валидации и значения полей в 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 имеет ограничения и, вероятно, не подходит, если вам нужно вернуть большой объем данных.
CyberPunkCodes
Короткий ответ: вам нужно выполнить всю работу самостоятельно: сохранить пользовательские данные в базе данных, проверить наличие ошибок или успешное выполнение, и перенаправить пользователя куда угодно по завершении.
Если вы хотите перенаправить обратно на форму, вы можете использовать поле, сгенерированное функцией 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();
}
}