实现AJAX通信所需的服务器端PHP脚本有两个部分。 首先,我们需要在网页上排列jQuery脚本,并本地化jQuery脚本需要的任何PHP值。 其次是AJAX请求的实际处理。
## 入队脚本
本部分介绍了WordPress中AJAX的两大难点,它将经验丰富的编程人员新增至WordPress。 一个是需要排入脚本,以便获得元链接在页面的头部分中正确显示。 另一个是所有AJAX请求需要通过wp-admin / admin-ajax.php发送。 不要将请求直接发送到您的插件页面。
## 排队
使用函数wp_enqueue_script()让WordPress在页面的部分插入一个元链接到您的脚本。 不要在标题模板中硬编码这样的链接。 作为一个插件开发人员,您没有准备好访问标题模板,但是这个规则不管怎么说。
入队功能有三个参数。 第一个是用于在其他功能中引用脚本的任意标签或句柄。 第二个是脚本文件的完整URL。 为了便于携带,请使用plugins_url()来构建正确的URL。 如果你为插件之外的东西排队脚本,使用一些相关的功能创建一个正确的URL - 从来没有硬编码。 第三个参数是脚本依赖的任何脚本标记的数组。 由于我们使用jQuery发送一个AJAX请求,所以至少需要在数组中列出'jquery'。 始终使用数组,即使它是单个依赖项。 我们的示例的入队呼叫如下所示:
```
wp_enqueue_script( 'ajax-script',
plugins_url( '/js/myjquery.js', __FILE__ ),
array('jquery')
);
```
加载脚本时,您无法直接从插件代码页排入脚本。 脚本必须从几个动作钩子之一排队 - 哪一个取决于脚本需要链接到哪个页面。 对于管理页面,请使用admin_enqueue_scripts。 对于前端页面使用wp_enqueue_scripts,除了登录页面,在这种情况下使用login_enqueue_scripts。
admin_enqueue_scripts钩子将当前页面文件名传递给您的回调。 使用此信息仅将脚本排列在需要的页面上。 前端版本没有通过任何内容。 在这种情况下,使用模板标签(如is_home(),is_single()等)来确保您只需将脚本排列在需要的位置。 这是我们的示例的完整的入队代码:
```
add_action( 'admin_enqueue_scripts', 'my_enqueue' );
function my_enqueue( $hook ) {
if( 'myplugin_settings.php' != $hook ) return;
wp_enqueue_script( 'ajax-script',
plugins_url( '/js/myjquery.js', __FILE__ ),
array( 'jquery' )
);
}
```
为什么我们在这里使用命名函数,但是使用jQuery的匿名函数?因为闭包最近才被PHP支持。 jQuery已经支持了很多时间。由于有些人可能仍在运行旧版本的PHP,因此我们总是使用命名函数来实现最大的兼容性。如果您有最新的PHP版本,并且仅针对您自己的安装开发,请继续使用闭包。
##注册与入队
您将在其他教程中看到宗教使用wp_register_script()的示例。这很好,但它的使用是可选的。什么是不可选的是wp_enqueue_script()。必须调用此函数才能使您的脚本文件在网页上正确链接。那么为什么要注册脚本?它创建一个有用的标签或句柄,您可以根据需要轻松地在代码的各个部分中引用该脚本。如果您只需要加载脚本,而不是在代码中的其他地方引用它,则无需注册。
##随机
您需要创建一个随机数,以便jQuery AJAX请求可以被验证为合法请求,而不是来自某个未知的坏行为者的潜在的恶意请求。只有你的PHP脚本和你的jQuery脚本才能知道这个值。收到请求后,您可以验证它是在此创建的相同值。这是为了创建一个我们的例子的随机数
```
$title_nonce = wp_create_nonce( 'title_example' );
```
参数title_example可以是任意任意的字符串。 建议字符串与所使用的内容相关,但它可以是适合您的任何东西。
##本地化
如果您从jQuery部分回想起,由jQuery创建的由jQuery创建的数据被传递给一个名为my_ajax_obj的全局对象。 在我们的示例中,此数据是一个随机数,并且是admin-ajax.php的完整URL。 分配对象属性和创建全局jQuery对象的过程称为本地化。 这是我们使用wp_localize_script()的示例中使用的本地化代码。
```
wp_localize_script( 'ajax-script', 'my_ajax_obj', array(
'ajax_url' => admin_url( 'admin-ajax.php' ),
'nonce' => $title_nonce, // It is common practice to comma after
) ); // the last array item for easier maintenance
```
>[info] 注意我们的脚本如何处理ajax脚本被使用,以便将全局对象分配给正确的脚本。 对象对我们的脚本是全局的,而不是所有的脚本。 也可以从用于排入脚本的同一个钩子调用本地化。 创建一个随机数也同样如此,尽管这个特定的功能可以在几乎任何地方被调用。 所有这些组合在一起的单个钩子回调看起来像这样:
```
add_action( 'admin_enqueue_scripts', 'my_enqueue' );
function my_enqueue( $hook ) {
if( 'myplugin_settings.php' != $hook ) return;
wp_enqueue_script( 'ajax-script',
plugins_url( '/js/myjquery.js', __FILE__ ),
array( 'jquery' )
);
$title_nonce = wp_create_nonce( 'title_example' );
wp_localize_script( 'ajax-script', 'my_ajax_obj', array(
'ajax_url' => admin_url( 'admin-ajax.php' ),
'nonce' => $title_nonce,
) );
}
```
## AJAX行动
服务器端PHP代码的另一个主要部分是接收POSTed数据的实际AJAX处理程序,执行一些操作,然后将相应的响应发送回浏览器。 这采用WordPress动作钩子的形式。 您使用哪个挂钩标签取决于用户是否登录,并且您的jQuery脚本作为action:value传递的值是多少。
>[info] 注意:$_GET , $_POST and $_COOKIE vs $_REQUEST
您可能已经使用一个或多个PHP超级全局变量(如$ _GET或$ _POST)从表单或Cookie(使用$ _COOKIE)检索值。也许你更喜欢$ _REQUEST,或至少看过它使用。这很酷 - 无论请求方法,POST或GET,它将具有表单值。适用于使用这两种方法的页面。除此之外,它还具有cookie值。一站式购物!其中有它的悲剧性缺陷。在名称冲突的情况下,cookie值将覆盖任何表单值。因此,糟糕的演员在他们的浏览器上制作一个假冒的cookie是非常容易的,这将覆盖您可能期望的请求的任何表单值。 $ _REQUEST是黑客将任意数据注入到表单值中的简单路径。要特别安全,坚持特定的变量,避免一切都适合。
由于我们的AJAX交换是用于插件的设置页面,所以用户必须登录。如果从jQuery部分回想起来,action:value是“my_tag_count”。这意味着我们的动作钩子标签将是wp_ajax_my_tag_count。如果我们的AJAX交换机被当前未登录的用户使用,则动作挂钩标签将是wp_ajax_nopriv_my_tag_count用于挂起动作的基本代码如下所示:
```
add_action( 'wp_ajax_my_tag_count', 'my_ajax_handler' );
function my_ajax_handler() {
// Handle the ajax request
wp_die(); // All ajax handlers die when finished
}
```
您的AJAX处理程序应该做的第一件事情是验证jQuery与check_ajax_referer()发送的随机数,该值应与脚本入队时本地化的值相同。
```
check_ajax_referer( 'title_example' );
```
提供的参数必须与之前提供的参数wp_create_nonce()相同。 如果随机数不检出,该函数就会死机。 如果这是一个真正的现在,现在使用它,这个价值不再是好的。 然后,您将生成一个新的并将其发送到回调脚本,以便它可以用于下一个请求。 但是由于WordPress的内容有二十四个小时的好处,所以你不需要做任何事情,但检查它。
##数据
随着nonce不可用,我们的处理程序可以处理由$ _POST ['title']中包含的jQuery脚本发送的数据。 我们可以使用update_user_meta()将用户的选择保存在用户元中。
```
update_user_meta( get_current_user_id(), 'title_preference', $_POST['title']);
```
然后,我们构建一个查询以获取所选标题标签的发布数。
```
$args = array(
'tag' => $_POST['title'],
);
$the_query = new WP_Query( $args );
```
最后我们可以将响应发送回jQuery脚本。有几种传输数据的方法。在我们处理我们的例子的细节之前,我们来看一些选项。
## XML
对XML的PHP支持留下了一些希望。幸运的是,WordPress提供了WP_Ajax_Response类,使任务更容易。 WP_Ajax_Response类将生成XML格式的响应,为标题设置正确的内容类型,输出响应xml,然后死 - 确保正确的XML响应。
## JSON
这种格式是轻量级和易于使用的,WordPress提供的wp_send_json函数来json编码您的响应,打印它,并死 - 有效地替换WP_Ajax_Response。 WordPress还提供了wp_send_json_success和wp_send_json_error函数,这些函数允许在JS中触发适当的done()或fail()回调。
##其他
只要发送者和接收者协调一致,就可以传输任何你喜欢的数据。诸如逗号分隔或制表符分隔的文本格式是许多可能性之一。对于少量的数据,发送原始流可能是足够的。这就是我们将使用我们的例子 - 我们将发送实际的替换HTML,没有别的。
```
echo $_POST['title'].' ('.$the_query->post_count.') ';
```
在现实世界的应用程序中,您必须考虑到由于某种原因可能会失败的可能性 - 例如,数据库服务器可能已关闭。 响应应该允许这种偶然性,并且接收响应的jQuery脚本应该相应地行动,或许告诉用户稍后再试。
## die
当处理程序完成所有任务时,它需要死机。 如果您使用WP_Ajax_Response或wp_send_json *函数,则会自动为您处理。 如果没有,只需使用WordPress wp_die()函数。
```
wp_die();
// That's all folks!
```
## AJAX处理者总结
我们的示例的完整AJAX处理程序如下所示:
```
//JSON
function my_ajax_handler() {
check_ajax_referer( 'title_example' );
update_user_meta( get_current_user_id(), 'title_preference', $_POST['title'] );
$args = array(
'tag' => $_POST['title'],
);
$the_query = new WP_Query( $args );
wp_send_json( $_POST['title'] . ' (' . $the_query->post_count . ') ' );
}
//Other
function my_ajax_handler() {
check_ajax_referer( 'title_example' );
update_user_meta( get_current_user_id(), 'title_preference', $_POST['title'] );
$args = array(
'tag' => $_POST['title'],
);
$the_query = new WP_Query( $args );
echo $_POST['title'].' ('.$the_query->post_count.') ';
wp_die(); // All ajax handlers should die when finished
}
```
- 简介
- 主题开发
- WordPress许可证
- 什么是主题
- 开发环境
- 主题开发示例
- 主题基础
- 模板文件
- 主样式表(style.css)
- 文章类型
- 规划主题文件
- 模板层级
- 模板标签
- 循环
- 主题函数
- 连接主题文件和目录
- 使用CSS和JavaScript
- 条件标签
- 类别,标签和自定义分类
- 模板文件
- 内容模板文件
- 页面模板文件
- 附件模板文件
- 自定义内容类型
- 部分和其他模板文件
- 评论模板
- 分类模板
- 404页面
- 主题功能
- 核心支持的功能
- 管理菜单
- 自定义Headers
- 自定义Logo
- 文章格式
- 置顶文章
- Sidebars
- Widgets
- 导航菜单
- 分页
- 媒体
- Audio
- Images
- Galleries
- Video
- 精选图片和缩略图
- 国际化
- 本地化
- 辅助功能
- 主题选项 – 自定义API
- 定制对象
- 改进用户体验的工具
- 定制JavaScript API
- JavaScript / Underscore.js渲染的自定义控件
- 高级用法
- 主题安全
- 数据消毒/逃避
- 数据验证
- 使用随机数
- 常见漏洞
- 高级主题
- 子主题
- UI最佳实践
- JavaScript最佳做法
- 主题单元测试
- 验证你的主题
- Plugin API Hooks
- 发布你的主题
- 所需的主题文件
- 测试
- 主题评论指南
- 写文档
- 提交你的主题到WordPress.org
- 参考文献
- 模板标签列表
- 条件标签列表
- 编码标准
- HTML编码标准
- CSS编码标准
- JavaScript编码标准
- PHP编码标准
- 插件开发
- 插件开发简介
- 什么是插件
- 插件基础
- 头部要求
- 包括软件许可证
- 启用 / 停用 Hooks
- 卸载方法
- 最佳做法
- 插件安全
- 检查用户功能
- 数据验证
- 保护输入
- 保护输出
- 随机数
- Hooks
- Actions
- Filters
- 自定义Hooks
- 高级主题
- 管理菜单
- 顶级菜单
- 子菜单
- 短代码
- 基本短码
- 封闭短码
- 带参数的短代码
- TinyMCE增强型短码
- 设置
- 设置API
- 使用设置API
- 选项API
- 自定义设置页面
- 元数据
- 管理帖子元数据
- 自定义元数据
- 渲染元数据
- 自定义文章类型
- 注册自定义文章类型
- 使用自定义文章类型
- 分类
- 使用自定义分类
- 在WP 4.2+中使用“split术语”
- 用户
- 创建和管理用户
- 使用用户元数据
- 角色和功能
- HTTP API
- JavaScript
- jQuery
- Ajax
- 服务器端PHP和入队
- Heartbeat API
- 概要
- 计划任务
- 了解WP-Cron计划
- 安排WP-Cron 事件
- 将WP-Cron挂接到系统任务计划程序中
- WP-Cron简单测试
- 国际化
- 本地化
- 如何国际化您的插件
- 国际化安全
- WordPress.org
- 详细插件指南
- 规划您的插件
- 如何使用Subversion
- 插件开发者常见问题
- 开发工具
- Debug Bar 和附加组件
- 辅助插件
- REST API手册
- 资源
- 文章
- 文章修订
- 文章类型
- 文章状态
- 类别
- 标签
- 页面
- 评论
- 分类
- 媒体
- 用户
- 设置
- 使用REST API
- 全局参数
- 分页
- 链接和嵌入
- 发现
- 认证
- 经常问的问题
- 骨干JavaScript客户端
- 客户端库
- 扩展REST API
- 添加自定义端点
- 自定义内容类型
- 修改回应
- 模式
- 词汇表
- 路由和端点
- 控制器类