PHPUnit via WP-CLI: Warning: Cannot modify header information … bootstrap.php:68

wordpress.stackexchange https://wordpress.stackexchange.com/questions/274810

  •  23-02-2021
  •  | 
  •  

سؤال

I'm trying to setup unit tests for a plugin I am developing. I just followed the steps at... https://make.wordpress.org/cli/handbook/plugin-unit-tests/

However, when I run phpunit I get the following...

$ phpunit
Installing...
Running as single site... To run multisite, use -c tests/phpunit/multisite.xml

Warning: Cannot modify header information - headers already sent by (output started at /private/tmp/wordpress-tests-lib/includes/bootstrap.php:68) in /Users/<USERNAME>/Sites/<MYSITE.COM>/wp-load.php on line 64

I am running...

  • Mac OS 10.12.6
  • PHP v5.6.30
  • PHPUnit 4.8.36
  • MAMP Pro 4.2

The error noted, bootstrap.php:68 which is the start of the program outputting the "Installing..." text from the output noted above. Line 68 reads...

system( WP_PHP_BINARY . ' ' . escapeshellarg( dirname( __FILE__ ) . '/install.php' ) . ' ' . escapeshellarg( $config_file_path ) . ' ' . $multisite );  
هل كانت مفيدة؟

المحلول

The error is telling you that the code tried to output a HTTP response header with the header() function after the response body has already begun to be sent. As you noted, line 68 of bootstrap.php is calling that script that outputs Installing.... So after that output has already been sent, you can't send a response header.

The next step to debug this is to find out why a response header is being sent. That isn't supposed to be happening, because here we are running the tests from the command line, we're not actually sending a page to the browser.

So, we need to see where header() is being called. The error tells you that it is in wp-load.php on line 64:

    header( 'Location: ' . $path );

This line itself doesn't tell us much, but we find that it is within a big if ... else statement:

/*
 * If wp-config.php exists in the WordPress root, or if it exists in the root and wp-settings.php
 * doesn't, load wp-config.php. The secondary check for wp-settings.php has the added benefit
 * of avoiding cases where the current directory is a nested installation, e.g. / is WordPress(a)
 * and /blog/ is WordPress(b).
 *
 * If neither set of conditions is true, initiate loading the setup process.
 */
if ( file_exists( ABSPATH . 'wp-config.php') ) {

    /** The config file resides in ABSPATH */
    require_once( ABSPATH . 'wp-config.php' );

} elseif ( @file_exists( dirname( ABSPATH ) . '/wp-config.php' ) && ! @file_exists( dirname( ABSPATH ) . '/wp-settings.php' ) ) {

    /** The config file resides one level above ABSPATH but is not part of another install */
    require_once( dirname( ABSPATH ) . '/wp-config.php' );

} else {

    // snip

    header( 'Location: ' . $path );

    // snip

}

Essentially what this tells us is that wp-load.php is looking for the wp-config.php file, and isn't finding it. So it is initiating the set-up process, and as part of that it is trying to redirect to the installation page by sending the Location header.

So you apparently have not set up your wp-config.php file correctly.

The wp-config.php file was supposed to be set up by the script you ran though, so this is likely an indicator that something failed. In fact, since we are running the tests here, the wp-tests-config.php file is expected to be used instead. So the next step is figuring out why wp-tests-config.php isn't being loaded. You should be able to find that file in the /tmp/wordpress-tests-lib/ directory.

نصائح أخرى

That problem sounds like your code is sending text/characters to the screen, then it sends out a page 'header' (the <head> part of an HTML page). PHP doesn't like that; once you put any characters on the screen, you can't send out page headers (the <head> part).

Sometimes it is as simple as a space character in front of the <?php code. Check for that, or any other text sent out before the page header.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى wordpress.stackexchange
scroll top