English 中文(简体)
Wordpress AJAX 剖面 URL
原标题:Wordpress AJAX parse url

是否有一种方法可以解析 Wordpress 中的 URL, 用于构建查询 。 例如, 如果我想在侧边栏( 使用 < code> wp_ get_archives () 播放) 的文档列表, 这些文档是通过 AJAX 处理的, 我怎么能有 Wordpress 构建 URL 并返回 JSON 数据 。 显然, 我可以自己解析一个 URL, 并找到默认的查询, 但是如果我能使用与 Wordpress 相同的方法, 那将会很好 。 我已经查看了 $wp_ query 对象, 但不确定我如何重新使用该代码 。

//jQuery:
$( #archives a ).on( click , function(evt) {

     $.ajax({
        ....
        data: { url:  ...  }
        success: function(result) {
            //parse JSON and append to HTML
        }
        ....
     });

});

//PHP:
function process_ajax() {


    //parse url
    //figure query
    //return JSON

}

谢谢你的帮助

最佳回答

我扩展了WP类, 并覆盖了 剖析请求 () 方法, 允许对预定义的 URL 进行解析 。 函数中的大多数逻辑都完全相同, 有点多余, 但除非有人知道其他方法, 这是最好的方法。 效果很好 。

class AJAX_WP extends WP {

    /*
     *  Overwrite the parse_request function to allow for
     *  processing of urls defined in variables
    */

    function parse_request( $url ) {
        global $wp_rewrite;

        //validate url
        if(empty($url))
            return false;

        //sanitize
        $url = filter_var($url, FILTER_SANITIZE_URL);

        $this->query_vars = array();
        $post_type_query_vars = array();

        if ( is_array($extra_query_vars) )
            $this->extra_query_vars = & $extra_query_vars;
        else if (! empty($extra_query_vars))
            parse_str($extra_query_vars, $this->extra_query_vars);

        // Process PATH_INFO, REQUEST_URI, and 404 for permalinks.

        // Fetch the rewrite rules.
        $rewrite = $wp_rewrite->wp_rewrite_rules();

        if ( ! empty($rewrite) ) {
            // If we match a rewrite rule, this will be cleared.
            $error =  404 ;
            $this->did_permalink = true;

            //parse url
            $_url = parse_url($url);

            //set path info
            $pathinfo = $_url[ path ];
            $pathinfo_array = explode( ? , $pathinfo);
            $pathinfo = str_replace("%", "%25", $pathinfo_array[0]);

            //req_uri
            $req_uri = $_url[ path ];
            $req_uri_array = explode( ? , $req_uri);
            $req_uri = $req_uri_array[0];

            //self
            $self = $_url[ path ];
            $home_path = parse_url(home_url());
            if ( isset($home_path[ path ]) )
                $home_path = $home_path[ path ];
            else
                $home_path =   ;
            $home_path = trim($home_path,  / );

            // Trim path info from the end and the leading home path from the
            // front.  For path info requests, this leaves us with the requesting
            // filename, if any.  For 404 requests, this leaves us with the
            // requested permalink.
            $req_uri = str_replace($pathinfo,   , $req_uri);
            $req_uri = trim($req_uri,  / );
            $req_uri = preg_replace("|^$home_path|",   , $req_uri);
            $req_uri = trim($req_uri,  / );
            $pathinfo = trim($pathinfo,  / );
            $pathinfo = preg_replace("|^$home_path|",   , $pathinfo);
            $pathinfo = trim($pathinfo,  / );
            $self = trim($self,  / );
            $self = preg_replace("|^$home_path|",   , $self);
            $self = trim($self,  / );

            // The requested permalink is in $pathinfo for path info requests and
            //  $req_uri for other requests.
            if ( ! empty($pathinfo) && !preg_match( |^.*  . $wp_rewrite->index .  $| , $pathinfo) ) {
                $request = $pathinfo;
            } else {
                // If the request uri is the index, blank it out so that we don t try to match it against a rule.
                if ( $req_uri == $wp_rewrite->index )
                    $req_uri =   ;
                $request = $req_uri;
            }

            $this->request = $request;

            // Look for matches.
            $request_match = $request;
            if ( empty( $request_match ) ) {
                // An empty request could only match against ^$ regex
                if ( isset( $rewrite[ $ ] ) ) {
                    $this->matched_rule =  $ ;
                    $query = $rewrite[ $ ];
                    $matches = array(  );
                }
            } else if ( $req_uri !=  wp-app.php  ) {
                foreach ( (array) $rewrite as $match => $query ) {
                    // If the requesting file is the anchor of the match, prepend it to the path info.
                    if ( ! empty($req_uri) && strpos($match, $req_uri) === 0 && $req_uri != $request )
                        $request_match = $req_uri .  /  . $request;

                    if ( preg_match("#^$match#", $request_match, $matches) ||
                        preg_match("#^$match#", urldecode($request_match), $matches) ) {

                        if ( $wp_rewrite->use_verbose_page_rules && preg_match(  /pagename=$matches[([0-9]+)]/ , $query, $varmatch ) ) {
                            // this is a verbose page match, lets check to be sure about it
                            if ( ! get_page_by_path( $matches[ $varmatch[1] ] ) )
                                continue;
                        }

                        // Got a match.
                        $this->matched_rule = $match;
                        break;
                    }
                }
            }

            if ( isset( $this->matched_rule ) ) {
                // Trim the query of everything up to the  ? .
                $query = preg_replace("!^.+?!",   , $query);

                // Substitute the substring matches into the query.
                $query = addslashes(WP_MatchesMapRegex::apply($query, $matches));

                $this->matched_query = $query;

                // Parse the query.
                parse_str($query, $perma_query_vars);

                // If we re processing a 404 request, clear the error var
                // since we found something.
                unset( $_GET[ error ] );
                unset( $error );
            }

            // If req_uri is empty or if it is a request for ourself, unset error.
            if ( empty($request) || $req_uri == $self || strpos($_url[ path ],  wp-admin/ ) !== false ) {
                unset( $_GET[ error ] );
                unset( $error );

                if ( isset($perma_query_vars) && strpos($_url[ path ],  wp-admin/ ) !== false )
                    unset( $perma_query_vars );

                $this->did_permalink = false;
            }
        }

        $this->public_query_vars = apply_filters( query_vars , $this->public_query_vars);

        foreach ( $GLOBALS[ wp_post_types ] as $post_type => $t )
            if ( $t->query_var )
                $post_type_query_vars[$t->query_var] = $post_type;

        foreach ( $this->public_query_vars as $wpvar ) {
            if ( isset( $this->extra_query_vars[$wpvar] ) )
                $this->query_vars[$wpvar] = $this->extra_query_vars[$wpvar];
            elseif ( isset( $_POST[$wpvar] ) )
                $this->query_vars[$wpvar] = $_POST[$wpvar];
            elseif ( isset( $_GET[$wpvar] ) )
                $this->query_vars[$wpvar] = $_GET[$wpvar];
            elseif ( isset( $perma_query_vars[$wpvar] ) )
                $this->query_vars[$wpvar] = $perma_query_vars[$wpvar];

            if ( !empty( $this->query_vars[$wpvar] ) ) {
                if ( ! is_array( $this->query_vars[$wpvar] ) ) {
                    $this->query_vars[$wpvar] = (string) $this->query_vars[$wpvar];
                } else {
                    foreach ( $this->query_vars[$wpvar] as $vkey => $v ) {
                        if ( !is_object( $v ) ) {
                            $this->query_vars[$wpvar][$vkey] = (string) $v;
                        }
                    }
                }

                if ( isset($post_type_query_vars[$wpvar] ) ) {
                    $this->query_vars[ post_type ] = $post_type_query_vars[$wpvar];
                    $this->query_vars[ name ] = $this->query_vars[$wpvar];
                }
            }
        }

        // Convert urldecoded spaces back into +
        foreach ( $GLOBALS[ wp_taxonomies ] as $taxonomy => $t )
            if ( $t->query_var && isset( $this->query_vars[$t->query_var] ) )
                $this->query_vars[$t->query_var] = str_replace(    ,  + , $this->query_vars[$t->query_var] );

        // Limit publicly queried post_types to those that are publicly_queryable
        if ( isset( $this->query_vars[ post_type ]) ) {
            $queryable_post_types = get_post_types( array( publicly_queryable  => true) );
            if ( ! is_array( $this->query_vars[ post_type ] ) ) {
                if ( ! in_array( $this->query_vars[ post_type ], $queryable_post_types ) )
                    unset( $this->query_vars[ post_type ] );
            } else {
                $this->query_vars[ post_type ] = array_intersect( $this->query_vars[ post_type ], $queryable_post_types );
            }
        }

        foreach ( (array) $this->private_query_vars as $var) {
            if ( isset($this->extra_query_vars[$var]) )
                $this->query_vars[$var] = $this->extra_query_vars[$var];
        }

        if ( isset($error) )
            $this->query_vars[ error ] = $error;

        $this->query_vars = apply_filters( request , $this->query_vars);

        do_action_ref_array( parse_request , array(&$this));

    }

}
问题回答

我知道这是旧的,但你们真的帮助了我 所以我想我应该提前支付。这里有一个更简单的版本(我希望这更安全一点):

class PermalinkParser extends WP{


        function parse_permalink($url) {
            $path                 = parse_url($url, PHP_URL_PATH);
            $previous             = $_SERVER;
            $_SERVER[ PATH_INFO ] = $_SERVER[ REQUEST_URI ] = $path;
            $_SERVER[ PHP_SELF ]  = str_replace($_SERVER[ DOCUMENT_ROOT ],  ,  ABSPATH .  index.php );

            $this->parse_request();
            $_SERVER = $previous;
            return $this->query_vars;
        }

        function main( $query_args =    ) {
            // do not run this
        }
    }

这里是我用来和WordPress4.2.2合作的最后代码,

/**
 * An extension of the global WP object class for URL parsing / query_var generating ability over AJAX
 *
 * Essentially, it lets you specify a url.
 *
 * Example of use:
 *
 *  global $wp;
 *  $wp = new AJAX_WP();
 *  $wp->main( $url );
 *
 * @since 2015-June-2
 */
class AJAX_WP extends WP {

    /**
     * Parse request to find correct WordPress query.
     *
     * Sets up the query variables based on the request. There are also many
     * filters and actions that can be used to further manipulate the result.
     *
     * @since 2.0.0
     *
     * @param array|string $extra_query_vars Set the extra query variables.
     */
    public function parse_request( $url ) {

        global $wp_rewrite;

        //validate url
        if(empty($url))
            return false;

        //sanitize
        $url = filter_var($url, FILTER_SANITIZE_URL);

        /**
         * Filter whether to parse the request.
         *
         * @since 3.5.0
         *
         * @param bool         $bool             Whether or not to parse the request. Default true.
         * @param WP           $this             Current WordPress environment instance.
         * @param array|string $extra_query_vars Extra passed query variables.
         */
        if ( ! apply_filters(  do_parse_request , true, $this, $extra_query_vars ) )
            return;

        $this->query_vars = array();
        $post_type_query_vars = array();

        if ( is_array( $extra_query_vars ) ) {
            $this->extra_query_vars = & $extra_query_vars;
        } elseif ( ! empty( $extra_query_vars ) ) {
            parse_str( $extra_query_vars, $this->extra_query_vars );
        }
        // Process PATH_INFO, REQUEST_URI, and 404 for permalinks.

        // Fetch the rewrite rules.
        $rewrite = $wp_rewrite->wp_rewrite_rules();

        if ( ! empty($rewrite) ) {
            // If we match a rewrite rule, this will be cleared.
            $error =  404 ;
            $this->did_permalink = true;

            /*$pathinfo = isset( $_SERVER[ PATH_INFO ] ) ? $_SERVER[ PATH_INFO ] :   ;
            list( $pathinfo ) = explode(  ? , $pathinfo );
            $pathinfo = str_replace( "%", "%25", $pathinfo );

            list( $req_uri ) = explode(  ? , $_SERVER[ REQUEST_URI ] );
            $self = $_SERVER[ PHP_SELF ];
            $home_path = trim( parse_url( home_url(), PHP_URL_PATH ),  /  );*/

            //parse url
            $_url = parse_url($url);

            //set path info
            $pathinfo = $_url[ path ];
            $pathinfo_array = explode( ? , $pathinfo);
            $pathinfo = str_replace("%", "%25", $pathinfo_array[0]);

            //req_uri
            $req_uri = $_url[ path ];
            $req_uri_array = explode( ? , $req_uri);
            $req_uri = $req_uri_array[0];

            //self
            $self = $_url[ path ];
            $home_path = parse_url(home_url());
            if ( isset($home_path[ path ]) )
                $home_path = $home_path[ path ];
            else
                $home_path =   ;
            $home_path = trim($home_path,  / );


            // Trim path info from the end and the leading home path from the
            // front. For path info requests, this leaves us with the requesting
            // filename, if any. For 404 requests, this leaves us with the
            // requested permalink.
            $req_uri = str_replace($pathinfo,   , $req_uri);
            $req_uri = trim($req_uri,  / );
            $req_uri = preg_replace("|^$home_path|i",   , $req_uri);
            $req_uri = trim($req_uri,  / );
            $pathinfo = trim($pathinfo,  / );
            $pathinfo = preg_replace("|^$home_path|i",   , $pathinfo);
            $pathinfo = trim($pathinfo,  / );
            $self = trim($self,  / );
            $self = preg_replace("|^$home_path|i",   , $self);
            $self = trim($self,  / );

            // The requested permalink is in $pathinfo for path info requests and
            //  $req_uri for other requests.
            if ( ! empty($pathinfo) && !preg_match( |^.*  . $wp_rewrite->index .  $| , $pathinfo) ) {
                $request = $pathinfo;
            } else {
                // If the request uri is the index, blank it out so that we don t try to match it against a rule.
                if ( $req_uri == $wp_rewrite->index )
                    $req_uri =   ;
                $request = $req_uri;
            }

            $this->request = $request;

            // Look for matches.
            $request_match = $request;
            if ( empty( $request_match ) ) {
                // An empty request could only match against ^$ regex
                if ( isset( $rewrite[ $ ] ) ) {
                    $this->matched_rule =  $ ;
                    $query = $rewrite[ $ ];
                    $matches = array(  );
                }
            } else {
                foreach ( (array) $rewrite as $match => $query ) {
                    // If the requesting file is the anchor of the match, prepend it to the path info.
                    if ( ! empty($req_uri) && strpos($match, $req_uri) === 0 && $req_uri != $request )
                        $request_match = $req_uri .  /  . $request;

                    if ( preg_match("#^$match#", $request_match, $matches) ||
                        preg_match("#^$match#", urldecode($request_match), $matches) ) {

                        if ( $wp_rewrite->use_verbose_page_rules && preg_match(  /pagename=$matches[([0-9]+)]/ , $query, $varmatch ) ) {
                            // This is a verbose page match, let s check to be sure about it.
                            if ( ! get_page_by_path( $matches[ $varmatch[1] ] ) )
                                continue;
                        }

                        // Got a match.
                        $this->matched_rule = $match;
                        break;
                    }
                }
            }

            if ( isset( $this->matched_rule ) ) {
                // Trim the query of everything up to the  ? .
                $query = preg_replace("!^.+?!",   , $query);

                // Substitute the substring matches into the query.
                $query = addslashes(WP_MatchesMapRegex::apply($query, $matches));

                $this->matched_query = $query;

                // Parse the query.
                parse_str($query, $perma_query_vars);

                // If we re processing a 404 request, clear the error var since we found something.
                if (  404  == $error )
                    unset( $error, $_GET[ error ] );
            }

            // If req_uri is empty or if it is a request for ourself, unset error.
            if ( empty($request) || $req_uri == $self ) {
                unset( $error, $_GET[ error ] );

                /*
                Not doing this — it s AJAX and will always be true

                if ( isset($perma_query_vars) && strpos($_SERVER[ PHP_SELF ],  wp-admin/ ) !== false ) {
                    unset( $perma_query_vars );
                }*/

                $this->did_permalink = false;
            }
        }

        /**
         * Filter the query variables whitelist before processing.
         *
         * Allows (publicly allowed) query vars to be added, removed, or changed prior
         * to executing the query. Needed to allow custom rewrite rules using your own arguments
         * to work, or any other custom query variables you want to be publicly available.
         *
         * @since 1.5.0
         *
         * @param array $public_query_vars The array of whitelisted query variables.
         */
        $this->public_query_vars = apply_filters(  query_vars , $this->public_query_vars );

        foreach ( get_post_types( array(),  objects  ) as $post_type => $t )
            if ( $t->query_var )
                $post_type_query_vars[$t->query_var] = $post_type;

        foreach ( $this->public_query_vars as $wpvar ) {
            if ( isset( $this->extra_query_vars[$wpvar] ) )
                $this->query_vars[$wpvar] = $this->extra_query_vars[$wpvar];
            elseif ( isset( $_POST[$wpvar] ) )
                $this->query_vars[$wpvar] = $_POST[$wpvar];
            elseif ( isset( $_GET[$wpvar] ) )
                $this->query_vars[$wpvar] = $_GET[$wpvar];
            elseif ( isset( $perma_query_vars[$wpvar] ) ) {
                $this->query_vars[$wpvar] = $perma_query_vars[$wpvar];
                }

            if ( !empty( $this->query_vars[$wpvar] ) ) {
                if ( ! is_array( $this->query_vars[$wpvar] ) ) {
                    $this->query_vars[$wpvar] = (string) $this->query_vars[$wpvar];
                } else {
                    foreach ( $this->query_vars[$wpvar] as $vkey => $v ) {
                        if ( !is_object( $v ) ) {
                            $this->query_vars[$wpvar][$vkey] = (string) $v;
                        }
                    }
                }

                if ( isset($post_type_query_vars[$wpvar] ) ) {
                    $this->query_vars[ post_type ] = $post_type_query_vars[$wpvar];
                    $this->query_vars[ name ] = $this->query_vars[$wpvar];
                }
            }
        }

        // Convert urldecoded spaces back into +
        foreach ( get_taxonomies( array() ,  objects  ) as $taxonomy => $t )
            if ( $t->query_var && isset( $this->query_vars[$t->query_var] ) )
                $this->query_vars[$t->query_var] = str_replace(    ,  + , $this->query_vars[$t->query_var] );

        // Limit publicly queried post_types to those that are publicly_queryable
        if ( isset( $this->query_vars[ post_type ]) ) {
            $queryable_post_types = get_post_types( array( publicly_queryable  => true) );
            if ( ! is_array( $this->query_vars[ post_type ] ) ) {
                if ( ! in_array( $this->query_vars[ post_type ], $queryable_post_types ) )
                    unset( $this->query_vars[ post_type ] );
            } else {
                $this->query_vars[ post_type ] = array_intersect( $this->query_vars[ post_type ], $queryable_post_types );
            }
        }

        foreach ( (array) $this->private_query_vars as $var) {
            if ( isset($this->extra_query_vars[$var]) )
                $this->query_vars[$var] = $this->extra_query_vars[$var];
        }

        if ( isset($error) )
            $this->query_vars[ error ] = $error;

        /**
         * Filter the array of parsed query variables.
         *
         * @since 2.1.0
         *
         * @param array $query_vars The array of requested query variables.
         */
        $this->query_vars = apply_filters(  request , $this->query_vars );


        /**
         * Fires once all query variables for the current request have been parsed.
         *
         * @since 2.1.0
         *
         * @param WP &$this Current WordPress environment instance (passed by reference).
         */
        do_action_ref_array(  parse_request , array( &$this ) );

    }

    /**
     * Sets up all of the variables required by the WordPress environment.
     *
     * The action  wp  has one parameter that references the WP object. It
     * allows for accessing the properties and methods to further manipulate the
     * object.
     *
     * @since 2.0.0
     *
     * @param string|array $query_args Passed to {@link parse_request()}
     */
    public function main( $url ) {

        $this->init();
        $this->parse_request( $url );
        $this->send_headers();
        $this->query_posts();
        $this->handle_404();
        $this->register_globals();

        /**
         * Fires once the WordPress environment has been set up.
         *
         * @since 2.1.0
         *
         * @param WP &$this Current WordPress environment instance (passed by reference).
         */
        do_action_ref_array(  wp , array( &$this ) );
    }

}

我不得不加上这个过滤器,

/**
 * Make sure that all the post types are available as query variables
 *
 * This fixes a problem with AJAX_WP not returning custom post types.
 *
 * @since 2015-June-2
 * @param array $public_vars
 * @return array
 */
function ananda_ajax_public_query_post_types( $public_vars ) {

        return array_merge( get_post_types( array( publicly_queryable  => true) ), $public_vars );
}

在此添加实际过滤器 :

add_filter(  query_vars ,  ananda_ajax_public_query_post_types , 10, 1 );




相关问题
ajax login using httpRequest?

I am trying to develop my login script to give feedback to the user if the login is valid or not. Basically if it isn t correct a div box will show saying its wrong, if its correct it will show its ...

Virtual Tour using sketch up, ajax, flash technologies

I want to know if there are existing technology that make your 3d models in sketch into virtual tours, using either Ajax or Flash for web presentation. If there s none, which will be a good approach ...

How can i update div continuously

I have asp.net application where i have a div which showing the value from other site. The value of that site is changing continuously. I want that my div will automatically update in some interval ...

热门标签