J'utilise un excellent petit produit open-source appelé Restler pour fournir une API RESTful à une application Wordpress. Pour que cela fonctionne, je veux pouvoir charger l'environnement Wordpress dans un ensemble de classes PHP que Restler exécutera à la réception d'une demande.
L'idée de charger l'environnement WP - sans le chargement des éléments de l'interface utilisateur - est réalisée par un script que j'ai appelé AddWordpress.php:
<?php
error_reporting(E_ALL);
$site_name='yoursite';
$site_domain='www.yoursite.com';
/**
* Construct a fake $_SERVER global to get WordPress to load a specific site.
* This avoids alot of messing about with switch_to_blog() and all its pitfalls.
*/
$_SERVER=array(
'HTTP_Host'=>$site_domain,
'REQUEST_METHOD'=>'GET',
'REQUEST_URI'=>"/{$site_name}/",
'SERVER_NAME'=>$site_domain,
);
// Remove all our bespoke variables as they'll be in scope as globals and could affect WordPress
unset($site_name,$site_domain);
// Pretend that we're executing an AJAX process. This should help WordPress not load all of the things.
define('DOING_AJAX',true);
// Stop WordPress doing any of its normal output handling.
define('WP_USE_THEMES',false);
// turn on debugging
define('WP_DEBUG', true);
define('WP_DEBUG_LOG', true);
// Load WordPress - intentionally using an absolute URL due to issues with relative paths on the CLI.
include "/[path-to-root-www]/wp-load.php";
Cela fonctionne comme un charme. Je peux maintenant exécuter des scripts comme celui-ci à partir de la ligne de commande (php test.php
où le script ci-dessous correspond à test.php):
<?php
include "AddWordpress.php";
$terms = get_terms("actions");
echo json_encode($terms);
Le problème que j'ai est que si je veux inclure le "AddWordpress.php" pas en haut du fichier mais à l'intérieur d'un appel de méthode - je sais que cela semble être une très mauvaise idée, mais il y a de bonnes raisons pour cela ... S'il te plait, crois-moi, alors toute la merde se décolle et ma journée tourne mal très vite. Plus précisément, le fichier de test ressemble maintenant à ceci:
<?php
function do_that_wordpress_thing() {
include "AddWordpress.php";
}
do_that_wordpress_thing();
$terms = get_terms("actions");
echo json_encode($terms);
et les erreurs que je reçois sont les suivantes:
Notice: is_404 was called incorrectly. Conditional query tags do not work before the query is run. Before then, they always return false. Please see Debugging in WordPress for more information. (This message was added in version 3.1.) in /[path-to-www-root]/wp-includes/functions.php on line 2944
Notice: is_home was called incorrectly. Conditional query tags do not work before the query is run. Before then, they always return false. Please see Debugging in WordPress for more information. (This message was added in version 3.1.) in /[path-to-www-root]/wp-includes/functions.php on line 2944
Notice: is_search was called incorrectly. Conditional query tags do not work before the query is run. Before then, they always return false. Please see Debugging in WordPress for more information. (This message was added in version 3.1.) in /[path-to-www-root]/wp-includes/functions.php on line 2944
Notice: is_archive was called incorrectly. Conditional query tags do not work before the query is run. Before then, they always return false. Please see Debugging in WordPress for more information. (This message was added in version 3.1.) in /[path-to-www-root]/wp-includes/functions.php on line 2944
... etc ...
* UPDATE * Ce que j'ai compris sur PHP.net est cet extrait de la fonction include def:
Si l'inclusion se produit dans une fonction du fichier appelant, alors tout le code contenu dans le fichier appelé se comportera comme s'il avait été défini dans cette fonction. Donc, cela suivra la portée variable de cette fonction. Les constantes magiques évaluées par l'analyseur avant l'inclusion sont une exception à cette règle.
Je pense que cela doit jouer un rôle important dans la raison pour laquelle cela ne fonctionne pas, mais je suis toujours désespérément perdu. Quelqu'un peut-il expliquer pourquoi cela pourrait se produire? Toute aide serait très appréciée.
Le mérite de cette réponse revient vraiment à @Wyck qui a correctement identifié la source du problème. Merci beaucoup. La raison du problème est:
Il existe un écart entre une instruction d'importation dans le code de la ligne principale et dans une fonction. Dans WP ou dans l'un des plug-in si les variables ne sont pas explicitement définies comme globales, elles sont localement étendues à la fonction dans laquelle elles sont importées.
C'est dommage qu'il n'y ait pas de directive d'importation pour diriger explicitement les variables vers un espace de noms particulier, mais en l'absence de cela, vous pouvez simplement réclamer que toutes les variables globales sont "globales" dans la fonction. En utilisant le même fichier de démonstration de mon énoncé de problème original, cela fonctionne maintenant:
<?php
function do_that_wordpress_thing() {
global $domain, $path, $base, $admin_page_hooks, $ajax_results, $all_links, $allowedposttags, $allowedtags, $authordata, $bgcolor, $cache_categories, $cache_lastcommentmodified, $cache_lastpostdate, $cache_lastpostmodified, $cache_userdata, $category_cache, $class, $comment, $comment_cache, $comment_count_cache, $commentdata, $current_user, $day, $debug, $descriptions, $error, $feeds, $id, $is_Apache, $is_IIS, $is_macIE, $is_winIE, $l10n, $locale, $link, $m, $map, $max_num_pages, $menu, $mode, $month, $month_abbrev, $monthnum, $more, $multipage, $names, $newday, $numpages, $page, $page_cache, $paged, $pagenow, $pages, $parent_file, $preview, $previousday, $previousweekday, $plugin_page, $post, $post_cache, $post_default_category, $post_default_title, $post_meta_cache, $postc, $postdata, $posts, $posts_per_page, $previousday, $request, $result, $richedit, $single, $submenu, $table_prefix, $targets, $timedifference, $timestart, $timeend, $updated_timestamp, $urls, $user_ID, $user_email, $user_identity, $user_level, $user_login, $user_pass_md5, $user_url, $weekday, $weekday_abbrev, $weekday_initial, $withcomments, $wp, $wp_broken_themes, $wp_db_version, $wp_did_header, $wp_did_template_redirect, $wp_file_description, $wp_filter, $wp_importers, $wp_plugins, $wp_taxonomies, $wp_the_query, $wp_themes, $wp_object_cache, $wp_query, $wp_queries, $wp_rewrite, $wp_roles, $wp_similiesreplace, $wp_smiliessearch, $wp_version, $wpcommentspopupfile, $wpcommentsjavascript, $wpdb;
global $load_sections; // for pagelines theme
include "AddWordpress.php";
}
do_that_wordpress_thing();
$terms = get_terms("actions"); // I have a custom taxonomy named "actions"
echo json_encode($terms);
Il est également intéressant de noter que si vous utilisez des autochargeurs automatiques dans votre plugin; vous devriez les rendre compatibles avec les espaces de noms. Par exemple, au lieu de:
spl_autoload_register ( 'autoloader_function_name' );
utilisez ceci:
spl_autoload_register ( __NAMESPACE__ . '\\autoloader_function_name' );