I'm trying to add a rewrite rule to Wordpress. I want to rewrite: "http://www.domain.com/plm_check/var_a/var_b/var_c/" to actually use a file from "http://www.domain.com/wp-content/plugins/plm/webservices/plm_check.php?var_a=...&var_b=...&var_c=..."

I've registered it like this:

/* Register rewrites for web service calls */
add_action( 'generate_rewrite_rules' , 'register_plm_rewrites');
function register_plm_rewrites() { //
    global $wp_rewrite; 

    $wp_rewrite->add_external_rule( '^plm_check/([a-zA-z0-9_]+)/([a-zA-z0-9-]+)/([0-9]+)/?$' , PLM_PLUGIN_URL . 'webservices/plm_check.php' );

    // Flush the rules

Instead of add_external_rule, I've tried add_rewrite_rule like this:

$wp_rewrite->add_rewrite_rule( '^plm_check/([a-zA-z0-9_]+)/([a-zA-z0-9-]+)/([0-9]+)/?$' , PLM_PLUGIN_URL . 'webservices/plm_check.php' , 'top' );

I've also tried it with and without $wp_rewrite.

I think the problem is that Wordpress won't allow me to directly access that file as a URL. For instance, if I just put in "http://www.domain.com/wp-content/plugins/plm/webservices/plm_check.php", it takes me to the 404 page, even though the file actually exists.

Am I using these functions wrong? Hooking to the wrong action? Trying to do something that WP isn't going to allow?


  • what does your plugin file do? do you need to connect to the database or otherwise use the WordPress environment? external rules end up in your .htaccess file and WP is never loaded for those requests, so if they're correctly formatted there should be no interaction or interference from WordPress. If you need the WP environment, then an internal rule is necessary.
    – Milo
    Commented Jan 16, 2013 at 17:43
  • It's a web service returning some XML data and is going to have to connect to the database. So I need to use the add_rewrite_rule?
    – skustes
    Commented Jan 16, 2013 at 18:05
  • Right now my web service page is just text while I get the rewrite portion fixed. I just tried it with add_rewrite_rule and still end up at the 404 page.
    – skustes
    Commented Jan 16, 2013 at 18:08

2 Answers 2


Here's a quick (hopefully error-free!) example of adding an internal rewrite and loading a plugin file to process those requests. This will give you access to the WordPress environment so you can use the database, etc..

The general steps are:

  1. add your rewrite and point it to index.php with your custom query vars appended
  2. register your custom query vars so WordPress knows what they are
  3. hook the parse_request action and check if one of the query vars is set. if it is, load the plugin file and exit before WordPress does the default query and loads the template


Plugin Name: PLG
Plugin URI:
Author URI:

class PLG {

    static $plugin_path;

    public function __construct(){
        $this->plugin_path = plugin_dir_path(__FILE__);
        register_activation_hook( __FILE__, array( $this, 'flush' ) );
        add_action( 'init', array( $this, 'init') );
        add_filter( 'query_vars', array( $this, 'query_vars') );
        add_action( 'parse_request', array( $this, 'parse_request') );

    public function flush(){

    public function init(){

    public function query_vars( $query_vars ){
        $query_vars[] = 'plmvar1';
        $query_vars[] = 'plmvar2';
        $query_vars[] = 'plmvar3';
        return $query_vars;

    public function parse_request( &$wp ){
        if ( array_key_exists( 'plmvar1', $wp->query_vars ) ){
            include $this->plugin_path . 'webservices/plm_check.php';

$wpa8185_plg = new PLG();

In your plugin file plm_check.php, you can access your query vars like:

global $wp;
echo $wp->query_vars['plmvar1'];
  • Oh wow, that's awesome! I'm pretty sure I wouldn't have come up with something like that had I banged away for a century. So I created a class file with this class, changed the variable names to what I need them to be and set my main plugin file to include this class. I assume what I need to do is invoke a new instance of this class in my Install function, right? Is that enough for Wordpress to have access to the parse_request function?
    – skustes
    Commented Jan 16, 2013 at 20:44
  • the very last line in the first block creates an instance of the class as soon as the file is loaded, so it should work as-is.
    – Milo
    Commented Jan 16, 2013 at 23:22
  • Ah, I see how that works. So here's what's happening. I've tried using Monkeyman Rewrite Analyzer and my rewrite rule isn't showing up in the list of rewrite rules. I've gone into the database and tried to find it in the WP Options "rewrite_rules" option and it's not there. I ran the regex through Regex Genie and it matched my URL (domain.com/subfolder/plm_check/abcdefghij/…).
    – skustes
    Commented Jan 17, 2013 at 14:24
  • I put an echo into each of the class functions and Construct is run on each page load, as it should be. Init() is run each time too (does that need to add_rewrite_rule on each page load? Flush() is never run on activation. I've manually flushed the rules and it still doesn't appear in the list of rewrite rules. Parse_request runs, but the only thing in $wp->query_vars is array(1) { ["error"]=> string(3) "404" }. I'll keep plugging away on this to try to debug it. Really appreciate your help.
    – skustes
    Commented Jan 17, 2013 at 14:26
  • I'd have to see how your own class is including this class, or more importantly where. try using the plugin on its own, without your own class. is your WordPress install in subfolder? rewrite rules need to get added on each request, because some other plugin or WP itself might flush the rules, at which point your plugin's would disappear. rules should definitely not be flushed on each request though, because it's an expensive operation, which is why it should only happen on activation. activation stuff is a bit tricky to debug, because you can't see its output, it happens in a sandbox.
    – Milo
    Commented Jan 17, 2013 at 20:24

In your case add_rewrite_rul() will call add_external_rule() which collects rules to be written into you .htaccess file. If your .htaccess is write protected, as it should be, it will not work. I also not sure that your rewrite rules will work at all, you should probably try them first by manually editing your .htaccess.

In addition, what @milo commented.

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.