13

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:

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.

2
9

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:

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

But!

As guys before mentioned, for AJAX you can use WP-s native ajax technique.

Of course, there are cases when WP's native AJAX technique is not enough.

2
  • 3
    wp-content can be absent or in a completely different directory than WP.
    – fuxia
    Jun 3 '15 at 18:45
  • This is probably the best way. If you have a weird wp-content location (unlikely) just adjust your regex. Nov 27 '16 at 2:37
0

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.

-1

You can use below code to use wp-load.php to include wp-load from any location

require_once( trailingslashit( ABSPATH ) .'wp-load.php' );
1
  • 2
    But if you've got ABSPATH set and trailingslashit defined then you've probably already included wp-load.
    – Rup
    Jan 10 '20 at 9:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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