Accedi all'API di WordPress all'esterno di WordPress (riga di comando PHP)


13

Ho uno script PHP che devo eseguire come cron job. Tuttavia questo script necessita di accedere alle API WP ( get_pages(), get_post_meta()e get_permalink()in particolare). Ho seguito le istruzioni su http://codex.wordpress.org/Integrating_WordPress_with_Your_Website , ma senza risultati.

Codice:

require_once('../../../wp-blog-header.php');
$args = array(
    'child_of' => 2083
);
$pages = get_pages($args);

Tuttavia quando corro php -q this_file.phpdalla riga di comando ottengo il seguente output:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>Database Error</title>

</head>
<body>
    <h1>Error establishing a database connection</h1>
</body>
</html>

Qualcuno ha qualche pensiero / suggerimento?

Risposte:


17

WordPress prevede che le variabili $ _SERVER vengano configurate come se fosse una normale richiesta web. Inoltre, suggerirei di caricare wp-load.php invece di wp-blog-header.php poiché probabilmente non hai bisogno della classe WP o del template loader per funzionare. Ecco come avvio normalmente qualsiasi script di cui ho bisogno per interagire con WP dalla riga di comando:

define('DOING_AJAX', true);
define('WP_USE_THEMES', false);
$_SERVER = array(
    "HTTP_HOST" => "mysite.com",
    "SERVER_NAME" => "mysite.com",
    "REQUEST_URI" => "/",
    "REQUEST_METHOD" => "GET"
);
require_once('current/wp-load.php');

Aggiornamento 2018:

Oggi Wordpress non richiede affatto $ _SERVER. Se hai semplicemente bisogno di accedere alle funzioni dell'API di Wordpress (ad esempio per leggere / scrivere nel database), tutto ciò di cui hai bisogno è:

require_once('current/wp-load.php');

# your code goes here...

Per usare get_pages, ha bisogno della classe WP. quindi wp-blog-header.php era il file giusto da chiamare.
goldenapples,

Ho provato a fare esattamente come hai specificato qui con il corretto HTTP_HOST, SERVER_NAMEe REQUEST_URI. Provato anche con entrambi wp-blog-header.phpe wp-load.php. Stesso messaggio di errore come indicato nella domanda originale in tutte le istanze. Sto eseguendo questo dalla mia directory dei temi - è importante?
ggutenberg,

@goldenapples, ne ha bisogno per caricarlo, ma non ne ha bisogno per funzionare, che è la roba extra che fa wp-blog-header.php.
prettyboymp,

2
@dosboy, stai eseguendo questo su un server o un computer di sviluppo che esegue mamp? Se lo stai eseguendo su un computer su cui è installata più di un'istanza di mysql, è possibile che il tuo ambiente stia utilizzando una diversa istanza php e mysql dalla riga di comando rispetto alle normali richieste http.
prettyboymp,

Hmm ... pensiero intelligente. È una scatola di sviluppo che esegue MAMP. Ma non ho accesso SSH alla mia scatola di produzione. Qualche idea su come specificare un'istanza di MySQL sulla mia macchina di sviluppo solo per assicurarsi che lo script funzioni?
Ggutenberg,

4

Puoi usare il comando wp-cli eval-file :

@daily /usr/bin/wp --path=/path/to/wp/ eval-file /path/to/that_file.php

Questo caricherà prima l'ambiente WP, quindi eseguirà il tuo file.


1

La risposta accettata da @prettyboymp riguarda le informazioni più utili e uniche sull'accesso a wordpress da uno script php che ho trovato sul web. Ha funzionato perfettamente per me con WP core 3.7.1, quindi 3,9 l'ha rotto.

Il problema era che ha wp-load.phpcambiato il modo in cui ha testato REQUEST_URIun percorso valido. Ma per fortuna ha anche aggiunto un nuovo filtro per consentire il corto circuito del test.

Quindi, per ripristinare la funzionalità della risposta in 3.9, ho aggiunto define('SUNRISE', 'on');a wp-config.php, e file creato wp-content/sunrise.phpcon questo contenuto:

add_filter('pre_get_site_by_path', 'my_pre_get_site_by_path', 10, 5 /*null, $domain, $path, $segments, $paths*/ );
    function my_pre_get_site_by_path($input, $domain, $path, $segments, $paths) {
    if ($path == '/') {
        return get_blog_details(array('domain' => $domain, 'path' => PATH_CURRENT_SITE), false);
    }
    return $input;
}

0

Una variante alla risposta di @ prettyboymp potrebbe essere:

if(in_array(php_sapi_name(), ['cli', 'cli-server'])) {
    foreach($_SERVER as $key => $val) {
        if(!getenv($key))
             putenv($key.'='.$val);
    }

    if(!getenv('HTTP_HOST'))
        putenv('HTTP_HOST='.gethostname());

    if(!getenv('SERVER_ADDR'))
        putenv('SERVER_ADDR='.gethostbyname(gethostname()));

    if(!getenv('REQUEST_URI'))
        putenv('REQUEST_URI=/');

    if(!getenv('REQUEST_METHOD'))
        putenv('REQUEST_METHOD=GET');
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.