php中get_adjacent_post函数PHP源码阅读笔记

五月 12, 2019 | views
Comments 0

这个函数是wordpress里的一个函数,作用是获取相邻的POST文章。

函数并不大,有效代码大概只有70行左右,但是里面包含的知识不少,所以专门用一篇文章来解释一下。

get_adjacent_post函数的源码位于wp-includes/link-template.php中。

我会通过“//roc:”在引出源码阅读笔记。

  1. /** 
  2.  * Retrieve adjacent post. 
  3.  * 
  4.  * Can either be next or previous post. 
  5.  * 
  6.  * @since 2.5.0 
  7.  * 
  8.  * @param bool $in_same_cat Optional. Whether post should be in a same category. 
  9.  * @param array|string $excluded_categories Optional. Array or comma-separated list of excluded category IDs. 
  10.  * @param bool $previous Optional. Whether to retrieve previous post.                                                              
  11.  * @return mixed Post object if successful. Null if global $post is not set. Empty string if no corresponding post exists. 
  12.  */ 

【笔记】

上面这一段是函数的介绍信息,这个函数包括三个参数:

1 $in_same_cat参数,表示是否需要在同一category中,默认为false。

2 $excluded_categories参数,用于设置忽略哪些category中的post。可以将category ID组成array或comma-separated list的方式来赋值。

3 $previous参数,表示是否提取前一篇post。默认为true。如果希望提取后一篇post,需则设置为false。

此函数的返回值也有三种情况:

1 返回post object,则表明成功;

2 返回NULL,则表明全局$post未设置;

3 返回空字符串,则表明相应的post不存在。

function get_adjacent_post( $in_same_cat = false, $excluded_categories = "", $previous = true ) {

global $wpdb;

【笔记】

这里声明了$wpdb全局变量,这个变量其实很有来头的,它是wordpress自身为开发者提供的公有全局变量,开发者们可以直接利用这个函数来对数据库进行操作,包括新建、删除、添加、更新等等。

需要注意的是,如果想使用这个“万能钥匙”,需要在自己的函数中向上面这样声明一下这个变量。

另外,在正常情况下,$wpdb变量只有权限访问博客所对应的一个数据库,对其他数据库是没有权限的。

比如想查询数据库中的表内容,那么可以这样:

  1. if ( ! $post = get_post() )        return null; 
  2.     $current_post_date = $post->post_date; 
  3.  
  4.     $join = ""
  5.     $posts_in_ex_cats_sql = ""
  6.     if ( $in_same_cat || ! emptyempty$excluded_categories ) ) { 
  7.         $join = " INNER JOIN $wpdb->term_relationships AS tr ON p.ID = tr.object_id INNER JOIN $wpdb->term_taxonomy tt ON tr.term_taxonomy_id = tt.term_taxonomy_id"
  8.  
  9.         if ( $in_same_cat ) { 
  10.             if ( ! is_object_in_taxonomy( $post->post_type, "category" ) ) 
  11.                 return ""
  12.             $cat_array = wp_get_object_terms($post->ID, "category"array("fields" => "ids")); 
  13.             if ( ! $cat_array || is_wp_error( $cat_array ) ) 
  14.                 return ""
  15.             $join .= " AND tt.taxonomy = "category" AND tt.term_id IN (" . implode(","$cat_array) . ")";  
  16.         }    
  17.  
  18.         $posts_in_ex_cats_sql = "AND tt.taxonomy = "category""
  19.         if ( ! emptyempty$excluded_categories ) ) { 
  20.             if ( ! is_array$excluded_categories ) ) { 
  21.                 // back-compat, $excluded_categories used to be IDs separated by " and " 
  22.                 if ( strpos$excluded_categories" and " ) !== false ) { 
  23.                     _deprecated_argument( __FUNCTION__"3.3", sprintf( __( "Use commas instead of %s to separate excluded categories." ), ""and"" ) ); 
  24.                     $excluded_categories = explode" and "$excluded_categories ); 
  25.                 } else { 
  26.                     $excluded_categories = explode","$excluded_categories ); 
  27.                 } 
  28.             } 
  29.  
  30.             $excluded_categories = array_map"intval"$excluded_categories ); 
  31.  
  32.             if ( ! emptyempty$cat_array ) ) { 
  33.                 $excluded_categories = array_diff($excluded_categories$cat_array); 
  34.                 $posts_in_ex_cats_sql = ""
  35.             } 
  36.  
  37.             if ( !emptyempty($excluded_categories) ) { 
  38.                 $posts_in_ex_cats_sql = " AND tt.taxonomy = "category" AND tt.term_id NOT IN (" . implode($excluded_categories",") . ")"
  39.             } 
  40.         } 
  41.     } 
  42.  
  43.     $adjacent = $previous ? "previous" : "next"
  44.     $op = $previous ? "<" : ">"
  45.     $order = $previous ? "DESC" : "ASC"
  46.  
  47.     $join  = apply_filters( "get_{$adjacent}_post_join"$join$in_same_cat$excluded_categories ); 
  48.     $where = apply_filters( "get_{$adjacent}_post_where"$wpdb->prepare("WHERE p.post_date $op %s AND p.post_type = %s AND p.post_status = "publish" $posts_in_ex_cats_sql"$current_post_date$post->post_type), $in_same_cat$excluded_categories ); 
  49.     $sort  = apply_filters( "get_{$adjacent}_post_sort""ORDER BY p.post_date $order LIMIT 1" ); 
  50.  
  51.     $query = "SELECT p.id FROM $wpdb->posts AS p $join $where $sort"
  52.     $query_key = "adjacent_post_" . md5($query); 
  53.     $result = wp_cache_get($query_key"counts"); 
  54.     if ( false !== $result ) { 
  55.         if ( $result ) 
  56.             $result = get_post( $result ); 
  57.         return $result
  58.     } 
  59.  
  60.     $result = $wpdb->get_var( $query ); 
  61.     if ( null === $result ) 
  62.         $result = ""
  63.  
  64.     wp_cache_set($query_key$result"counts"); 
  65.     //phpfensi.com 
  66.     if ( $result ) 
  67.         $result = get_post( $result ); 
  68.  
  69.     return $result



zend