1

The error that I have is a very common error. Yet I saw that the error message is different per person. The message I am getting is:

array(4) { ["type"]=> int(2) ["message"]=> string(171) "Cannot modify header information - headers already sent by (output started at /home/radioprog/domains/radioprogrammabank.nl/public_html/wp/wp-includes/formatting.php:5688)" ["file"]=> string(145) "/home/radioprog/domains/radioprogrammabank.nl/public_html/wp/wp-content/plugins/insert-php-code-snippet/shortcode-handler.php(65) : eval()'d code" ["line"]=> int(61) }

When I change themes (twenty nineteen), the error does not go away. It simply changes to:

array(4) { ["type"]=> int(2) ["message"]=> string(175) "Cannot modify header information - headers already sent by (output started at /home/radioprog/domains/radioprogrammabank.nl/public_html/wp/wp-includes/class.wp-styles.php:287)" ["file"]=> string(145) "/home/radioprog/domains/radioprogrammabank.nl/public_html/wp/wp-content/plugins/insert-php-code-snippet/shortcode-handler.php(65) : eval()'d code" ["line"]=> int(61) } upload is gelukt

I tried to go to the formatting.php and changing what was wrong, but it did not solve my problems.

I have a header() function that needs to redirect people to another page. When I var_dump it. The first error is shown. I want the error to go away so that I can redirect visitors to a different page using the header() function

shortcode-handler.php (line 55 - 75):

    }
    $content_to_eval='?>'.$content_to_eval;
}

/***** to handle old codes : end *****/
else{
    if(substr(trim($content_to_eval), 0,5)=='<?php')
        $content_to_eval='?>'.$content_to_eval;
}

                        eval($content_to_eval);
                        $xyz_em_content = ob_get_contents();
                       // ob_clean();
                        ob_end_clean();
                         return $xyz_em_content;
                  /*  }
                    else{
                        eval($sippetdetails->content);
                    }*/
                }
                else{
  • Welcome to WordPress Stack Exchange! The error is on line 65 in the file insert-php-code-snippet/shortcode-handler.php, not in formatting.php. Please add the lines 55–75 of that file to your question. – fuxia Mar 4 '20 at 13:28
  • Hi @fuxia, I have added line 55-75 to my question – user183467 Mar 4 '20 at 13:36
  • Looks like the $content_to_eval contains a header() function. That cannot happen in a shortcode callback, because shortcodes are rendered long after HTTP headers and some HTML have been sent. You have to separate the redirect from the shortcode callback. And please, never use eval(). – fuxia Mar 4 '20 at 13:46
  • I have not written this code, it is a plugin. The plugin is called insert-PHP-code snippet. It allows me to write PHP code. What do you mean with separate? I am afraid that if I change this the plugin will not work and my PHP will not work. How would you rewrite this code? – user183467 Mar 4 '20 at 13:51
  • @fuxia please read my comment above – user183467 Mar 4 '20 at 14:11
2

The basic problem you have is that you want to send a redirect header, and that redirection code is executed too late, namely in your shortcode handler. You can send HTTP headers only before any output has been sent, not later.

So what you have to do, generally speaking, is separating the shortcode logic from the redirection logic.

Here is a very simple example, illustrating the general approach. Not tested!

class ShortcodeRedirect
{
    private $identifier = 'wpse359995';

    public function form( $atts, $content ='' )
    {
        return '<form method="post" accept-charset="utf-8">' .
        $content
        '<input type="hidden" name="key" value="' . $this->identifier . '">
        <input type="text">
        <input type="submit">
        </form>';
    }

    public function redirect()
    {
        if ( 'POST' !== $_SERVER['REQUEST_METHOD'] )
            return;

        $key = filter_input( INPUT_POST, 'key', FILTER_SANITIZE_STRING );

        if ( ! $key or ( $key !== $this->identifier ) )
            return;

        $text = filter_input( INPUT_POST, 'text', FILTER_SANITIZE_STRING );

        if ( ! $text )
            return;

        wp_redirect( 'your_target_url' );
        exit;
    }
}

if ( ! is_admin() ) {
    $shortcoderedirect = new ShortcodeRedirect;

    add_shortcode( 'form', [ $shortcoderedirect, 'form' ] );
    add_action( 'template_redirect', [ $shortcoderedirect, 'redirect' ] );
}

As you can see, the shortcode callback doesn't know anything about the HTTP headers, and the redirection callback (template_redirect is the proper hook to do that) doesn't know anything about the shortcode.

The only connection between them is the identifier, a private property of the class, which can't be accessed from the outside.

And if I may say so: Don't use plugins to inject executable PHP code into your posts. This can backfire quite badly if some gets access to the post content somehow, and it's very difficult to debug, as you have experienced already. Try to write your own code, and put that into a proper plugin. You might actually enjoy it. :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy