In general, the code from this question fit to me for 90%. One little change I need - I want all URL like example.com/snpv/any_text/ direct not to index.php as in original code, but to my.php script in root of my THEME (not site!). So, I correct the code for my needs:

register_activation_hook(__FILE__, 'make_flush_rules');
function make_flush_rules()
    add_rewrite_rule('snpv/([^/]+)', '/wp-content/themes/lightsaber/my.php?prm1=$matches[1]', 'top');

add_filter('query_vars', 'make_query_vars');
function make_query_vars($query_vars)
    $query_vars[] = 'prm1';
    return $query_vars;

To make picture clear:

  • lightsaber-my Theme
  • my.php-just independent script. It is not page (or, to be precise, not WP page) or page template, just php-code to generate some output

I create this plugin and activate it. Enter URL example.com/snpv/ABC/ and get 404 page. :( How to correct problem? Thanks!

  • you can't direct rewrite rules to other scripts, everything should still be directed to index.php, but you should also set up a hook early in the request to check if your special query var has been set and execute your code then.
    – Milo
    Commented Dec 17, 2011 at 15:24
  • Thanks a lot for you answer! I understand - straight redirect to my.php is impossible. :( Can you tell, please, the name of hook (filter?) you mention above?
    – Smarty
    Commented Dec 18, 2011 at 6:58
  • see answer with the code.
    – Milo
    Commented Dec 18, 2011 at 19:21

1 Answer 1


Here's an example with template_redirect that loads your php script if the prm1 query var is set:

// set up the rewrite
add_action( 'init', 'wpse36736_setup_rewrites' );
function wpse36736_setup_rewrites(){
    add_rewrite_rule( 'snpv/([^/]+)', 'index.php?prm1=$matches[1]', 'top' );

// add query var
add_filter('query_vars', 'wpse36736_query_vars');
function wpse36736_query_vars( $query_vars ){
    $query_vars[] = 'prm1';
    return $query_vars;

// check the query var on template_redirect
add_filter( 'template_redirect', 'wpse36736_template_redirect' );
function wpse36736_template_redirect(){
    global $wp_query;
    if( $wp_query->get( 'prm1' ) ):
        include( get_template_directory() . "/prm1.php" );

You can then access prm1 in your script via:

$prm1 = get_query_var( 'prm1' );

The only strange thing about this is the way WordPress interprets this query, the behavior in 3.3 seems to be a bit different than with previous versions. If you inspect the global $wp_query variable set for any of these requests, everything is populated as if it's the main posts page and is_404 is false. I recall this wasn't the case back when I tried to help out on this question.

Anyway, what I typically do in this situation is create a page, say snpv, and change the rewrite rule to 'index.php?pagename=snpv&prm1=$matches[1]'.

  • Is it necessary to use index.php, register a query var, add a condition and finally call the exit function? The author of the question is trying to use an independent php script directly. How can we get that working?
    – JCarlosR
    Commented Jun 19, 2020 at 23:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.