WordPress插件中$_POST始终为空的问题排查与操作咨询
Hey there! Let's break down your problem step by step and fix those $_POST-related issues with your WordPress plugin settings page.
The core issue here is how WordPress handles settings form submissions. When you submit your form to options.php, WordPress does three key things:
- Validates and saves your setting
- Redirects you back to your settings page using a GET request
- Clears the original POST data in the process
By the time your my_script_form() function runs, the page has already redirected—so $_POST is empty because you're now on a fresh GET request, not the original POST submission.
You need to catch the POST data before WordPress redirects. Here are two reliable ways:
1. Use the sanitization callback for register_setting
Add a sanitization function to your register_setting call—this runs during the POST processing, so you can inspect the data here:
add_action('admin_init', 'my_script_admin_settings'); function my_script_admin_settings(){ // Add a sanitization callback to catch POST data register_setting('my_script_group', 'my_script_option', 'my_script_sanitize_input'); } function my_script_sanitize_input($input) { // View raw POST data (this will show up in your PHP error log or on the screen if you enable debug) var_dump($_POST); // Or log it to avoid breaking the redirect error_log(print_r($_POST, true)); // Always return the input (sanitize it here if needed!) return $input; }
2. Temporarily test with the current page as form action
For quick testing, change your form's action to point directly to your settings page instead of options.php:
<form action="<?php echo admin_url('admin.php?page=my_script'); ?>" method="post">
This skips the WordPress redirect, so $_POST will be visible in my_script_form(). Just remember to switch back to options.php afterward—using WordPress's official settings endpoint ensures proper security and validation.
Instead of checking $_POST directly in your form function, use WordPress's built-in hooks to run code after the setting is saved:
Option 1: Use the updated_option hook
This triggers only when your specific option is updated, making it clean and reliable:
add_action('updated_option', 'my_script_after_save', 10, 3); function my_script_after_save($option_name, $old_value, $new_value) { // Only run for our option if ($option_name === 'my_script_option') { // Add your custom logic here—e.g., log changes, trigger an API call, etc. error_log("Script settings updated! Old value: " . print_r($old_value, true)); error_log("New value: " . print_r($new_value, true)); } }
Option 2: Check for submission in admin_init
You can also detect the POST request directly in your admin_init function before the redirect happens:
add_action('admin_init', 'my_script_admin_settings'); function my_script_admin_settings(){ register_setting('my_script_group', 'my_script_option'); // Check if this is a valid submission for our settings group if (isset($_POST['option_page']) && $_POST['option_page'] === 'my_script_group' && isset($_POST['action']) && $_POST['action'] === 'update') { // Run your custom actions here error_log("Form submitted successfully!"); } }
- Use
esc_textarea()instead ofesc_attr()for your textarea content—it's the proper WordPress function for escaping multi-line text:<textarea name="my_script_option[my_script_id]" rows="3" cols="100"><?php echo esc_textarea( $options['my_script_id'] ); ?></textarea> - Set a default value for your option to avoid PHP warnings if the option hasn't been saved yet:
$options = get_option('my_script_option', array('my_script_id' => ''));
内容的提问来源于stack exchange,提问作者Tautve

