How to include wp-load.php from any location?

I have a plugin which calls a stand-alone php script (myAjax.php) via a jQuery.ajax() script inside the plugin.

I need to place the following code into the myAjax.php file:

Read More
require_once('../../../wp-load.php');

if (!is_user_logged_in()){
    die("You Must Be Logged In to Access This");
}
if( ! current_user_can('edit_files')) {
    die("Sorry you are not authorized to access this file");
}

However, I’d like a more bulletproof method of specifying the path to wp-load.php in case the actual relative path is different than my example.

Related posts

Leave a Reply

4 comments

  1. You can use __DIR__ constant. Since the file is either inside plugin or theme folder, which are always located inside wp-content folder.. You can simply get the path of the file and trim everything starting from wp-content from it:

    $path = preg_replace( '/wp-content.*$/', '', __DIR__ );
    

    If you need to make sure the wp is not inside some wp-content folder (who knows? things happen) – use negative lookahead:

    $path = preg_replace( '/wp-content(?!.*wp-content).*/', '', __DIR__ );
    

    (since it’s easier to be sure your own plugin you are developing is not located inside some other wp-content folder)

    Aaand.. your wp-load is there:

    require_once( $path . 'wp-load.php' );
    

    Best Practice

    As before mentioned, for AJAX you should use WordPress’ admin-ajax technique or the new REST API.

  2. I know this is an old question but wanted to add my own answer which I think might help some users trying to achieve the same thing.

    Yes it’s always better (and easier) to use the native WP Ajax API, but it can become very slow because it loads the entire WP instance.

    My solution: is quite simple, and should work to retrieve the root of the wordpress installation. In whatever script you are doing the custom AJAX call, just make sure you first register the script with wp_register_script() (don’t enqueue it yet). Then use wp_localize_script() and parse the ABSPATH (this is a constant that is defined inside wp-load.php and will hold the root path). You can now retrieve this inside your script and parse it along with the AJAX call. Finally of course make sure to actually enqueue the script with wp_enqueue_script().

    Example:

    The below PHP snippet will enqueue your script.js file, and allows you to retrieve the root dir by calling pluginslug_scriptname_i18n.wp_root. Basically the wp_localize_script() is used to do translations, but this also becomes in handy to parse data into your script(s) that you retrieved server side.

            $handle = 'pluginslug-scriptname'; // Set script handle
            $name = str_replace( '-', '_', $handle ) . '_i18n'; // Will convert handle to pluginslug_scriptname_i18n
            wp_register_script( $handle, plugin_dir_url( __FILE__ ) . 'script.js', array(), '1.0.0', false );  
            wp_localize_script(
                $handle,
                $name,
                array( 
                    'ajax_url' => plugin_dir_url( __FILE__ ) . 'ajax-handler.php', // @THIS WILL HOLD YOUR AJAX URL :) To retrieve this inside your script.js simply call: pluginslug_scriptname_i18n.ajax_url
                    'wp_root' => ABSPATH // @THIS WILL HOLD THE ROOT PATH :) To retrieve this inside your script.js simply call: pluginslug_scriptname_i18n.wp_root
                )
            );
            wp_enqueue_script( $handle );
    

    Your script.js could look like this:

        var xhttp = new XMLHttpRequest();
        xhttp.onreadystatechange = function() {
            if (this.readyState == 4 ){
                if (this.status == 200) {
                    // Success:
                }
                // Complete:
            }
        };
        xhttp.onerror = function () {
          console.log(this);
          console.log("** An error occurred during the transaction");
        };
        xhttp.open("POST", pluginslug_scriptname_i18n.ajax_url, true);
        xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded; charset=UTF-8");
        var params = JSON.stringify({
            first_name: 'Johny',
            wp_root: pluginslug_scriptname_i18n.wp_root
        });
        xhttp.send(params);
    

    Now inside your ajax-handler.php you can retrieve the wp_content_dir and load your wp-load.php like so:

    // Set proper content type
    header('Content-Type: text/html');
    // Disable caching
    header('Cache-Control: no-cache');
    header('Pragma: no-cache');
    // Get's the payload
    $request_body = json_decode( file_get_contents('php://input'), true );  
    
    // Set this to true to just load the basics!
    // Only set this to true if you know what you are doing
    // Lookup SHORTINIT inside wp-settings.php for more details
    define( 'SHORTINIT', false ); 
    
    // Include wp-load.php
    require_once( $request_body['wp_root'] . 'wp-load.php' );
    die();
    

    Please keep in mind that the wp_root can be altered client side.

    As a side note:

    Another trick that some of you might not be aware of is that before including wp-load.php you can define a constant called SHORTINIT (boolean). This will tell WordPress to just load the basics (meaning you will lose a lot of WP core functions) but it will speed up the loading time since it won’t include all the required files for a regular WP instance. The SHORTINIT is defined inside wp-settings.php (just open up the file and look for SHORTINIT. You will have a better understanding of what is happening under the hood. This nifty trick will speed up the load times even more (up to 75% in my tests that I did some time ago). But this will depend on the WP version. Also keep in mind that the wp-load.php changes frequently with new releases of WP versions, so if you use SHORTINIT be sure that your script will always work even in future versions of WordPress, and also with lower version of WordPress. In short, if you do complex things that rely on a lot of the WordPress codex, then make sure to NOT set SHORTINIT to true.

  3. I suggest this as a possible “bulletproof” method of finding the path to wp-load.php so long as it is in a directory above where you are running the script.

    echo get_wp_abspath('wp-load.php') . PHP_EOL;
    
    function get_wp_abspath($filename)
    {
      $_DIR = __DIR__; // location of this script
    
      $_FILE = $_DIR . '/' . $filename; // fullpath/file
    
      while(!file_exists($_FILE)) // if not found
      {
        $_DIR = dirname($_DIR); // up one step (i.e. ../)
    
        $_FILE = $_DIR . '/' . $filename; // new fullpath/file
    
        if($_DIR == '/') return FALSE; // if we hit the base path, fail
      }
    
      return $_FILE; // if file found, return fullpath/file
    }
    
  4. You can use below code to use wp-load.php to include wp-load from any location

    require_once( trailingslashit( ABSPATH ) .'wp-load.php' );