从URL确定WP_QUERY参数

时间:2014-07-14 作者:Jody Heavener

我想知道是否可以通过以下方式确定WP\\U查询参数only 使用给定的页面URL。我之所以尝试这样做,是因为我正在开发一个SPA主题(最终是一个JSON响应),并且需要能够在不重新加载页面的情况下确定查询。

虽然这很有技巧,但我成功地将帖子URL与Permalink结构配对,以确定单个帖子查询应该是什么:

<?php

function api_query_url() {

  // Check that the URL is set and is in fact a string
  if ( ! isset( $_POST[\'url\'] ) || gettype( $_POST[\'url\'] ) !== \'string\' ) {
    api_response( false, 400, "\'url\' is a required parameter!" );
  }

  // Parse the URL for parameters and path
  $query_url = parse_url( $_POST[\'url\'] );

  // Pass query-based URL directly to Single API request
  if ( isset( $query_url[\'query\'] ) ) {
    api_single( $query_url[\'query\'] );
  }

  // Map Permalink structure tags to WP_Query parameters
  $structure_refs = array(
    \'year\'     => \'year\',
    \'monthnum\' => \'monthnum\',
    \'day\'      => \'day\',
    \'hour\'     => \'hour\',
    \'minute\'   => \'minute\',
    \'second\'   => \'second\',
    \'post_id\'  => \'p\',
    \'postname\' => \'name\',
    \'category\' => \'category_name\',
    \'author\'   => \'author_name\'
  );

  // Retreive the site\'s Permalink Structure and break it in to an array
  $structure = array_filter( explode( \'/\', get_option( \'permalink_structure\' ) ) );

  // Break our query parameters in to an array
  $query_params = array_filter( explode( \'/\', $query_url[\'path\'] ) );

  // Set up an empty query array
  $query = array();

  // For each query parameter received
  foreach ($query_params as $param) {

    // Using the parameter value\'s position, locate its corresponding structure key
    $key_position  = array_search( $param, $query_params );
    $structure_key = str_replace( \'%\', \'\', $structure[$key_position] );

    // If the structure key exists in the structure references, add to to the query
    if ( array_key_exists( $structure_key, $structure_refs) ) {
      $query[$structure_refs[$structure_key]] = $param;
    }
  }

  // Pass off to Query handler to create JSON response
  api_single( $query );

}
add_action( \'wp_ajax_nopriv_api_query_url\', \'api_query_url\' );
使用上述函数,我可以通过url 作为参数来执行ajax调用,它将对其进行解析以找到WP\\U查询参数。

因此,URL如下http://example.com/blog/my-first-post/ 将被解析为提取name => \'my-first-post\' 和URL,如http://example.com/?p=124 将被解析为提取p => 124. 然后传递给WP_Query 等等FTR,我还删除了任何列入黑名单的参数,如post_statushas_password 为了确保安全。

为了解析一个漂亮的URL结构,我使用路径的组件/2014/07/hello-world/ 我们得到了2014、07和hello world,然后我将它们与设置的permalink结构进行比较,在这种情况下/%year%/%monthnum%/%postname%/ - 由于一些permalink标记不能与WP\\u查询一起使用,我进行了一些转换;例如postname 可能是name.

Anyhow... 我感觉自己有了一个良好的开端,直到我进入页面。使用我上面的代码,页面URL如下http://example.com/about/ 上述permalink结构提取的参数为year => \'about\'. 不太好。

如果有人对我应该如何处理这个问题有任何指导,我将不胜感激。另外,如果我在处理这件事上完全错了,请告诉我。我只需要在不重新加载页面的情况下确定查询。

2 个回复
SO网友:gmazzap

Edited Jul, 07 2014 at 6:28


你的方法有很多缺陷。如果有任何自定义重写规则,它将不起作用;如果服务器是IIS且pretty permalink处于活动状态,它(可能)将不起作用;它将不适用于自定义帖子类型;它将不适用于存档或搜索URL等。

要以经济实惠的方式从url中获取单帖/页面url,有以下功能url_to_postid, e、 g。

$id = url_to_postid( $query_url[\'path\'] );

if ( is_numeric( $id ) && (int) $id > 0 ) {
  // the required post id is: $id
} else {
  // the url is not for a single post, may be an archive url, a search url or even
  // a non-valid 404 url
}
如果你只对单个帖子(甚至是CPT)或页面URL感兴趣,那么上面的几行可能是你唯一需要的,但是如果你需要解析所有类型的WordPress URL,那么你需要一些其他的东西,这并不是很容易的事情。

以经济实惠的方式从url获取查询变量的唯一方法是重现WordPress解析url的方式。

这是通过以下方法在core中完成的parse_requestWP

然而,很难/不鼓励将该方法用于上述目的,因为:

直接访问$_SERVER, $_POST$_GET 变量,很难解析与当前HTTP请求无关的任意URL它会触发一些与当前HTTP请求解析严格相关的操作挂钩,对任意URL进行触发毫无意义。它访问并修改全局$wp 在解析请求后不应更改的变量,否则很可能会出现问题

果心parse_request 该方法有214行长(3.9.1节),完成这项工作可能会非常痛苦,但幸运的是,已经有人完成了这项艰巨的工作,请参见here.

SO网友:Shazzad

有一个简单的解决方案,使用一个好的和一个奇怪的机制。

好的部分

function api_query_url()
{
  // Check that the URL is set and is in fact a string
  if ( ! isset( $_POST[\'url\'] ) || gettype( $_POST[\'url\'] ) !== \'string\' ) {
    api_response( false, 400, "\'url\' is a required parameter!" );
  }

  // Add an extra parameter to the url.
  $api_url = add_query_arg( \'json_vars\', time(), $_POST[\'url\'] );

  $request = wp_remote_request( $api_url );
  $content = wp_remote_retrieve_body( $request );

  if( is_wp_error($content) ){
    api_response( false, 400, "couldn\'t retrive the data" );
  }

  if( !empty($content) )
      $vars = json_decode( $content );
  else
      $vars = array();

  // pass the array to your function
  api_single( $vars );
}
add_action( \'wp_ajax_nopriv_api_query_url\', \'api_query_url\' );  
奇数部分
/* Comparing the extra parameter (json_vars), we return the json of the vars & no html */
function api_parse_request( $q )
{
    /* home/front-page doesn\'t have any q-vars */
    /* so you might be setting some defaults for that */
    $vars = $q->query_vars;
    if( isset($_REQUEST[\'json_vars\']) ){
        echo json_encode( $vars );
        die();
    }
}
add_action( \'parse_request\', \'api_parse_request\' );

结束

相关推荐

Dynamic Custom Permalinks

我有一个场景,其目的是创建可以动态更改的自定义永久链接,例如:如果显示国家信息,则URL应为http://example.com/country-information如果显示特定国家的城市信息,则URL应如下所示http://example.com/country/city-information. 我怎样才能做到这一点?