自从我使用 AJAX 和 Wordpress 以来已经有一段时间了。我以前做事的方式非常简单,使用在 functions.php 中创建函数的函数名称,然后我使用 :
添加操作add_action('wp_ajax_nopriv_myfunction', 'myfunction');
add_action('wp_ajax_myfunction', 'myfunction');
我在这里画了一个空白,因为现在我的 PHP 代码结构有点不同,我的函数不再位于我的 functions.php 文件中。它位于一个名为:
的类中ds_calculators
$.ajax({
type: 'POST',
url: my_ajax.ajaxurl,
data: { action : 'ds_calculators::myfunction', },
success: function(data, textStatus, XMLHttpRequest)
{
//jQuery('#table_listing').html(''); // empty an element
jQuery('.changer').html(data); // put our list of links into it
},
error: function(XMLHttpRequest, textStatus, errorThrown)
{
if (typeof console === "undefined")
{
console = {
log: function() {},
debug: function() {},
};
}
if (XMLHttpRequest.status == 404)
{
console.log('Element not found.');
}
else
{
console.log('Error: ' + errorThrown);
}
}
});
我现在添加这样的动作
add_action('wp_ajax_nopriv_myFunction', 'ds_calculators::myFunction');
add_action('wp_ajax_myFunction', 'ds_calculators::myFunction');
对于上述情况,我遇到了 400(错误请求)。当函数在类中时,如何包含函数名称?那是我的问题还是我的其他问题?
你不需要在 JS 端指定类引用:
$.ajax({
url: window.ajaxurl,
method: "post",
data: {
action: "myfunction",
},
})
...
在php模板中,如果你的函数在类中,你需要引用它的实例($this)来指定它。
add_action( 'wp_ajax_myfunction', array($this, 'myfunction') );
add_action('wp_ajax_nopriv_myfunction', array($this, 'myfunction') );
如果 (myfucntion) 方法是静态的,那么您将使用类名为 'ds_calculators::myfunction' 的作用域运算符
add_action( 'wp_ajax_myfunction', 'ds_calculators::myfunction' );
add_action('wp_ajax_nopriv_myfunction', 'ds_calculators::myfunction' );
记住
wp_ajax_nopriv_{$action}
为注销的用户触发未经身份验证的 Ajax 操作。
如果你使用 wp_ajax 钩子,你不需要太担心命名空间。
add_action( 'wp_ajax_myfunction', array($this, 'myfunction') );
告诉 wordpress,当请求发送到默认的 ajax url 时,操作设置为“myfunction”,以将其传递给解析时引用的回调函数。唯一要注意的是
wp_ajax_${your_function/action_name}
必须与它在解析时调用的函数相同,并且所讨论的方法必须是 public
这里 是一篇关于如何在类中实现 wordpress ajax 处理程序的精彩文章,以及我从哪里偷来的
namespace MyPlugin;
class AjaxHandler
{
/**
* Action hook used by the AJAX class.
*
* @var string
*/
const ACTION = 'my_plugin';
/**
* Action argument used by the nonce validating the AJAX request.
*
* @var string
*/
const NONCE = 'my-plugin-ajax';
/**
* Register the AJAX handler class with all the appropriate WordPress hooks.
*/
public static function register()
{
$handler = new self();
add_action('wp_ajax_' . self::ACTION, array($handler, 'handle'));
add_action('wp_ajax_nopriv_' . self::ACTION, array($handler, 'handle'));
add_action('wp_loaded', array($handler, 'register_script'));
}
/**
* Handles the AJAX request for my plugin.
*/
public function handle()
{
// Make sure we are getting a valid AJAX request
check_ajax_referer(self::NONCE);
// Stand back! I'm about to try... SCIENCE!
die();
}
/**
* Register our AJAX JavaScript.
*/
public function register_script()
{
wp_register_script('wp_ajax', plugins_url('path/to/ajax.js', __FILE__));
wp_localize_script('wp_ajax', 'wp_ajax_data', $this->get_ajax_data());
wp_enqueue_script('wp_ajax');
}
/**
* Get the AJAX data that WordPress needs to output.
*
* @return array
*/
private function get_ajax_data()
{
return array(
'action' => self::ACTION,
'nonce' => wp_create_nonce(AjaxHandler::NONCE)
);
}
/**
* Get the comment text sent by the AJAX request.
*
* @return string
*/
private function get_comment()
{
$comment = '';
if (isset($_POST['comment'])) {
$comment = filter_var($_POST['comment'], FILTER_SANITIZE_STRING);
}
return $comment;
}
/**
* Get the post ID sent by the AJAX request.
*
* @return int
*/
private function get_post_id()
{
$post_id = 0;
if (isset($_POST['post_id'])) {
$post_id = absint(filter_var($_POST['post_id'], FILTER_SANITIZE_NUMBER_INT));
}
return $post_id;
}
/**
* Sends a JSON response with the details of the given error.
*
* @param WP_Error $error
*/
private function send_error(WP_Error $error)
{
wp_send_json(array(
'code' => $error->get_error_code(),
'message' => $error->get_error_message()
));
}
}
Ajax::register();
如果您有兴趣将 REST API 与 ajax api 一起使用/而不是 ajax api,这里是我制作的一个快速课程,了解如何完成并显示该设置中的命名空间,以及涵盖 wp-nonce 的基础知识
<?php
/**
* Demo Rest API
*
* This file is included in my main plugin class on the
* 'init' action hook. Then the class is instantiated
* (aka new RestApi() is called) and the constructor for
* this calss fires adding the rest_api_init action hook
* for the register_routes() method.
*
* @author yourname
* @version $Id$
* @copyright yourname, 22 February, 2023
* @package default
*/
declare(strict_types = 1);
namespace TESEO;
use WP_REST_Server;
use WP_REST_Request;
use WP_REST_Response;
use WP_Error;
/**
* Class RestApi
*
* @package TESEO
*/
class RestApi {
/**
* Define the url in a constant
*/
const DEMO_URL = 'teseo/v1';
/**
* RestApi constructor.
*/
public function __construct() {
add_action( 'rest_api_init', array( $this, 'register_routes' ) );
add_action( 'wp_footer', array( $this, 'TESEO_plugin_path' ) );
}
/**
* Add plugin path constant to the footer
*
* @return void
*/
public function TESEO_plugin_path(): void {
?>
<script>
// For use in the frontend ajax
var my_plugin_js_vars = {
'plugin_url': '<?php echo plugin_dir_url( __FILE__ ); ?>'
'ajax_url': '<?php echo \admin_url( 'admin-ajax.php' ); ?>',
'nonce': '<?php echo \wp_create_nonce( 'npg_ajax_nonce' ); ?>',
};
// For use with rest you want a nonce
var my_plugin_rest_vars = {
'nonce': '<?php echo \wp_create_nonce( 'wp_rest' ); ?>',
};
</script>
<?php
}
/**
* Register rest API routes on the 'rest_api_init' action
*
* This is where most of the 'namespacing' happens.
* The default base url is '/wp-json/' with the namespace being the first part of the url.
* So in this case the url would be '/wp-json/teseo/v1/' with the namespace being 'teseo'.
* The version is the second part of the url, and the actual route is the third part of the url.
*/
public function register_routes(): void {
register_rest_route(
'teseo/v1',
'/dummy',
array(
'methods' => WP_REST_Server::READABLE,
'callback' => array( $this, 'get_dummy' ),
'permission_callback' => array( $this, 'get_dummy_permissions_check' ),
'args' => array(),
)
);
register_rest_route(
'teseo/v1',
'/dummy/validate',
array(
'methods' => WP_REST_Server::READABLE,
'callback' => array( $this, 'get_dummy_validate' ),
'permission_callback' => array( $this, 'get_dummy_validate_permissions_check' ),
'args' => array(
'id' => array(
'required' => true,
'validate_callback' => function( $param, $request, $key ) {
return is_numeric( $param );
},
),
'nonce' => array(
'required' => true,
'validate_callback' => function( $param, $request, $key ) {
return wp_verify_nonce( $param, 'wp_rest' );
},
),
),
),
);
}
/**
* Get dummy
*
* @param WP_REST_Request $request Request.
*
* @return WP_REST_Response|WP_Error
*/
public function get_dummy( WP_REST_Request $request ): WP_REST_Response {
$data = array(
'message' => 'Hello World',
);
return new WP_REST_Response( $data, 200 );
}
/**
* Get dummy permissions check
*
* @param WP_REST_Request $request Request.
*
* @return bool|WP_Error
*/
public function get_dummy_permissions_check( WP_REST_Request $request ): bool {
return true;
}
/**
* Get dummy validate
*
* @param WP_REST_Request $request Request.
* @return WP_REST_Response|WP_Error
*/
public function get_dummy_validate( WP_REST_Request $request ): WP_REST_Response {
$data = array(
'message' => 'Hello World',
);
return new WP_REST_Response( $data, 200 );
}
/**
* Get dummy validate permissions check
*
* We don't actually need to do anything here, because the permission check
* is already done in the parameter validation. But if we wanted to, we could
* do extra checks here for the current user, role or whatever.
*
* @param WP_REST_Request $request Request.
* @return bool|WP_Error
*/
public function get_dummy_validate_permissions_check( WP_REST_Request $request ) {
// check if the user has the role 'administrator'
if ( ! current_user_can( 'administrator' ) ) {
return new WP_Error( 'rest_forbidden', esc_html__( 'You do not have permission to do this.', 'textdomain' ), array( 'status' => 401 ) );
}
// check if the users id is 1
if ( 1 !== get_current_user_id() ) {
return new WP_Error( 'rest_forbidden', esc_html__( 'You do not have permission to do this.', 'textdomain' ), array( 'status' => 401 ) );
}
// arbitrary check for some other condition
return $this->validate_arbitrary_permissions_check( $request ) ? true : new WP_Error( 'rest_forbidden', esc_html__( 'You do not have permission to do this.', 'textdomain' ), array( 'status' => 401 ) );
}
/**
* Validate that the user making the request has made atleast 5 posts
* in the last 30 days.
*
* @param WP_REST_Request $request Request.
* @return bool|WP_Error
*/
public function validate_arbitrary_permissions_check( WP_REST_Request $request ) {
// get the current user
$user = wp_get_current_user();
// get the users posts
$posts = get_posts(
array(
'author' => $user->ID,
'date_query' => array(
array(
'after' => '30 days ago',
),
),
'post_type' => 'post',
'post_status' => 'publish',
)
);
// check if the user has made atleast 5 posts in the last 30 days
if ( count( $posts ) < 5 ) {
return new WP_Error( 'rest_forbidden', esc_html__( 'You do not have permission to do this.', 'textdomain' ), array( 'status' => 401 ) );
}
return true;
}
}