如何在我称为Ajax的php脚本中访问wordpress函数

时间:2019-04-23 15:36:55

标签: php ajax wordpress

我正在尝试从PHP脚本调用WordPress函数(get_avatar($ id)),该PHP脚本正在从排队的javascript文件的ajax引用调用中访问。 (说这种负荷已经使我的头部受伤了。)

作为一个例子,我为WordPress创建了一个插件:hmm-test。它在hmm-test.php中实现。该脚本排队一个javascript文件:test.js。在js内,我有一个xhttprequest调用,该调用将POSTS发送到hmm-test.php,该分支会基于POST变量的测试。

当hmm-test.php作为GET调用时,例如,使用嵌入了短代码的页面的WordPress URL,我可以调用WordPress函数。在POST分支中,我还希望能够调用WordPress本机函数,并将其作为JSON有效负载的一部分返回。

所以我的问题是:我可以将hmm-test.php的'POST'分支设为'wordpress-aware'以便可以在其中调用本地WP函数吗?

我被卡住了-不知道还能尝试什么。我尝试尽早创建一个REST端点以通过Ajax URL进行调用,但一直遇到身份验证问题。如果这行得通,我可以花一些时间来完成它,但是我发现OAuth有点棘手。我让它为别的东西工作,但失去了它。如果有一种方法可以通过简单的POST完成,那对我的概念证明就足够了。

这是插件PHP脚本和排队的javascript的全部内容:

<?php
/*
Plugin Name:  HMM Test
*/

if (strlen($_POST['action'])) {

        $rv["payload"] = get_avatar(108);
        $rv["payload"] = "This is the payload message";
        $rv["status"]  = 'SUCCESS';
        echo json_encode($rv);

} else {

        function hmm_test_enqueue_scripts() {

                wp_register_script( 'test-js', plugins_url( '/js/test.js', __FILE__ ), '', '1.0', all );

        }

        add_action( 'wp_enqueue_scripts', 'hmm_test_enqueue_scripts' );

        /* ***************************************************************************
         * This is the main page
         * ************************************************************************* */

        add_shortcode( 'test-contents', 'my_test_contents' );

        function my_test_contents() {

                wp_enqueue_script( 'test-js' );

                wp_localize_script('test-js', 'wpVariables', array(
                        'pluginsUrl' => plugins_url(),
                        'pluginDir' => trailingslashit( dirname( plugin_basename( __FILE__ ) ) ),
                        'userID' => 37
                ));

                echo "Wordpress functions test: get_avatar()";
                echo get_avatar( 37 );          # -- This works from the plugin script

                echo '<button type="button" class="test-button">Click to crash</button>';
        }
}

还有JS:

(function () {
        var c = document.getElementsByClassName('test-button');

        for (var i = 0; i < c.length; i++ ) {
                c[i].addEventListener('click', doTest, false);
        }
})();

function doTest() {

        console.log("In doTest()");

        var xhttp = new XMLHttpRequest();
        xhttp.onreadystatechange = function() {
                if (this.readyState == 4 && this.status == 200) {
                        console.log("responseText: " + this.responseText);
                }
        };

        var ajaxUrl = wpVariables.pluginsUrl + '/' + wpVariables.pluginDir + 'hmm-test.php';
        var userid  = wpVariables.userID;

        xhttp.open("POST", ajaxUrl, true);
        xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
        let arg = "action=update" + "&userid=" + userid;
console.log("Calling URL:" + ajaxUrl + " with arg: " + arg);
        xhttp.send(arg);
}

当我将简短代码[hmm-test]放在Wordpress页面中时,它加载正常,并且得到了预期的'Wordpress functions test ...',这是用户37的正确头像图片(在此示例中为硬编码) ),然后单击使事情崩溃的按钮(暂时!)。

单击按钮,我看到这是控制台窗口:

  

在doTest()test.js?ver = 1.0:40中调用   网址:https://not-my-real-url.com/wp-content/plugins/hmm-test/hmm-test.php   带有arg:action = update&userid = 37 test.js?ver = 1.0:30 responseText:致命错误:调用未定义函数get_avatar()    /home4/mifydnu/public_html/wp-content/plugins/hmm-test/hmm-test.php   在第 8

显然,也许并不奇怪,关于get_avatar()函数一无所知。这很有意义-我只是通过URL调用一些PHP脚本。脚本位于某个地方的Wordpress目录中没有任何区别。但是我为如何解决这个问题而感到困惑。

谢谢您的建议!

2 个答案:

答案 0 :(得分:0)

您需要使用Wordpress的ajax脚本。它涉及将代码编写为函数,并使用WordPress挂钩将其附加到WP ajax脚本。参见{{3}}。

这样做的一个很大好处是,某些站点具有适当的安全设置,将不允许直接访问插件中的php文件,除非您使用此内置方法,否则这将破坏AJAX。在我们新的安全性插件破解它之后,我不得不转换一个非常大的插件才能使用此方法。结果实际上为我减少了很多编码,并提高了稳定性和更好的性能。

答案 1 :(得分:0)

由于您将POST请求直接发送到PHP脚本(而不是使用AJAX API或REST API),因此基本上绕过了整个WordPress核心,因此它的所有功能都无法使用脚本,因此您现在看到的“调用未定义函数”错误。

这是重构的代码,因此它使用AJAX API,因此所有WP函数都可用于您的脚本:

主插件文件:

<?php
/**
 * Plugin Name:  HMM Test
 */

/**
 * Registers scripts and stylesheets.
 */
function hmm_test_enqueue_scripts() {
    wp_register_script( 'test-js', plugins_url( '/js/test.js', __FILE__ ), array(), '1.0', true );
    wp_localize_script('test-js', 'wpVariables', array(
        'ajaxurl' => admin_url( 'admin-ajax.php' ),
        'userID' => 37
    ));
    wp_enqueue_script( 'test-js' );
}
add_action( 'wp_enqueue_scripts', 'hmm_test_enqueue_scripts' );

/**
 * Registers the shortcode.
 */
function my_test_contents() {
    echo "Wordpress functions test: get_avatar()";
    echo get_avatar( 37 );          # -- This works from the plugin script

    echo '<button type="button" class="test-button">Click to crash</button>';
}
add_shortcode( 'test-contents', 'my_test_contents' );

/**
 * Handles the AJAX request.
 */
function my_action() {
    $rv["payload"] = get_avatar(108);
    $rv["payload"] = "This is the payload message";
    $rv["status"]  = 'SUCCESS';
    echo json_encode($rv);

    wp_die(); // this is required to terminate immediately and return a proper response
}
add_action( 'wp_ajax_my_action', 'my_action' );

test.js现在变为:

(function () {
    var c = document.getElementsByClassName('test-button');

    for (var i = 0; i < c.length; i++ ) {
            c[i].addEventListener('click', doTest, false);
    }
})();

function doTest() {

    console.log("In doTest()");

    var xhttp = new XMLHttpRequest();
    xhttp.onreadystatechange = function() {
        if (this.readyState == 4 && this.status == 200) {
            console.log("responseText: " + this.responseText);
        }
    };

    var ajaxUrl = wpVariables.ajaxurl;
    var userid  = wpVariables.userID;

    xhttp.open("POST", ajaxUrl, true);
    xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");

    // The "action" parameter is the name of the (pardon the redundancy) "action" 
    // registered with "wp_ajax_" (see main plugin file for reference)
    //
    // You can name this whatever you want but make sure it's unique
    // to your plugin to avoid name collisions.
    let arg = "action=my_action" + "&userid=" + userid;

    console.log("Calling URL:" + ajaxUrl + " with arg: " + arg);

    xhttp.send(arg);

}

重要:没有任何验证(安全随机数,$ _ POST变量检查等)应添加到代码中,以使其更加可靠/安全。