問題描述
我正在使用一個很好的小 open-source 產品,名為 Restler,為 Wordpress 應用程式提供 RESTful API 。為了使其工作,我希望能夠在一個請求進來的 Restler 將執行的一組 PHP 類中載入 Wordpress 環境。
載入 WP 環境的想法 – 沒有 UI 元素的載入 – 是透過我稱為 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";
這就像一個魅力。我現在可以從命令列 (php test.php,下面的指令碼是 test.php) 執行這樣的指令碼:
<?php
include "AddWordpress.php";
$terms = get_terms("actions");
echo json_encode($terms);
我遇到的問題是,如果我想包括”AddWordpress.php” 不在檔案的頂部,但在方法呼叫內 – 我知道這聽起來像一個非常糟糕的主意,但有很好的理由… 請相信我 – 那麼所有的狗屎都會鬆動,我的日子變得非常快。更具體地說,測試檔案現在如下所示:
<?php
function do_that_wordpress_thing() {
include "AddWordpress.php";
}
do_that_wordpress_thing();
$terms = get_terms("actions");
echo json_encode($terms);
我得到的錯誤如下:
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 *我在 PHP.net 上收到的東西是 include 函式 def 的這個程式碼段:
If the include occurs inside a function within the calling file, then all of the code contained in the called file will behave as though it had been defined inside that function. So, it will follow the variable scope of that function. An exception to this rule are magic constants which are evaluated by the parser before the include occurs.
我認為這對於為什麼這不工作,但我仍然絕望地失去了重要的作用。誰能解釋為什麼會發生這種情況?任何幫助將非常感激。
最佳解決方法
這個答案的信用真的去了 @Wyck 誰正確地確定了問題的根源。非常感謝你。問題的原因是:
There is a variance between an import statement in the mainline code versus within a function. In WP or in in any of the plugins if variables aren’t explicitly set to global then they become locally scoped to the function they are being imported into.
這是一個恥辱,沒有匯入指令來明確地將變數定向到一個特定的名稱空間,但是沒有這個,你可以簡單地將所有的全域性變數宣告為”global” 在函式中。從我原來的問題陳述中使用相同的演示檔案,現在可以使用:
<?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);
另外值得注意的是,如果在你的外掛中使用自動裝載機; 你應該使它們符合名稱空間。例如,而不是:
spl_autoload_register ( 'autoloader_function_name' );
用這個:
spl_autoload_register ( __NAMESPACE__ . '\autoloader_function_name' );
參考文獻
注:本文內容整合自 Google/Baidu/Bing 輔助翻譯的英文資料結果。如果您對結果不滿意,可以加入我們改善翻譯效果:薇曉朵技術論壇。