Truy cập API WordPress bên ngoài WordPress (dòng lệnh PHP)


13

Tôi có một kịch bản PHP mà tôi cần để chạy như một công việc định kỳ. Tuy nhiên kịch bản này cần truy cập vào API WP ( get_pages(), get_post_meta()get_permalink()cụ thể). Tôi đã làm theo các hướng dẫn tại http://codex.wordpress.org/Integrating_WordPress_with_Your_Website , nhưng không có kết quả.

Mã số:

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

Tuy nhiên, khi tôi chạy php -q this_file.phptừ dòng lệnh, tôi nhận được đầu ra sau:

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

Bất cứ ai có bất kỳ suy nghĩ / đề nghị?

Câu trả lời:


17

WordPress hy vọng các biến $ _SERVER sẽ được thiết lập như thể đó là một yêu cầu web bình thường. Ngoài ra, tôi sẽ khuyên bạn nên tải wp-load.php thay vì wp-blog-header.php vì có thể bạn không cần lớp WP hoặc trình tải mẫu để chạy. Đây là cách tôi thường bắt đầu bất kỳ tập lệnh nào tôi cần để tương tác với WP từ dòng lệnh:

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

Cập nhật 2018:

Ngày nay, Wordpress không yêu cầu $ _SERVER. Nếu bạn chỉ cần truy cập các hàm API Wordpress (ví dụ để đọc / ghi vào cơ sở dữ liệu), tất cả những gì bạn cần là:

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

# your code goes here...

Để sử dụng get_pages, anh ta cần lớp WP. vì vậy wp-blog-header.php là tệp phù hợp để gọi.
Goldenapples

Đã thử làm chính xác như bạn đã chỉ định ở đây với chính xác HTTP_HOST, SERVER_NAMEREQUEST_URI. Cũng đã thử với cả wp-blog-header.phpwp-load.php. Thông báo lỗi tương tự như đã nêu trong câu hỏi ban đầu trong tất cả các trường hợp. Tôi đang chạy cái này từ thư mục chủ đề của mình - có vấn đề gì không?
ggutenberg

@goldenapples, anh ta cần nó để tải, nhưng anh ta không cần nó để chạy, đó là những thứ bổ sung mà wp-blog-header.php làm.
Prettyboymp

2
@dosboy, bạn đang chạy cái này trên máy chủ hay máy tính phát triển chạy mamp? Nếu bạn đang chạy nó trên một máy tính có cài đặt nhiều hơn một phiên bản mysql, có khả năng môi trường của bạn có thể đang sử dụng một phiên bản php và mysql khác từ dòng lệnh so với các yêu cầu http thông thường.
Prettyboymp

Hmm ... suy nghĩ thông minh. Nó là một hộp dev chạy MAMP. Nhưng tôi không có quyền truy cập SSH vào hộp sản xuất của mình. Bất kỳ ý tưởng làm thế nào để chỉ định một phiên bản MySQL trên máy dev của tôi chỉ để đảm bảo tập lệnh đang hoạt động?
ggutenberg

4

Bạn có thể sử dụng lệnh wp-cli eval-file :

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

Điều này trước tiên sẽ tải môi trường WP, sau đó chạy tệp của bạn.


1

Câu trả lời được chấp nhận bởi @prettyboymp là về thông tin hữu ích và độc đáo nhất về việc truy cập wordpress từ tập lệnh php mà tôi đã tìm thấy trên web. Nó hoạt động hoàn hảo với tôi với WP core 3.7.1, sau đó 3.9 đã phá vỡ nó.

Vấn đề là điều đó wp-load.phpđã thay đổi cách nó kiểm tra REQUEST_URIđường dẫn hợp lệ. Nhưng may mắn thay, nó cũng đã thêm một bộ lọc mới để cho phép kiểm tra ngắn mạch.

Vì vậy, để khôi phục lại chức năng của các câu trả lời trong 3.9, tôi đã thêm define('SUNRISE', 'on');vào wp-config.php, và tạo ra tập tin wp-content/sunrise.phpvới nội dung này:

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

Một biến thể cho câu trả lời của @ beautifulboymp có thể là:

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');
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.