I’ve been working on building a web application in WordPress on which I’m implementing a set of rewrite rules to introduce RESTful routing into the application.

Once the application is done, I hope to provide a significantly more in-depth post on how I built it, but in the mean time I figured I’d cover how I’m handling certain challenges that I’ve faced in development.

In this case, I needed to fire a call to wp_redirect after a certain event happened, but kept getting the PHP error:

Cannot modify header information - headers already sent by (output started ... )

Here’s how I ended up resolving the wp_redirect headers already sent message.

A Word About Routes

This is an oversimplification of what I’m doing, but I essentially have various models in the application. In this case, I was working with a person model.

Through my rewrite rules, I can perform the following actions:

  • person/all lists all the people
  • person/add adds a new person to the application
  • person/update/1 where 1 is the ID of the user)
  • person/delete/1 where 1 is the ID of the user and asks the user to confirm deletion
  • person/destroy/1 where 1 is the ID of the user and where the user is actually removed from the database

For anyone coming from a Rails or RESTful background, this should be familiar; otherwise, it should be clear enough.

The Problem of Destroy

So the general flow of control of control is like this:

  • The user selects the person they want to delete
  • They are directed to the delete action where they are prompted to confirm or cancel the action
  • If they confirm, they are directed to the destroy action
  • When a success destroy occurs (that is, the user is successfully deleted), they should be be redirected back to the person/all view.

Everything was good except once the destroy action completed, I was seeing the usual PHP header message:

Cannot modify header information - headers already sent by (output started ... )

The problem is the page is beginning to render text and then my call to wp_redirect was attempting to load another page prior to finishing the initial page’s load.

This isn’t good.

Of Redirects and Output Buffers

To fix the problem of being unable to redirect until a page has actually loaded, I added a hook on the init action that will actually buffer output using ob_start.

This will allow for a redirect to occur before the initial page has finished loading.

The output buffer function looks like this:

function app_output_buffer() {
	ob_start();
} // soi_output_buffer
add_action('init', 'app_output_buffer');

And the function for destroying the person looks like this (which is called in the context of the person’s destroy view – or page, in WordPress terms).

function app_destroy_person( $person_id ) {

	// Include the necessary library to delete a person
	include_once( 'wp-admin/includes/user.php' );
	wp_delete_user( $person_id );

	// Redirect back to the Person listing
	wp_redirect( app_get_permalink_by_slug( 'all', 'person' ) );
	exit;

} // end app_destroy_person

As always, there may be a better way. If you know of one, then please share it in the comments.