服务器端PHP脚本需要两个部分来实现AJAX通信。首先,我们需要在网页上对jQuery脚本进行排队,并本地化jQuery脚本所需的任何PHP值。其次是AJAX请求的实际处理。
本节介绍了WordPress中AJAX的两个主要怪癖,这两个怪癖会让新手遇到经验丰富的程序员。一个是需要将脚本排队,以使元链接正确显示在页面的头部部分。另一个是全部的需要通过发送AJAX请求wp-admin/admin-ajax.php
。不要直接向插件页面发送请求。
使用函数wp_enqueue_script()
让WordPress在页面的部分中插入脚本的元链接。永远不要在标题模板中硬编码此类链接。作为一名插件开发人员,您没有现成的页眉模板访问权限,但无论如何,这条规则值得一提。
enqueue函数接受以下五个参数:
- $句柄是脚本的名称。
- 美元src定义脚本的位置。为了便于携带,请使用
插件_ url()
构建正确的URL。如果您要将脚本排队以获取插件以外的内容,请使用一些相关函数来创建正确的URL–不要硬编码
- $个部门是一个数组,可以处理新脚本所依赖的任何脚本,例如jQuery。由于我们使用jQuery发送AJAX请求,您至少需要列出
“jquery”
在数组中。
- $ver(美元)允许您列出版本号。
- $个参数定义页脚打印的参数数组(通过
英尺(_F)
键)和脚本加载策略(通过策略
键),例如推迟
或异步
。这将替换/重载$英寸英尺
参数从WordPress版本6.3开始。
wp_enque_script脚本('ajax脚本',插件url('/js/myjquery.js',__FILE__),数组(“jquery”),'1.0.,0',阵列(“in_footer”=>true,));
加载插件代码页时,不能直接将脚本排队。脚本必须从几个操作挂钩中的一个进入队列,这取决于脚本需要链接到哪种类型的页面。对于管理页面,请使用管理员队列脚本
。对于前端页面,请使用wp_排队_脚本
,登录页面除外,在这种情况下使用登录排队脚本
.
这个管理员队列脚本
hook将当前页面文件名传递给回调。使用此信息仅在需要脚本的页面上排队。前端版本没有通过任何操作。在这种情况下,请使用模板标记,例如is_home()
,是单个(_S)
等,以确保只在需要脚本的地方排队。这是我们示例的完整排队代码:
add_action(“admin_enqueue_scripts”,“my_enqueue”);函数my_enqueue($hook){if('myplugin_settings.php'!==$hook){回报;}wp_排队_脚本(“ajax-script”,插件url('/js/myjquery.js',__FILE__),数组(“jquery”),'1.0.0',阵列(“in_footer”=>true,));}
为什么我们在这里使用命名函数,而在jQuery中使用匿名函数?因为PHP最近才支持闭包。jQuery支持它们已经有一段时间了。由于有些人可能仍在运行较旧版本的PHP,因此我们始终使用命名函数以实现最大兼容性。如果您有一个最新的PHP版本,并且只为自己的安装而开发,那么如果愿意,可以继续使用闭包。
注册与排队
你会在其他教程中看到虔诚使用的例子wp_register_script()
。这很好,但它的使用是可选的。不可选的是wp_enqueue_script()
。必须调用此函数才能在网页上正确链接脚本文件。那么为什么要注册脚本呢?它创建了一个有用的标记或句柄,您可以根据需要在代码的各个部分中轻松引用该脚本。如果您只需要加载脚本,而没有在代码的其他地方引用它,则无需注册它。
延迟的脚本加载
WordPress支持通过wp_register_script()
和wp_enqueue_script()
函数,通过策略
在新的$个参数
WordPress 6.3中引入的数组参数。
支持的策略如下:
- 推迟
- 通过指定数组键值对添加
“战略”=>“推迟”
$args参数。
- 标记为延迟执行的脚本(通过defer脚本属性)仅在DOM树完全加载后(但在
DOM内容已加载
和窗口加载事件)。与异步脚本不同,延迟脚本的执行顺序与在DOM中打印/添加脚本的顺序相同。
- 异步
- 通过指定数组键值对添加
“策略”=>“异步”
到$个参数
参数。
- 标记为异步执行的脚本-通过
异步
脚本属性-在浏览器加载后立即执行。异步脚本没有保证的执行顺序,因为脚本B(虽然是在脚本a之后添加到DOM中的)可能首先执行,因为它可能在脚本a之前完成加载。这些脚本可能在DOM完全构造之前或在DOM内容已加载
事件。
以下是为插件中的附加脚本排队指定加载策略的示例:
wp_注册_脚本(“ajax-script-two”,插件url('/js/myscript.js',__FILE__),数组(ajax-script),'1.0.,0',阵列(“策略”=>“推迟”,));
使用时也适用相同的方法wp_enque_script()(问题脚本)
。在上面的示例中,我们表示打算加载“ajax-script-two”
以延迟方式编写脚本。
指定延迟脚本加载策略时,在决定“合格策略”时,会考虑脚本的依赖树(其依赖项和/或从属项)这样就不会导致应用对一个脚本有效但对树中其他脚本有害的策略,因为这会导致意外的无序执行。由于这种逻辑,您通过$个参数
参数可能不是最终(选择的)策略,但它永远不会对预期策略有害(或更严格)。
您需要创建一个nonce,以便将jQuery AJAX请求验证为合法请求,而不是来自某个未知不良参与者的潜在恶意请求。只有您的PHP脚本和jQuery脚本才知道这个值。收到请求后,您可以验证它是否与此处创建的值相同。下面是如何为我们的示例创建nonce的方法:
$title_nonce=wp_create_nonce(“title_example”);
参数title_example(标题_示例)
可以是任意字符串。建议字符串与nonce的用途相关,但它可以是任何适合您的字符串。
如果您从jQuery部分,PHP创建的供jQuery使用的数据被传递到名为我的_雅各布
。在我们的示例中,此数据是nonce和指向的完整URLadmin-ajax.php
。分配对象属性和创建全局jQuery对象的过程称为本地化。这是我们的示例中使用的本地化代码,它使用wp_localize_script()
.
wp_localize_script(“ajax-script”,“my_ajax_obj”,阵列(“ajax_url”=>admin_url(“admin-ajax.php”),“nonce”=>$title_nonce,));
注意我们的脚本如何处理ajax脚本
使用,以便将全局对象分配给正确的脚本。对象对我们的脚本是全局的,而不是对所有脚本。本地化也可以从用于排队脚本的同一钩子中调用。创建nonce也是如此,尽管该特定函数几乎可以在任何地方调用。所有这些组合在一个钩子回调中看起来如下:
add_action('admin_enque_scripts','my_enque');/***将我的脚本和资产排队。**@param$挂钩*/函数my_enqueue($hook){if('myplugin_settings.php'!==$hook){回报;}wp_排队_脚本(“ajax-script”,插件url('/js/myjquery.js',__FILE__),数组(“jquery”),'1.0.0',真的);wp_localize_script('ajax脚本',“my_ajax_obj”,阵列(“ajax_url”=>admin_url(“admin-ajax.php”),“nonce”=>wp_create_nonce(“title_example”),));}
记住只将此nonce本地化添加到所需的页面,不要向不应该使用它的人显示nonce。并且记住使用当前用户扫描()
具有完成安全性的能力或角色。
服务器端PHP代码的另一个主要部分是实际的AJAX处理程序,它接收POSTed数据,对其进行处理,然后将适当的响应发送回浏览器。这采用WordPress的形式活动钩。使用哪个hook标记取决于用户是否登录以及jQuery脚本作为操作:值。
$_GET、$_POST和$_COOKIE与$_REQUEST
您可能已经使用了一个或多个PHP超级全局变量,例如$_GET(获取)
或$_POST(发送)
从表单或cookie中检索值(使用$_COOKIE(考基)
). 也许你更喜欢$请求
相反,或者至少见过它的使用。这有点酷——不管请求方法如何,邮政
或GET(获取)
,它将具有表单值。适用于同时使用这两种方法的页面。除此之外,它还具有cookie值。一站式购物!这就是它的悲剧缺陷。在名称冲突的情况下,cookie值将覆盖任何表单值。因此,一个糟糕的参与者很容易在他们的浏览器上制作一个伪造的cookie,这将覆盖你可能期望从请求中获得的任何表单值。$请求
是黑客将任意数据注入表单值的简单途径。为了更加安全,请坚持特定的变量,避免一刀切。
因为我们的AJAX交换是为了插件的设置页面,所以用户必须登录jQuery部分,的操作:
值为“我的标签计数”
。这意味着我们的动作挂钩标签将是wp_ajax标记计数
。如果当前未登录的用户使用我们的AJAX交换,则操作挂钩标记将为wp_ajax_nopriv标记计数
用于挂钩操作的基本代码如下所示:
add_action('wp_ajax_my_tag_count','my_ajax_handler');/***处理我的AJAX请求。*/函数my_ajax_handler(){//在此处处理ajax请求wp_die();//所有ajax处理程序完成后都会死亡}
AJAX处理程序应该做的第一件事是使用check_ajax_referer()
,该值应与脚本排队时本地化的值相同。
check_ajax_referer(“标题示例”);
提供的参数必须与提供的参数相同早期的到wp_create_nonce()
。如果nonce未签出,函数将终止。如果这是一个真正的nonce,那么现在它已经被使用了,那么这个值就不再有用了。然后,您将生成一个新的脚本并将其发送到回调脚本,以便可以将其用于下一个请求。但是,由于WordPress nonce适合24小时使用,所以您只需检查它即可。
当nonce退出时,我们的处理程序可以处理中包含的jQuery脚本发送的数据$_POST[标题]
。首先,我们将值赋给一个新变量,然后运行它wp_unslash()删除任何意外的引号。
$title=wp_unslash($_POST['title']);
我们可以使用更新用户元数据().
update_user_meta(get_current_user_id(),'标题_引用',清理post_title($title));
然后我们构建一个查询,以获取所选标题标记的帖子计数。
$args=阵列('tag'=>$title,);$the_query=新的WP_query($args);
最后,我们可以将响应发送回jQuery脚本。有几种传输数据的方法。在处理示例的细节之前,让我们先看看一些选项。
XML格式
PHP对XML的支持还有待改进。幸运的是,WordPress提供了WP_Ajax_响应
让任务更容易。这个WP_Ajax_响应类将生成一个XML格式的响应,为标头设置正确的内容类型,输出响应XML,然后死亡-确保正确的XML响应。
JSON格式
这种格式轻量级且易于使用,WordPress提供了wp发送json
函数对您的响应进行json编码、打印和死亡,有效地替换WP_Ajax_响应WordPress还提供了wp_send_json成功
和wp_send_json错误
函数,它允许在JS中触发适当的done()或fail()回调。
其他
只要发送方和接收方协调一致,您可以以任何方式传输数据。逗号分隔或制表符分隔等文本格式是多种可能性之一。对于少量数据,发送原始流可能就足够了。这就是我们在示例中要做的事情——我们将发送实际的替换HTML,而不发送其他内容。
echo esc_html($title)。'('.$the_query->post_count.')';
在实际应用程序中,必须考虑到操作可能因某些原因而失败的可能性,例如,数据库服务器可能已关闭。响应应该考虑到这种意外情况,接收响应的jQuery脚本应该相应地进行操作,可能会告诉用户稍后再试。
当处理程序完成所有任务时,它需要死亡。如果您正在使用WP_Ajax_响应或wpsendjson函数,这将自动为您处理。如果没有,只需使用WordPresswp_die()
功能。
我们示例中的完整AJAX处理程序如下所示:
/***使用JSON的AJAX处理程序*/函数my_ajax_handler__json(){check_ajax_referer(“标题示例”);$title=wp_unslash($_POST['title']);update_user_meta(get_current_user_id(),'title_preference',消毒_post_title($title));$args=数组('tag'=>$title,);$the_query=新WP_query($args);wp_send_json(esc_html($title))。'('.$the_query->post_count.')');}
/***AJAX处理程序未使用JSON。*/函数my_ajax_handler(){check_ajax_referer(“标题示例”);$title=wp_unslash($_POST['title']);update_user_meta(get_current_user_id(),'标题_引用',清理post_title($title));$args=阵列(“tag”=>$title,);$the_query=新WP_query($args);echo esc_html($title)。'('.$the_query->post_count.')';wp_die();//完成后,所有ajax处理程序都应该终止}