Check what is at URI (post, archive, etc…)

Retrieve “type” of query from url: Previous suggestions

As noted in the linked answer, there’s url_to_postid(). This will just get you the ID of the object at that endpoint. Long story short, this function will only return an ID and then run a new \WP_Query to get the post type object from the DB and finally return the URl – if there is any and _if it is something of is_singular (a post, a page). So that function is not really helpful.

As mentioned in the comments, there’s also:

$object = get_page_by_path( 
    'path/endpoint', 
    OBJECT|ARRAY_N|ARRAY_A,
    [ 'post', 'page', 'custom_post_type', '…' ]
);

which will run the following query:

$sql = "
    SELECT ID, post_name, post_parent, post_type
    FROM $wpdb->posts
    WHERE post_name IN ( $in_string )
        AND post_type IN ( $post_types_string )
";

And again: Not helpful.

WordPress Url to Query: Behind the scenes

This is how the process looks in WordPress

-------     --------------     -------------
| URl | --> | Query Vars | --> | \WP_Query |
-------     --------------     -------------

As mentioned by @TheDeadMedic, there’s WP::parse_request() that performs all the magic:

  1. Retrieve all query vars
  2. Fetch rewrite rules
  3. Look up matches between the request and rewrite rules
  4. Run registered query variables through a whitelist filter

While doing all that, the method actually fills an associative array: WP::$query_vars:

WP::$query_vars = [
    // $_POST or $_GET or query string variables `foo=bar&baz=dragons`
    // `custom` is not the actual name. The key will be named as the var.
    'custom'    => [],
    // An array of `$postTypeObject->query_var`s
    // Only those which are publicly queryable
    'post_type' => [],
    // Only publicly queryable taxonomies
    'taxonomy'  => [],
    'term'      => [],
    'name'      => [],
    'error'     => [],
    // …
];

At the end of that method, you have two filters. The first one is:

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

where you have the above mentioned array present. Now you can start determining what kind of response your URl serves:

add_filter( 'request', function( Array $vars ) {
    // do whatever you need to do, depending on $vars in here
    return $vars;
} );

Examples of some var_dump( $vars ):

  • Date based archive:

    array (size=2)
      'year' => string '2016' (length=4)
      'monthnum' => string '04' (length=2)
    
  • Category archive:

    array (size=1)
      'category_name' => string 'alignment' (length=9)
    
  • Hierarchical Taxonomy Child:

    array (size=1)
      'category_name' => string 'parent-category/child-category-05' (length=33)
    
  • A posts single view – sticky is the same as default:

    array (size=2)
      'page' => string '' (length=0)
      'name' => string 'sticky' (length=6)