Accéder à l'API WordPress en dehors de WordPress (PHP en ligne de commande)

13

J'ai un script PHP que je dois exécuter en tant que tâche cron. Cependant, ce script doit avoir accès à l'API WP ( get_pages(), get_post_meta()et get_permalink()spécifiquement). J'ai suivi les instructions sur http://codex.wordpress.org/Integrating_WordPress_with_Your_Website , mais en vain.

Code:

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

Cependant, lorsque je cours à php -q this_file.phppartir de la ligne de commande, j'obtiens la sortie suivante:

<!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>

Quelqu'un a des idées / suggestions?

ggutenberg
la source

Réponses:

17

WordPress s'attend à ce que les variables $ _SERVER soient configurées comme s'il s'agissait d'une demande Web normale. En outre, je suggérerais de charger wp-load.php au lieu de wp-blog-header.php car vous n'avez probablement pas besoin de la classe WP ou du chargeur de modèle pour fonctionner. Voici comment je démarre normalement tous les scripts dont j'ai besoin pour interagir avec WP à partir de la ligne de commande:

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');

Mise à jour 2018:

De nos jours, Wordpress ne nécessite pas du tout $ _SERVER. Si vous avez simplement besoin d'accéder aux fonctions de l'API Wordpress (par exemple pour lire / écrire dans la base de données), tout ce dont vous avez besoin est:

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

# your code goes here...
prettyboymp
la source
Pour l'utiliser get_pages, il a besoin de la classe WP. donc wp-blog-header.php était le bon fichier à appeler.
goldenapples
J'ai essayé de faire exactement ce que vous avez spécifié ici avec le bon HTTP_HOST, SERVER_NAMEet REQUEST_URI. A également essayé avec les deux wp-blog-header.phpet wp-load.php. Même message d'erreur que celui indiqué dans la question d'origine dans tous les cas. J'exécute cela à partir de mon répertoire de thèmes - est-ce important?
ggutenberg
@goldenapples, il en a besoin pour se charger, mais il n'en a pas besoin pour s'exécuter, ce qui est le truc supplémentaire que fait wp-blog-header.php.
prettyboymp
2
@dosboy, exécutez-vous cela sur un serveur ou un ordinateur de développement exécutant mamp? Si vous l'exécutez sur un ordinateur sur lequel plusieurs instances de mysql sont installées, il est possible que votre environnement utilise une instance php et mysql différente de la ligne de commande par rapport aux requêtes http normales.
prettyboymp
Hmm ... une pensée intelligente. Il s'agit d'une boîte de développement exécutant MAMP. Mais je n'ai pas accès SSH à ma boîte de production. Une idée comment spécifier une instance MySQL sur ma machine de développement juste pour vous assurer que le script fonctionne?
ggutenberg
4

Vous pouvez utiliser la commande wp-cli eval-file :

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

Cela chargera d'abord l'environnement WP, puis exécutera votre fichier.

scribu
la source
1

La réponse acceptée par @prettyboymp concerne les informations les plus utiles et uniques sur l'accès à wordpress à partir d'un script php que j'ai trouvées sur le Web. Cela a parfaitement fonctionné pour moi avec WP core 3.7.1, puis 3.9 l'a cassé.

Le problème était que cela a wp-load.phpchangé la façon dont il a testé le REQUEST_URIchemin d'accès valide. Mais heureusement, il a également ajouté un nouveau filtre pour permettre de court-circuiter le test.

Donc , pour restaurer la fonctionnalité de la réponse en 3.9, j'ai ajouté define('SUNRISE', 'on');à wp-config.php, et le fichier créé wp-content/sunrise.phpavec ce contenu:

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;
}
suie
la source
0

Une variante de la réponse de @ prettyboymp pourrait être:

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');
}
éveiller
la source