admin管理员组

文章数量:1134248

I need to refresh my screen after curl has run but I get "headers already sent" error.

This is my code which is a plugin.

function fs_settings_admin_callback(){

    if ($_POST['generate']){
        $url = '';
  
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($curl, CURLOPT_HEADER, false);

        $ret = curl_exec($curl);
        $result = json_decode($ret,true);
  
 
        $httpcode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
        curl_close($curl);
         // ob_end_clean() ;
          //ob_end_flush() ;
          //ob_flush();
        header("Refresh:0");
    }
}


function fs_add_submenu_page(){
    
    add_submenu_page(
         $parent_slug = 'edit.php?post_type=my_custom_post_type',
         $page_title = 'Settings', 
         $menu_title = 'Settings', 
         $capability = 'manage_options', 
         $menu_slug = 'fs_settings', 
         $callback = 'fs_settings_admin_callback', 
         $position = null 
    );    
}  

I understand that probably I need to use output buffering but I cannot figure out how. If I use ob_end_clean or others the screen will refresh but then is blank and would like to continue to see my form from initial submit.

I need to refresh my screen after curl has run but I get "headers already sent" error.

This is my code which is a plugin.

function fs_settings_admin_callback(){

    if ($_POST['generate']){
        $url = 'https://www.example.com/api/fs/v1/endpoint';
  
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($curl, CURLOPT_HEADER, false);

        $ret = curl_exec($curl);
        $result = json_decode($ret,true);
  
 
        $httpcode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
        curl_close($curl);
         // ob_end_clean() ;
          //ob_end_flush() ;
          //ob_flush();
        header("Refresh:0");
    }
}


function fs_add_submenu_page(){
    
    add_submenu_page(
         $parent_slug = 'edit.php?post_type=my_custom_post_type',
         $page_title = 'Settings', 
         $menu_title = 'Settings', 
         $capability = 'manage_options', 
         $menu_slug = 'fs_settings', 
         $callback = 'fs_settings_admin_callback', 
         $position = null 
    );    
}  

I understand that probably I need to use output buffering but I cannot figure out how. If I use ob_end_clean or others the screen will refresh but then is blank and would like to continue to see my form from initial submit.

Share Improve this question edited Aug 13, 2023 at 2:31 spreaderman asked Aug 13, 2023 at 1:57 spreadermanspreaderman 1138 bronze badges 2
  • How/when/where are you running that code? Is that inside of a hook? Are you making a remote request to a custom REST API endpoint? – Sally CJ Commented Aug 13, 2023 at 2:23
  • 1 I have added additional info to the original post to who how/when/where. – spreaderman Commented Aug 13, 2023 at 2:32
Add a comment  | 

1 Answer 1

Reset to default 1

No, you should not use output buffering, and instead, you just need to use the right hook to refresh the page — the one that you've used runs after the headers and content are already sent to the browser, hence it's not the right hook or that it should only be used to output the content for your custom admin menu page.

The hook that you should use is load-<page hook>, where <page hook> is the return value of add_submenu_page() which is a hook suffix like my_custom_post_type_page_fs_settings in your case.

So for example:

  • In the fs_settings_admin_callback function:

    $hook_suffix = add_submenu_page(
        'edit.php?post_type=my_custom_post_type',
        your code here
    );
    
    add_action( "load-$hook_suffix", 'fs_settings_maybe_generate' );
    
  • Then do the refresh in the callback specified above:

    function fs_settings_maybe_generate() {
        if ( ! empty( $_POST['generate'] ) ) {
            // your code here
    
            header( 'Refresh: 0' );
            exit;
        }
    }
    

Another hook which you can use/try is admin_post_<action> where <action> would be the value of a hidden input named action in your form. However, we won't be using the Refresh header, but instead, do a redirect to the form page.

  • Sample form:

    <form method="post" action="admin-post.php">
        <p>
            <input type="checkbox" name="generate" id="fs-generate" />
            <label for="fs-generate">Generate</label>
        </p>
    
        <input type="hidden" name="action" value="generate" />
        <?php wp_nonce_field( 'fs-generate' ); ?>
    
        <?php submit_button(); ?>
    </form>
    
  • Now handle the form submissions:

    add_action( 'admin_post_generate', 'fs_admin_post_generate' );
    function fs_admin_post_generate() {
        check_admin_referer( 'fs-generate' );
    
        if ( ! empty( $_POST['generate'] ) ) {
            // your code here
        }
    
        // Always redirect back.
        wp_redirect( wp_get_referer() );
        exit;
    }
    

See https://developer.wordpress.org/apis/security/ for details on adding an nonce field and other security measures.

Additionally, you should also utilize the WordPress's HTTP API for making HTTP/remote/external requests, e.g. wp_remote_get():

function fs_settings_maybe_generate() {
    if ( ! empty( $_POST['generate'] ) ) {
        $response = wp_remote_get( 'https://www.example.com/api/fs/v1/endpoint' );
        $body = wp_remote_retrieve_body( $response );
        // Do something with $body, if you want to.

        header( 'Refresh: 0' );
        exit;
    }
}

本文标签: pluginsWordpress 63 headers already sent error