Come includere wp-load.php da qualsiasi posizione?
Ho un plugin che richiama uno script PHP standalone (myAjax.php
) tramite uno script jQuery.ajax()
all'interno del plugin.
Ho bisogno di inserire il seguente codice nel file myAjax.php
:
require_once('../../../wp-load.php');
if (!is_user_logged_in()){
die("Devi essere loggato per accedere a questa risorsa");
}
if( ! current_user_can('edit_files')) {
die("Spiacente, non sei autorizzato ad accedere a questo file");
}
Tuttavia, vorrei un metodo più sicuro per specificare il percorso a wp-load.php
nel caso in cui il percorso relativo effettivo sia diverso dal mio esempio.

Puoi utilizzare la costante __DIR__
. Dato che il file si trova all'interno della cartella di un plugin o di un tema, che sono sempre situati dentro la cartella wp-content
.. Puoi semplicemente ottenere il percorso del file e tagliare tutto a partire da wp-content
:
$path = preg_replace( '/wp-content.*$/', '', __DIR__ );
Se hai bisogno di assicurarti che wp non sia dentro qualche cartella wp-content
(chi lo sa? può capitare) - usa il negative lookahead:
$path = preg_replace( '/wp-content(?!.*wp-content).*/', '', __DIR__ );
(dato che è più facile essere certi che il tuo plugin in sviluppo non si trovi dentro qualche altra cartella wp-content
)
Eee.. il tuo wp-load
è qui:
require_once( $path . 'wp-load.php' );
Migliore Pratica
Come menzionato prima, per AJAX dovresti usare la tecnica admin-ajax di WordPress o la nuova REST API.

So che questa è una domanda vecchia, ma volevo aggiungere la mia risposta che penso possa aiutare alcuni utenti che cercano di ottenere lo stesso risultato.
Sì, è sempre meglio (e più facile) usare l'API AJAX nativa di WordPress, ma può diventare molto lenta perché carica l'intera istanza di WP.
La mia soluzione: è abbastanza semplice e dovrebbe funzionare per recuperare la root
dell'installazione di WordPress. In qualsiasi script stai facendo la chiamata AJAX personalizzata, assicurati prima di registrare lo script con wp_register_script()
(non ancora di inserirlo in coda). Poi usa wp_localize_script()
e passa la costante ABSPATH
(questa è una costante definita all'interno di wp-load.php
e conterrà il percorso root). Ora puoi recuperare questo valore all'interno del tuo script e passarlo insieme alla chiamata AJAX. Infine, ovviamente, assicurati di inserire effettivamente lo script in coda con wp_enqueue_script()
.
Esempio:
Il seguente snippet PHP inserirà in coda il tuo file script.js
e ti permetterà di recuperare la directory root
chiamando pluginslug_scriptname_i18n.wp_root
. Fondamentalmente wp_localize_script()
viene usato per le traduzioni, ma torna utile anche per passare dati al tuo script che hai recuperato lato server.
$handle = 'pluginslug-scriptname'; // Imposta l'handle dello script
$name = str_replace( '-', '_', $handle ) . '_i18n'; // Convertirà l'handle in 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', // @QUESTO CONTERRÀ IL TUO URL AJAX :) Per recuperarlo all'interno di script.js chiama semplicemente: pluginslug_scriptname_i18n.ajax_url
'wp_root' => ABSPATH // @QUESTO CONTERRÀ IL PERCORSO ROOT :) Per recuperarlo all'interno di script.js chiama semplicemente: pluginslug_scriptname_i18n.wp_root
)
);
wp_enqueue_script( $handle );
Il tuo script.js
potrebbe essere così:
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 ){
if (this.status == 200) {
// Successo:
}
// Completato:
}
};
xhttp.onerror = function () {
console.log(this);
console.log("** Si è verificato un errore durante la transazione");
};
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);
Ora all'interno del tuo ajax-handler.php
puoi recuperare la wp_content_dir
e caricare il tuo wp-load.php
così:
// Imposta il corretto content type
header('Content-Type: text/html');
// Disabilita la cache
header('Cache-Control: no-cache');
header('Pragma: no-cache');
// Ottiene il payload
$request_body = json_decode( file_get_contents('php://input'), true );
// Imposta questo a true per caricare solo l'essenziale!
// Impostalo a true solo se sai cosa stai facendo
// Cerca SHORTINIT in wp-settings.php per maggiori dettagli
define( 'SHORTINIT', false );
// Includi wp-load.php
require_once( $request_body['wp_root'] . 'wp-load.php' );
die();
Ricorda che il valore di wp_root
può essere modificato lato client.
Come nota a margine:
Un altro trucco di cui alcuni potrebbero non essere a conoscenza è che prima di includere wp-load.php
puoi definire una costante chiamata SHORTINIT
(booleana). Questo dirà a WordPress di caricare solo l'essenziale (significa che perderai molte funzioni core di WP) ma velocizzerà il tempo di caricamento poiché non includerà tutti i file necessari per una normale istanza di WP. La costante SHORTINIT
è definita all'interno di wp-settings.php
(apri il file e cerca SHORTINIT
. Avrai una migliore comprensione di cosa succede sotto il cofano. Questo trucco velocizzerà ulteriormente i tempi di caricamento (fino al 75% nei test che ho fatto tempo fa). Ma questo dipenderà dalla versione di WP. Tieni anche presente che wp-load.php
cambia frequentemente con le nuove versioni di WP, quindi se usi SHORTINIT
assicurati che il tuo script funzioni sempre anche nelle future versioni di WordPress e anche con versioni più vecchie. In breve, se fai cose complesse che si affidano a gran parte del codex di WordPress, allora assicurati di NON impostare SHORTINIT
a true.

Suggerisco questo come un possibile metodo "infallibile" per trovare il percorso a wp-load.php
purché si trovi in una directory superiore rispetto a dove stai eseguendo lo script.
echo get_wp_abspath('wp-load.php') . PHP_EOL;
function get_wp_abspath($filename)
{
$_DIR = __DIR__; // posizione di questo script
$_FILE = $_DIR . '/' . $filename; // percorso completo/file
while(!file_exists($_FILE)) // se non trovato
{
$_DIR = dirname($_DIR); // sali di un livello (es. ../)
$_FILE = $_DIR . '/' . $filename; // nuovo percorso completo/file
if($_DIR == '/') return FALSE; // se raggiungiamo il percorso base, fallisci
}
return $_FILE; // se il file è trovato, restituisci percorso completo/file
}
