Zeus and WordPress Part 2: Fixing Query Strings

If you’re trying to get WordPress working on a Zeus Web server, and you’ve gotten as far as using a good rewrite script to make permalinks work properly, you might have noticed that query strings don’t work at the ends of your permalinks. At first, it seemed like this wouldn’t be too big of an issue; it just meant that users wouldn’t be able to preview posts/pages, and there would be one or two other issues they’d have to live with. However, after using the site that way for a little while, we started coming across more and more issues that this caused, and it finally reached a tipping point.

To solve the issue, I wrote a simple function that runs any time a 404 error occurs on the site. Essentially, it parses the path of the requested page, cuts off the query string temporarily, and then searches the database for a post or page that has the slug at the end of the path.

You may be wondering why I didn’t just parse the request/get variables sent with the page. The problem is, those were empty in each of the cases I tested.

Anyway, following is the function I ended up writing.

function zeus_reply_fix() {
	if ( ! isset( $_SERVER['PATH_INFO'] ) ) {
		return;
	}
	if ( ! is_404() ) {
		return;
	}

	$path = $_SERVER['PATH_INFO'];
	$parts = explode( '/', $path );
	$qs = array_pop( $parts );
	$parsed = array();
	if ( strstr( $qs, '&' ) || strstr( $qs, '?' ) ) {
		parse_str( $qs, $parsed );
	} else {
		return;
	}
	if ( is_array( $parsed ) ) {
		global $wpdb, $post, $wp_query;
		$post_ID = $wpdb->get_var( $wpdb->prepare( "SELECT ID FROM {$wpdb->posts} WHERE post_name=%s", array_pop( $parts ) ) );

		if ( empty( $post_ID ) ) {
			return;
		}

		$wp_query = new WP_Query( array( 'page_id' => $post_ID ) );
		$wp_query->is_404 = false;
		foreach ( $parsed as $k=>$v ) {
			if ( ! empty( $k ) && ! empty( $v ) )
				set_query_var( $k, $v );
		}

		$_GET = $_GET + $parsed;

		$use_template = 'index.php';
		$post = $wp_query->get_queried_object();

		load_template( trailingslashit( get_template_directory() ) . $use_template );
		die();
	}
}
add_action( 'wp', 'zeus_reply_fix', 99 );

Have you found a better way of dealing with this issue? Do you see anything that could be done better? I’d love to see other solutions to this particular problem with Zeus & WordPress.

3 Responses

  • John

    Hi Curtiss!

    Terrific post! Thanks.

    Am a little confused as to where or how to go about deploying the function you’ve described above? Any guidance you might be able to provide would be much appreciated.

    Thanks,
    John

  • In my case, I was using a custom theme for this site, so I simply added that code into the theme’s functions.php file.

    If you are using WordPress as a single installation (not multisite), or if you are using WordPress Multisite (not even sure that’s possible on Zeus) and want to implement this on all sites in the network, you could also put that code into its own PHP file, then upload that file to wp-content/mu-plugins (if the mu-plugins directory doesn’t exist, you can create it).

    If you’re running WordPress Multisite, and you only want to make this change on a single site, you’ll have to turn it into a custom plugin that can be activated only on that site.

  • You mentioned in part 1 of ‘Zeus and WordPress’ that you recommend Apache over Zeus. I think people really need to know that they ARE asking for problems by using WordPress on Zeus. There are so many good hosts using Apache that there really doesn’t seem like a good reason for people to use WordPress on Zeus.
    People avoid using Zeus to host your WordPress!