问题描述
我正在使用一个很好的小 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 辅助翻译的英文资料结果。如果您对结果不满意,可以加入我们改善翻译效果:薇晓朵技术论坛。