我想知道是否可以通过以下方式确定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_status
或has_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\'
. 不太好。
如果有人对我应该如何处理这个问题有任何指导,我将不胜感激。另外,如果我在处理这件事上完全错了,请告诉我。我只需要在不重新加载页面的情况下确定查询。
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_request
的WP
班
然而,很难/不鼓励将该方法用于上述目的,因为:
直接访问$_SERVER
, $_POST
和$_GET
变量,很难解析与当前HTTP请求无关的任意URL它会触发一些与当前HTTP请求解析严格相关的操作挂钩,对任意URL进行触发毫无意义。它访问并修改全局$wp
在解析请求后不应更改的变量,否则很可能会出现问题我们可以从那里的代码开始,删除不需要的部分,并使代码使用任意url,而不是当前HTTP请求中的url。
果心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\' );