最近小 V(本站好友) 在开发一款自适应的 WordPress 网站主题,该 WordPress 主题大量数据展示与提交都用到了 ajax 技术,所以小 V 特意写一篇教程记录下,方便其他 WordPress 开发者做 WordPress ajax 应用开发的时候做参考。如果有些小伙伴还不知道什么是 ajax,请自行百度脑补~~,闲话就不多说了,教程开始。
不少开发者在写插件时喜欢用以下方式实现 ajax:

  1. require_once( '../../../../wp-config.php' );

就连百度站长平台官方开发的 WordPress 结构化数据提交插件也是如此实现 ajax 的,这是一种极其不合理的写法,因为一旦用户设置的目录不同, 相对路径就会失效. 并且, 如果你在你的插件中使用的是面向对象的写法, 你将无法直接使用一些变量和私有方法. 最大的坏处就是会导致整个 WordPress 的框架额外重新加载一遍,严重的影响了网站的运行效率。

其实,WordPress 为了方便开发者开发带有 ajax 功能的插件主题已经预定义好了 ajax 方法,我们只需按照官方预留的方法去使用就好了。在开发 WordPress ajax 你要先了解的是,不管是后台还是前台任何的 Ajax 请求都是在 admin-ajax.php 处理的,向 admin-ajax.php 发送请求的时候, 有一个必须的参数是 $_REQUEST['action'], 因为 admin-ajax.php 需要根据用户是否登陆了来触发不同的 hooks 。

  1. if ( is_user_logged_in() ) {  
  2.  
  3.  
  4.  
  5.   
  6. $_REQUEST['action'] );  

  7. else {  
  8.  
  9.  
  10.  
  11.   
  12. $_REQUEST['action'] );  

  13. }  

以上代码取自 WordPress 系统文件 admin-ajax.php,从以上代码我们可以看出我们要发起一个请求首先要知道这个请求是否在登录状态下发起的?不同状态触发的 hook 也不一样,下面是个在主题利用 jquery 实现 ajax 的示例代码:

  1. add_action( 'wp_head', 'v7v3AjaxScript');  
  2. function v7v3AjaxScript(){  
  3.     print '<script>var v7v3_ajaxurl = "'. admin_url( 'admin-ajax.php' ) . '"' . ";</script>n";  
  4. "<script> 
  5.     $(docunment).ready(function(){ 
  6.         $.ajax( { 
  7.             url: v7v3_ajaxurl, 
  8.             data:{ 
  9.                 action : 'is_login' 
  10.             }, 
  11.             type:'post', 
  12.             cache:false, 
  13.             success:function(data) { 
  14.                 alert(data); 
  15.             } 
  16.         }); 
  17.     }); 
  18.     </scrip>";  
  19. }  
  20. add_action( 'wp_ajax_nopriv_is_login', 'v7v3_ajax_not_login' );  
  21.      
  22. function v7v3_ajax_is_login(){  
  23.     global $current_user;  
  24.     printf( '登录用户您好 : %s!', $current_user->display_name );  
  25.     die;  
  26.      
  27. function v7v3_ajax_not_login(){  
  28.     print '尊敬的访客您好!';  
  29.     die;  
  30. }  

在开发 WordPress ajax 应用中最重要的一点就是函数结束之前一定要加 die 或者 exit,如果不加的话会把整个 WordPress 框架都重新加载一遍。