在WordPress之外访问WordPress API(命令行PHP)


13

我有一个PHP脚本,需要作为cron作业运行。但是这个脚本需要访问到WP API( get_pages()get_post_meta()get_permalink()明确)。我已按照http://codex.wordpress.org/Integrating_WordPress_with_Your_Website上的说明进行操作,但无济于事。

码:

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

但是,当我从命令行运行时php -q this_file.php,会得到以下输出:

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

有人有什么想法/建议吗?

Answers:


17

WordPress希望像正常的Web请求一样设置$ _SERVER变量。另外,我建议加载wp-load.php而不是wp-blog-header.php,因为您可能不需要WP类或模板加载器来运行。这是我通常从命令行启动与WP交互所需的任何脚本的方式:

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

更新2018:

如今,Wordpress根本不需要$ _SERVER。如果您只需要访问Wordpress API函数(例如,读取/写入数据库),则您需要:

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

# your code goes here...

要使用get_pages,他确实需要WP类。因此wp-blog-header.php是正确的文件。
goldenapples 2010年

试图这样做正是因为你已经用正确此处指定HTTP_HOSTSERVER_NAMEREQUEST_URI。还尝试了wp-blog-header.phpwp-load.php。在所有情况下,与原始问题中所述的错误消息相同。我正在主题目录中运行它,这有关系吗?
ggutenberg 2010年

@goldenapples,他需要加载它,但不需要运行它,这是wp-blog-header.php要做的额外工作。
prettyboymp 2010年

2
@dosboy,您是在运行Mamp的服务器或开发计算机上运行此代码吗?如果您在安装了多个mysql实例的计算机上运行它,则您的环境可能会从命令行使用与正常http请求不同的php和mysql实例。
prettyboymp 2010年

嗯...聪明的想法。它是运行MAMP的开发箱。但是我无法通过SSH访问生产环境。知道如何在我的开发机上指定MySQL实例,以确保脚本正常工作吗?
ggutenberg 2010年

4

您可以使用wp-cli eval-file命令:

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

这将首先加载WP环境,然后运行文件。


1

@prettyboymp接受的答案是有关从Web上找到的php脚本访问wordpress的最有用和最独特的信息。在WP核心3.7.1下,它对我来说非常理想,然后3.9破坏了它。

问题是wp-load.php改变了测试REQUEST_URI有效路径的方式。但幸运的是,它还添加了一个新的滤波器,以使测试短路。

因此,为了恢复3.9中答案的功能,我添加define('SUNRISE', 'on');wp-config.php,并创建了wp-content/sunrise.php具有以下内容的文件:

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

@prettyboymp的答案的变体可能是:

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');
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.