get_site_by_path

The timeline below displays how wordpress function get_site_by_path has changed across different WordPress versions. If a version is not listed, refer to the next available version below.

WordPress Version: 6.3

/**
 * Retrieves the closest matching site object by its domain and path.
 *
 * This will not necessarily return an exact match for a domain and path. Instead, it
 * breaks the domain and path into pieces that are then used to match the closest
 * possibility from a query.
 *
 * The intent of this method is to match a site object during bootstrap for a
 * requested site address
 *
 * @since 3.9.0
 * @since 4.7.0 Updated to always return a `WP_Site` object.
 *
 * @param string   $domain   Domain to check.
 * @param string   $path     Path to check.
 * @param int|null $segments Path segments to use. Defaults to null, or the full path.
 * @return WP_Site|false Site object if successful. False when no site is found.
 */
function get_site_by_path($domain, $path, $segments = null)
{
    $path_segments = array_filter(explode('/', trim($path, '/')));
    /**
     * Filters the number of path segments to consider when searching for a site.
     *
     * @since 3.9.0
     *
     * @param int|null $segments The number of path segments to consider. WordPress by default looks at
     *                           one path segment following the network path. The function default of
     *                           null only makes sense when you know the requested path should match a site.
     * @param string   $domain   The requested domain.
     * @param string   $path     The requested path, in full.
     */
    $segments = apply_filters('site_by_path_segments_count', $segments, $domain, $path);
    if (null !== $segments && count($path_segments) > $segments) {
        $path_segments = array_slice($path_segments, 0, $segments);
    }
    $paths = array();
    while (count($path_segments)) {
        $paths[] = '/' . implode('/', $path_segments) . '/';
        array_pop($path_segments);
    }
    $paths[] = '/';
    /**
     * Determines a site by its domain and path.
     *
     * This allows one to short-circuit the default logic, perhaps by
     * replacing it with a routine that is more optimal for your setup.
     *
     * Return null to avoid the short-circuit. Return false if no site
     * can be found at the requested domain and path. Otherwise, return
     * a site object.
     *
     * @since 3.9.0
     *
     * @param null|false|WP_Site $site     Site value to return by path. Default null
     *                                     to continue retrieving the site.
     * @param string             $domain   The requested domain.
     * @param string             $path     The requested path, in full.
     * @param int|null           $segments The suggested number of paths to consult.
     *                                     Default null, meaning the entire path was to be consulted.
     * @param string[]           $paths    The paths to search for, based on $path and $segments.
     */
    $pre = apply_filters('pre_get_site_by_path', null, $domain, $path, $segments, $paths);
    if (null !== $pre) {
        if (false !== $pre && !$pre instanceof WP_Site) {
            $pre = new WP_Site($pre);
        }
        return $pre;
    }
    /*
     * @todo
     * Caching, etc. Consider alternative optimization routes,
     * perhaps as an opt-in for plugins, rather than using the pre_* filter.
     * For example: The segments filter can expand or ignore paths.
     * If persistent caching is enabled, we could query the DB for a path <> '/'
     * then cache whether we can just always ignore paths.
     */
    /*
     * Either www or non-www is supported, not both. If a www domain is requested,
     * query for both to provide the proper redirect.
     */
    $domains = array($domain);
    if (str_starts_with($domain, 'www.')) {
        $domains[] = substr($domain, 4);
    }
    $args = array('number' => 1, 'update_site_meta_cache' => false);
    if (count($domains) > 1) {
        $args['domain__in'] = $domains;
        $args['orderby']['domain_length'] = 'DESC';
    } else {
        $args['domain'] = array_shift($domains);
    }
    if (count($paths) > 1) {
        $args['path__in'] = $paths;
        $args['orderby']['path_length'] = 'DESC';
    } else {
        $args['path'] = array_shift($paths);
    }
    $result = get_sites($args);
    $site = array_shift($result);
    if ($site) {
        return $site;
    }
    return false;
}

WordPress Version: 6.1

/**
 * Retrieves the closest matching site object by its domain and path.
 *
 * This will not necessarily return an exact match for a domain and path. Instead, it
 * breaks the domain and path into pieces that are then used to match the closest
 * possibility from a query.
 *
 * The intent of this method is to match a site object during bootstrap for a
 * requested site address
 *
 * @since 3.9.0
 * @since 4.7.0 Updated to always return a `WP_Site` object.
 *
 * @param string   $domain   Domain to check.
 * @param string   $path     Path to check.
 * @param int|null $segments Path segments to use. Defaults to null, or the full path.
 * @return WP_Site|false Site object if successful. False when no site is found.
 */
function get_site_by_path($domain, $path, $segments = null)
{
    $path_segments = array_filter(explode('/', trim($path, '/')));
    /**
     * Filters the number of path segments to consider when searching for a site.
     *
     * @since 3.9.0
     *
     * @param int|null $segments The number of path segments to consider. WordPress by default looks at
     *                           one path segment following the network path. The function default of
     *                           null only makes sense when you know the requested path should match a site.
     * @param string   $domain   The requested domain.
     * @param string   $path     The requested path, in full.
     */
    $segments = apply_filters('site_by_path_segments_count', $segments, $domain, $path);
    if (null !== $segments && count($path_segments) > $segments) {
        $path_segments = array_slice($path_segments, 0, $segments);
    }
    $paths = array();
    while (count($path_segments)) {
        $paths[] = '/' . implode('/', $path_segments) . '/';
        array_pop($path_segments);
    }
    $paths[] = '/';
    /**
     * Determines a site by its domain and path.
     *
     * This allows one to short-circuit the default logic, perhaps by
     * replacing it with a routine that is more optimal for your setup.
     *
     * Return null to avoid the short-circuit. Return false if no site
     * can be found at the requested domain and path. Otherwise, return
     * a site object.
     *
     * @since 3.9.0
     *
     * @param null|false|WP_Site $site     Site value to return by path. Default null
     *                                     to continue retrieving the site.
     * @param string             $domain   The requested domain.
     * @param string             $path     The requested path, in full.
     * @param int|null           $segments The suggested number of paths to consult.
     *                                     Default null, meaning the entire path was to be consulted.
     * @param string[]           $paths    The paths to search for, based on $path and $segments.
     */
    $pre = apply_filters('pre_get_site_by_path', null, $domain, $path, $segments, $paths);
    if (null !== $pre) {
        if (false !== $pre && !$pre instanceof WP_Site) {
            $pre = new WP_Site($pre);
        }
        return $pre;
    }
    /*
     * @todo
     * Caching, etc. Consider alternative optimization routes,
     * perhaps as an opt-in for plugins, rather than using the pre_* filter.
     * For example: The segments filter can expand or ignore paths.
     * If persistent caching is enabled, we could query the DB for a path <> '/'
     * then cache whether we can just always ignore paths.
     */
    // Either www or non-www is supported, not both. If a www domain is requested,
    // query for both to provide the proper redirect.
    $domains = array($domain);
    if ('www.' === substr($domain, 0, 4)) {
        $domains[] = substr($domain, 4);
    }
    $args = array('number' => 1, 'update_site_meta_cache' => false);
    if (count($domains) > 1) {
        $args['domain__in'] = $domains;
        $args['orderby']['domain_length'] = 'DESC';
    } else {
        $args['domain'] = array_shift($domains);
    }
    if (count($paths) > 1) {
        $args['path__in'] = $paths;
        $args['orderby']['path_length'] = 'DESC';
    } else {
        $args['path'] = array_shift($paths);
    }
    $result = get_sites($args);
    $site = array_shift($result);
    if ($site) {
        return $site;
    }
    return false;
}

WordPress Version: 5.6

/**
 * Retrieves the closest matching site object by its domain and path.
 *
 * This will not necessarily return an exact match for a domain and path. Instead, it
 * breaks the domain and path into pieces that are then used to match the closest
 * possibility from a query.
 *
 * The intent of this method is to match a site object during bootstrap for a
 * requested site address
 *
 * @since 3.9.0
 * @since 4.7.0 Updated to always return a `WP_Site` object.
 *
 * @param string   $domain   Domain to check.
 * @param string   $path     Path to check.
 * @param int|null $segments Path segments to use. Defaults to null, or the full path.
 * @return WP_Site|false Site object if successful. False when no site is found.
 */
function get_site_by_path($domain, $path, $segments = null)
{
    $path_segments = array_filter(explode('/', trim($path, '/')));
    /**
     * Filters the number of path segments to consider when searching for a site.
     *
     * @since 3.9.0
     *
     * @param int|null $segments The number of path segments to consider. WordPress by default looks at
     *                           one path segment following the network path. The function default of
     *                           null only makes sense when you know the requested path should match a site.
     * @param string   $domain   The requested domain.
     * @param string   $path     The requested path, in full.
     */
    $segments = apply_filters('site_by_path_segments_count', $segments, $domain, $path);
    if (null !== $segments && count($path_segments) > $segments) {
        $path_segments = array_slice($path_segments, 0, $segments);
    }
    $paths = array();
    while (count($path_segments)) {
        $paths[] = '/' . implode('/', $path_segments) . '/';
        array_pop($path_segments);
    }
    $paths[] = '/';
    /**
     * Determine a site by its domain and path.
     *
     * This allows one to short-circuit the default logic, perhaps by
     * replacing it with a routine that is more optimal for your setup.
     *
     * Return null to avoid the short-circuit. Return false if no site
     * can be found at the requested domain and path. Otherwise, return
     * a site object.
     *
     * @since 3.9.0
     *
     * @param null|false|WP_Site $site     Site value to return by path. Default null
     *                                     to continue retrieving the site.
     * @param string             $domain   The requested domain.
     * @param string             $path     The requested path, in full.
     * @param int|null           $segments The suggested number of paths to consult.
     *                                     Default null, meaning the entire path was to be consulted.
     * @param string[]           $paths    The paths to search for, based on $path and $segments.
     */
    $pre = apply_filters('pre_get_site_by_path', null, $domain, $path, $segments, $paths);
    if (null !== $pre) {
        if (false !== $pre && !$pre instanceof WP_Site) {
            $pre = new WP_Site($pre);
        }
        return $pre;
    }
    /*
     * @todo
     * Caching, etc. Consider alternative optimization routes,
     * perhaps as an opt-in for plugins, rather than using the pre_* filter.
     * For example: The segments filter can expand or ignore paths.
     * If persistent caching is enabled, we could query the DB for a path <> '/'
     * then cache whether we can just always ignore paths.
     */
    // Either www or non-www is supported, not both. If a www domain is requested,
    // query for both to provide the proper redirect.
    $domains = array($domain);
    if ('www.' === substr($domain, 0, 4)) {
        $domains[] = substr($domain, 4);
    }
    $args = array('number' => 1, 'update_site_meta_cache' => false);
    if (count($domains) > 1) {
        $args['domain__in'] = $domains;
        $args['orderby']['domain_length'] = 'DESC';
    } else {
        $args['domain'] = array_shift($domains);
    }
    if (count($paths) > 1) {
        $args['path__in'] = $paths;
        $args['orderby']['path_length'] = 'DESC';
    } else {
        $args['path'] = array_shift($paths);
    }
    $result = get_sites($args);
    $site = array_shift($result);
    if ($site) {
        return $site;
    }
    return false;
}

WordPress Version: 5.4

/**
 * Retrieves the closest matching site object by its domain and path.
 *
 * This will not necessarily return an exact match for a domain and path. Instead, it
 * breaks the domain and path into pieces that are then used to match the closest
 * possibility from a query.
 *
 * The intent of this method is to match a site object during bootstrap for a
 * requested site address
 *
 * @since 3.9.0
 * @since 4.7.0 Updated to always return a `WP_Site` object.
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param string   $domain   Domain to check.
 * @param string   $path     Path to check.
 * @param int|null $segments Path segments to use. Defaults to null, or the full path.
 * @return WP_Site|false Site object if successful. False when no site is found.
 */
function get_site_by_path($domain, $path, $segments = null)
{
    $path_segments = array_filter(explode('/', trim($path, '/')));
    /**
     * Filters the number of path segments to consider when searching for a site.
     *
     * @since 3.9.0
     *
     * @param int|null $segments The number of path segments to consider. WordPress by default looks at
     *                           one path segment following the network path. The function default of
     *                           null only makes sense when you know the requested path should match a site.
     * @param string   $domain   The requested domain.
     * @param string   $path     The requested path, in full.
     */
    $segments = apply_filters('site_by_path_segments_count', $segments, $domain, $path);
    if (null !== $segments && count($path_segments) > $segments) {
        $path_segments = array_slice($path_segments, 0, $segments);
    }
    $paths = array();
    while (count($path_segments)) {
        $paths[] = '/' . implode('/', $path_segments) . '/';
        array_pop($path_segments);
    }
    $paths[] = '/';
    /**
     * Determine a site by its domain and path.
     *
     * This allows one to short-circuit the default logic, perhaps by
     * replacing it with a routine that is more optimal for your setup.
     *
     * Return null to avoid the short-circuit. Return false if no site
     * can be found at the requested domain and path. Otherwise, return
     * a site object.
     *
     * @since 3.9.0
     *
     * @param null|false|WP_Site $site     Site value to return by path. Default null
     *                                     to continue retrieving the site.
     * @param string             $domain   The requested domain.
     * @param string             $path     The requested path, in full.
     * @param int|null           $segments The suggested number of paths to consult.
     *                                     Default null, meaning the entire path was to be consulted.
     * @param string[]           $paths    The paths to search for, based on $path and $segments.
     */
    $pre = apply_filters('pre_get_site_by_path', null, $domain, $path, $segments, $paths);
    if (null !== $pre) {
        if (false !== $pre && !$pre instanceof WP_Site) {
            $pre = new WP_Site($pre);
        }
        return $pre;
    }
    /*
     * @todo
     * Caching, etc. Consider alternative optimization routes,
     * perhaps as an opt-in for plugins, rather than using the pre_* filter.
     * For example: The segments filter can expand or ignore paths.
     * If persistent caching is enabled, we could query the DB for a path <> '/'
     * then cache whether we can just always ignore paths.
     */
    // Either www or non-www is supported, not both. If a www domain is requested,
    // query for both to provide the proper redirect.
    $domains = array($domain);
    if ('www.' === substr($domain, 0, 4)) {
        $domains[] = substr($domain, 4);
    }
    $args = array('number' => 1, 'update_site_meta_cache' => false);
    if (count($domains) > 1) {
        $args['domain__in'] = $domains;
        $args['orderby']['domain_length'] = 'DESC';
    } else {
        $args['domain'] = array_shift($domains);
    }
    if (count($paths) > 1) {
        $args['path__in'] = $paths;
        $args['orderby']['path_length'] = 'DESC';
    } else {
        $args['path'] = array_shift($paths);
    }
    $result = get_sites($args);
    $site = array_shift($result);
    if ($site) {
        return $site;
    }
    return false;
}

WordPress Version: 5.3

/**
 * Retrieves the closest matching site object by its domain and path.
 *
 * This will not necessarily return an exact match for a domain and path. Instead, it
 * breaks the domain and path into pieces that are then used to match the closest
 * possibility from a query.
 *
 * The intent of this method is to match a site object during bootstrap for a
 * requested site address
 *
 * @since 3.9.0
 * @since 4.7.0 Updated to always return a `WP_Site` object.
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param string   $domain   Domain to check.
 * @param string   $path     Path to check.
 * @param int|null $segments Path segments to use. Defaults to null, or the full path.
 * @return WP_Site|false Site object if successful. False when no site is found.
 */
function get_site_by_path($domain, $path, $segments = null)
{
    $path_segments = array_filter(explode('/', trim($path, '/')));
    /**
     * Filters the number of path segments to consider when searching for a site.
     *
     * @since 3.9.0
     *
     * @param int|null $segments The number of path segments to consider. WordPress by default looks at
     *                           one path segment following the network path. The function default of
     *                           null only makes sense when you know the requested path should match a site.
     * @param string   $domain   The requested domain.
     * @param string   $path     The requested path, in full.
     */
    $segments = apply_filters('site_by_path_segments_count', $segments, $domain, $path);
    if (null !== $segments && count($path_segments) > $segments) {
        $path_segments = array_slice($path_segments, 0, $segments);
    }
    $paths = array();
    while (count($path_segments)) {
        $paths[] = '/' . implode('/', $path_segments) . '/';
        array_pop($path_segments);
    }
    $paths[] = '/';
    /**
     * Determine a site by its domain and path.
     *
     * This allows one to short-circuit the default logic, perhaps by
     * replacing it with a routine that is more optimal for your setup.
     *
     * Return null to avoid the short-circuit. Return false if no site
     * can be found at the requested domain and path. Otherwise, return
     * a site object.
     *
     * @since 3.9.0
     *
     * @param null|false|WP_Site $site     Site value to return by path.
     * @param string             $domain   The requested domain.
     * @param string             $path     The requested path, in full.
     * @param int|null           $segments The suggested number of paths to consult.
     *                                     Default null, meaning the entire path was to be consulted.
     * @param array              $paths    The paths to search for, based on $path and $segments.
     */
    $pre = apply_filters('pre_get_site_by_path', null, $domain, $path, $segments, $paths);
    if (null !== $pre) {
        if (false !== $pre && !$pre instanceof WP_Site) {
            $pre = new WP_Site($pre);
        }
        return $pre;
    }
    /*
     * @todo
     * caching, etc. Consider alternative optimization routes,
     * perhaps as an opt-in for plugins, rather than using the pre_* filter.
     * For example: The segments filter can expand or ignore paths.
     * If persistent caching is enabled, we could query the DB for a path <> '/'
     * then cache whether we can just always ignore paths.
     */
    // Either www or non-www is supported, not both. If a www domain is requested,
    // query for both to provide the proper redirect.
    $domains = array($domain);
    if ('www.' === substr($domain, 0, 4)) {
        $domains[] = substr($domain, 4);
    }
    $args = array('number' => 1, 'update_site_meta_cache' => false);
    if (count($domains) > 1) {
        $args['domain__in'] = $domains;
        $args['orderby']['domain_length'] = 'DESC';
    } else {
        $args['domain'] = array_shift($domains);
    }
    if (count($paths) > 1) {
        $args['path__in'] = $paths;
        $args['orderby']['path_length'] = 'DESC';
    } else {
        $args['path'] = array_shift($paths);
    }
    $result = get_sites($args);
    $site = array_shift($result);
    if ($site) {
        return $site;
    }
    return false;
}

WordPress Version: .10

/**
 * Retrieves the closest matching site object by its domain and path.
 *
 * This will not necessarily return an exact match for a domain and path. Instead, it
 * breaks the domain and path into pieces that are then used to match the closest
 * possibility from a query.
 *
 * The intent of this method is to match a site object during bootstrap for a
 * requested site address
 *
 * @since 3.9.0
 * @since 4.7.0 Updated to always return a `WP_Site` object.
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param string   $domain   Domain to check.
 * @param string   $path     Path to check.
 * @param int|null $segments Path segments to use. Defaults to null, or the full path.
 * @return WP_Site|false Site object if successful. False when no site is found.
 */
function get_site_by_path($domain, $path, $segments = null)
{
    $path_segments = array_filter(explode('/', trim($path, '/')));
    /**
     * Filters the number of path segments to consider when searching for a site.
     *
     * @since 3.9.0
     *
     * @param int|null $segments The number of path segments to consider. WordPress by default looks at
     *                           one path segment following the network path. The function default of
     *                           null only makes sense when you know the requested path should match a site.
     * @param string   $domain   The requested domain.
     * @param string   $path     The requested path, in full.
     */
    $segments = apply_filters('site_by_path_segments_count', $segments, $domain, $path);
    if (null !== $segments && count($path_segments) > $segments) {
        $path_segments = array_slice($path_segments, 0, $segments);
    }
    $paths = array();
    while (count($path_segments)) {
        $paths[] = '/' . implode('/', $path_segments) . '/';
        array_pop($path_segments);
    }
    $paths[] = '/';
    /**
     * Determine a site by its domain and path.
     *
     * This allows one to short-circuit the default logic, perhaps by
     * replacing it with a routine that is more optimal for your setup.
     *
     * Return null to avoid the short-circuit. Return false if no site
     * can be found at the requested domain and path. Otherwise, return
     * a site object.
     *
     * @since 3.9.0
     *
     * @param null|bool|WP_Site $site     Site value to return by path.
     * @param string            $domain   The requested domain.
     * @param string            $path     The requested path, in full.
     * @param int|null          $segments The suggested number of paths to consult.
     *                                    Default null, meaning the entire path was to be consulted.
     * @param array             $paths    The paths to search for, based on $path and $segments.
     */
    $pre = apply_filters('pre_get_site_by_path', null, $domain, $path, $segments, $paths);
    if (null !== $pre) {
        if (false !== $pre && !$pre instanceof WP_Site) {
            $pre = new WP_Site($pre);
        }
        return $pre;
    }
    /*
     * @todo
     * caching, etc. Consider alternative optimization routes,
     * perhaps as an opt-in for plugins, rather than using the pre_* filter.
     * For example: The segments filter can expand or ignore paths.
     * If persistent caching is enabled, we could query the DB for a path <> '/'
     * then cache whether we can just always ignore paths.
     */
    // Either www or non-www is supported, not both. If a www domain is requested,
    // query for both to provide the proper redirect.
    $domains = array($domain);
    if ('www.' === substr($domain, 0, 4)) {
        $domains[] = substr($domain, 4);
    }
    $args = array('number' => 1, 'update_site_meta_cache' => false);
    if (count($domains) > 1) {
        $args['domain__in'] = $domains;
        $args['orderby']['domain_length'] = 'DESC';
    } else {
        $args['domain'] = array_shift($domains);
    }
    if (count($paths) > 1) {
        $args['path__in'] = $paths;
        $args['orderby']['path_length'] = 'DESC';
    } else {
        $args['path'] = array_shift($paths);
    }
    $result = get_sites($args);
    $site = array_shift($result);
    if ($site) {
        return $site;
    }
    return false;
}

WordPress Version: 5.1

/**
 * Retrieves the closest matching site object by its domain and path.
 *
 * This will not necessarily return an exact match for a domain and path. Instead, it
 * breaks the domain and path into pieces that are then used to match the closest
 * possibility from a query.
 *
 * The intent of this method is to match a site object during bootstrap for a
 * requested site address
 *
 * @since 3.9.0
 * @since 4.7.0 Updated to always return a `WP_Site` object.
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param string   $domain   Domain to check.
 * @param string   $path     Path to check.
 * @param int|null $segments Path segments to use. Defaults to null, or the full path.
 * @return WP_Site|false Site object if successful. False when no site is found.
 */
function get_site_by_path($domain, $path, $segments = null)
{
    $path_segments = array_filter(explode('/', trim($path, '/')));
    /**
     * Filters the number of path segments to consider when searching for a site.
     *
     * @since 3.9.0
     *
     * @param int|null $segments The number of path segments to consider. WordPress by default looks at
     *                           one path segment following the network path. The function default of
     *                           null only makes sense when you know the requested path should match a site.
     * @param string   $domain   The requested domain.
     * @param string   $path     The requested path, in full.
     */
    $segments = apply_filters('site_by_path_segments_count', $segments, $domain, $path);
    if (null !== $segments && count($path_segments) > $segments) {
        $path_segments = array_slice($path_segments, 0, $segments);
    }
    $paths = array();
    while (count($path_segments)) {
        $paths[] = '/' . implode('/', $path_segments) . '/';
        array_pop($path_segments);
    }
    $paths[] = '/';
    /**
     * Determine a site by its domain and path.
     *
     * This allows one to short-circuit the default logic, perhaps by
     * replacing it with a routine that is more optimal for your setup.
     *
     * Return null to avoid the short-circuit. Return false if no site
     * can be found at the requested domain and path. Otherwise, return
     * a site object.
     *
     * @since 3.9.0
     *
     * @param null|bool|WP_Site $site     Site value to return by path.
     * @param string            $domain   The requested domain.
     * @param string            $path     The requested path, in full.
     * @param int|null          $segments The suggested number of paths to consult.
     *                                    Default null, meaning the entire path was to be consulted.
     * @param array             $paths    The paths to search for, based on $path and $segments.
     */
    $pre = apply_filters('pre_get_site_by_path', null, $domain, $path, $segments, $paths);
    if (null !== $pre) {
        if (false !== $pre && !$pre instanceof WP_Site) {
            $pre = new WP_Site($pre);
        }
        return $pre;
    }
    /*
     * @todo
     * caching, etc. Consider alternative optimization routes,
     * perhaps as an opt-in for plugins, rather than using the pre_* filter.
     * For example: The segments filter can expand or ignore paths.
     * If persistent caching is enabled, we could query the DB for a path <> '/'
     * then cache whether we can just always ignore paths.
     */
    // Either www or non-www is supported, not both. If a www domain is requested,
    // query for both to provide the proper redirect.
    $domains = array($domain);
    if ('www.' === substr($domain, 0, 4)) {
        $domains[] = substr($domain, 4);
    }
    $args = array('number' => 1);
    if (count($domains) > 1) {
        $args['domain__in'] = $domains;
        $args['orderby']['domain_length'] = 'DESC';
    } else {
        $args['domain'] = array_shift($domains);
    }
    if (count($paths) > 1) {
        $args['path__in'] = $paths;
        $args['orderby']['path_length'] = 'DESC';
    } else {
        $args['path'] = array_shift($paths);
    }
    $result = get_sites($args);
    $site = array_shift($result);
    if ($site) {
        return $site;
    }
    return false;
}

WordPress Version: 4.9

/**
 * Retrieves the closest matching site object by its domain and path.
 *
 * This will not necessarily return an exact match for a domain and path. Instead, it
 * breaks the domain and path into pieces that are then used to match the closest
 * possibility from a query.
 *
 * The intent of this method is to match a site object during bootstrap for a
 * requested site address
 *
 * @since 3.9.0
 * @since 4.7.0 Updated to always return a `WP_Site` object.
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param string   $domain   Domain to check.
 * @param string   $path     Path to check.
 * @param int|null $segments Path segments to use. Defaults to null, or the full path.
 * @return WP_Site|false Site object if successful. False when no site is found.
 */
function get_site_by_path($domain, $path, $segments = null)
{
    $path_segments = array_filter(explode('/', trim($path, '/')));
    /**
     * Filters the number of path segments to consider when searching for a site.
     *
     * @since 3.9.0
     *
     * @param int|null $segments The number of path segments to consider. WordPress by default looks at
     *                           one path segment following the network path. The function default of
     *                           null only makes sense when you know the requested path should match a site.
     * @param string   $domain   The requested domain.
     * @param string   $path     The requested path, in full.
     */
    $segments = apply_filters('site_by_path_segments_count', $segments, $domain, $path);
    if (null !== $segments && count($path_segments) > $segments) {
        $path_segments = array_slice($path_segments, 0, $segments);
    }
    $paths = array();
    while (count($path_segments)) {
        $paths[] = '/' . implode('/', $path_segments) . '/';
        array_pop($path_segments);
    }
    $paths[] = '/';
    /**
     * Determine a site by its domain and path.
     *
     * This allows one to short-circuit the default logic, perhaps by
     * replacing it with a routine that is more optimal for your setup.
     *
     * Return null to avoid the short-circuit. Return false if no site
     * can be found at the requested domain and path. Otherwise, return
     * a site object.
     *
     * @since 3.9.0
     *
     * @param null|bool|WP_Site $site     Site value to return by path.
     * @param string            $domain   The requested domain.
     * @param string            $path     The requested path, in full.
     * @param int|null          $segments The suggested number of paths to consult.
     *                                    Default null, meaning the entire path was to be consulted.
     * @param array             $paths    The paths to search for, based on $path and $segments.
     */
    $pre = apply_filters('pre_get_site_by_path', null, $domain, $path, $segments, $paths);
    if (null !== $pre) {
        if (false !== $pre && !$pre instanceof WP_Site) {
            $pre = new WP_Site($pre);
        }
        return $pre;
    }
    /*
     * @todo
     * caching, etc. Consider alternative optimization routes,
     * perhaps as an opt-in for plugins, rather than using the pre_* filter.
     * For example: The segments filter can expand or ignore paths.
     * If persistent caching is enabled, we could query the DB for a path <> '/'
     * then cache whether we can just always ignore paths.
     */
    // Either www or non-www is supported, not both. If a www domain is requested,
    // query for both to provide the proper redirect.
    $domains = array($domain);
    if ('www.' === substr($domain, 0, 4)) {
        $domains[] = substr($domain, 4);
    }
    $args = array('domain__in' => $domains, 'path__in' => $paths, 'number' => 1);
    if (count($domains) > 1) {
        $args['orderby']['domain_length'] = 'DESC';
    }
    if (count($paths) > 1) {
        $args['orderby']['path_length'] = 'DESC';
    }
    $result = get_sites($args);
    $site = array_shift($result);
    if ($site) {
        return $site;
    }
    return false;
}

WordPress Version: 4.7

/**
 * Retrieves the closest matching site object by its domain and path.
 * 
 * This will not necessarily return an exact match for a domain and path. Instead, it
 * breaks the domain and path into pieces that are then used to match the closest
 * possibility from a query.
 *
 * The intent of this method is to match a site object during bootstrap for a
 * requested site address
 *
 * @since 3.9.0
 * @since 4.7.0 Updated to always return a `WP_Site` object.
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param string   $domain   Domain to check.
 * @param string   $path     Path to check.
 * @param int|null $segments Path segments to use. Defaults to null, or the full path.
 * @return WP_Site|false Site object if successful. False when no site is found.
 */
function get_site_by_path($domain, $path, $segments = null)
{
    $path_segments = array_filter(explode('/', trim($path, '/')));
    /**
     * Filters the number of path segments to consider when searching for a site.
     *
     * @since 3.9.0
     *
     * @param int|null $segments The number of path segments to consider. WordPress by default looks at
     *                           one path segment following the network path. The function default of
     *                           null only makes sense when you know the requested path should match a site.
     * @param string   $domain   The requested domain.
     * @param string   $path     The requested path, in full.
     */
    $segments = apply_filters('site_by_path_segments_count', $segments, $domain, $path);
    if (null !== $segments && count($path_segments) > $segments) {
        $path_segments = array_slice($path_segments, 0, $segments);
    }
    $paths = array();
    while (count($path_segments)) {
        $paths[] = '/' . implode('/', $path_segments) . '/';
        array_pop($path_segments);
    }
    $paths[] = '/';
    /**
     * Determine a site by its domain and path.
     *
     * This allows one to short-circuit the default logic, perhaps by
     * replacing it with a routine that is more optimal for your setup.
     *
     * Return null to avoid the short-circuit. Return false if no site
     * can be found at the requested domain and path. Otherwise, return
     * a site object.
     *
     * @since 3.9.0
     *
     * @param null|bool|WP_Site $site     Site value to return by path.
     * @param string            $domain   The requested domain.
     * @param string            $path     The requested path, in full.
     * @param int|null          $segments The suggested number of paths to consult.
     *                                    Default null, meaning the entire path was to be consulted.
     * @param array             $paths    The paths to search for, based on $path and $segments.
     */
    $pre = apply_filters('pre_get_site_by_path', null, $domain, $path, $segments, $paths);
    if (null !== $pre) {
        if (false !== $pre && !$pre instanceof WP_Site) {
            $pre = new WP_Site($pre);
        }
        return $pre;
    }
    /*
     * @todo
     * caching, etc. Consider alternative optimization routes,
     * perhaps as an opt-in for plugins, rather than using the pre_* filter.
     * For example: The segments filter can expand or ignore paths.
     * If persistent caching is enabled, we could query the DB for a path <> '/'
     * then cache whether we can just always ignore paths.
     */
    // Either www or non-www is supported, not both. If a www domain is requested,
    // query for both to provide the proper redirect.
    $domains = array($domain);
    if ('www.' === substr($domain, 0, 4)) {
        $domains[] = substr($domain, 4);
    }
    $args = array('domain__in' => $domains, 'path__in' => $paths, 'number' => 1);
    if (count($domains) > 1) {
        $args['orderby']['domain_length'] = 'DESC';
    }
    if (count($paths) > 1) {
        $args['orderby']['path_length'] = 'DESC';
    }
    $result = get_sites($args);
    $site = array_shift($result);
    if ($site) {
        return $site;
    }
    return false;
}

WordPress Version: 4.6

/**
 * Retrieve a site object by its domain and path.
 *
 * @since 3.9.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param string   $domain   Domain to check.
 * @param string   $path     Path to check.
 * @param int|null $segments Path segments to use. Defaults to null, or the full path.
 * @return object|false Site object if successful. False when no site is found.
 */
function get_site_by_path($domain, $path, $segments = null)
{
    $path_segments = array_filter(explode('/', trim($path, '/')));
    /**
     * Filters the number of path segments to consider when searching for a site.
     *
     * @since 3.9.0
     *
     * @param int|null $segments The number of path segments to consider. WordPress by default looks at
     *                           one path segment following the network path. The function default of
     *                           null only makes sense when you know the requested path should match a site.
     * @param string   $domain   The requested domain.
     * @param string   $path     The requested path, in full.
     */
    $segments = apply_filters('site_by_path_segments_count', $segments, $domain, $path);
    if (null !== $segments && count($path_segments) > $segments) {
        $path_segments = array_slice($path_segments, 0, $segments);
    }
    $paths = array();
    while (count($path_segments)) {
        $paths[] = '/' . implode('/', $path_segments) . '/';
        array_pop($path_segments);
    }
    $paths[] = '/';
    /**
     * Determine a site by its domain and path.
     *
     * This allows one to short-circuit the default logic, perhaps by
     * replacing it with a routine that is more optimal for your setup.
     *
     * Return null to avoid the short-circuit. Return false if no site
     * can be found at the requested domain and path. Otherwise, return
     * a site object.
     *
     * @since 3.9.0
     *
     * @param null|bool|object $site     Site value to return by path.
     * @param string           $domain   The requested domain.
     * @param string           $path     The requested path, in full.
     * @param int|null         $segments The suggested number of paths to consult.
     *                                   Default null, meaning the entire path was to be consulted.
     * @param array            $paths    The paths to search for, based on $path and $segments.
     */
    $pre = apply_filters('pre_get_site_by_path', null, $domain, $path, $segments, $paths);
    if (null !== $pre) {
        return $pre;
    }
    /*
     * @todo
     * get_blog_details(), caching, etc. Consider alternative optimization routes,
     * perhaps as an opt-in for plugins, rather than using the pre_* filter.
     * For example: The segments filter can expand or ignore paths.
     * If persistent caching is enabled, we could query the DB for a path <> '/'
     * then cache whether we can just always ignore paths.
     */
    // Either www or non-www is supported, not both. If a www domain is requested,
    // query for both to provide the proper redirect.
    $domains = array($domain);
    if ('www.' === substr($domain, 0, 4)) {
        $domains[] = substr($domain, 4);
    }
    $args = array('domain__in' => $domains, 'path__in' => $paths, 'number' => 1);
    if (count($domains) > 1) {
        $args['orderby']['domain_length'] = 'DESC';
    }
    if (count($paths) > 1) {
        $args['orderby']['path_length'] = 'DESC';
    }
    $result = get_sites($args);
    $site = array_shift($result);
    if ($site) {
        // @todo get_blog_details()
        return $site;
    }
    return false;
}

WordPress Version: 4.4

/**
 * Retrieve a site object by its domain and path.
 *
 * @since 3.9.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param string   $domain   Domain to check.
 * @param string   $path     Path to check.
 * @param int|null $segments Path segments to use. Defaults to null, or the full path.
 * @return object|false Site object if successful. False when no site is found.
 */
function get_site_by_path($domain, $path, $segments = null)
{
    global $wpdb;
    $path_segments = array_filter(explode('/', trim($path, '/')));
    /**
     * Filter the number of path segments to consider when searching for a site.
     *
     * @since 3.9.0
     *
     * @param int|null $segments The number of path segments to consider. WordPress by default looks at
     *                           one path segment following the network path. The function default of
     *                           null only makes sense when you know the requested path should match a site.
     * @param string   $domain   The requested domain.
     * @param string   $path     The requested path, in full.
     */
    $segments = apply_filters('site_by_path_segments_count', $segments, $domain, $path);
    if (null !== $segments && count($path_segments) > $segments) {
        $path_segments = array_slice($path_segments, 0, $segments);
    }
    $paths = array();
    while (count($path_segments)) {
        $paths[] = '/' . implode('/', $path_segments) . '/';
        array_pop($path_segments);
    }
    $paths[] = '/';
    /**
     * Determine a site by its domain and path.
     *
     * This allows one to short-circuit the default logic, perhaps by
     * replacing it with a routine that is more optimal for your setup.
     *
     * Return null to avoid the short-circuit. Return false if no site
     * can be found at the requested domain and path. Otherwise, return
     * a site object.
     *
     * @since 3.9.0
     *
     * @param null|bool|object $site     Site value to return by path.
     * @param string           $domain   The requested domain.
     * @param string           $path     The requested path, in full.
     * @param int|null         $segments The suggested number of paths to consult.
     *                                   Default null, meaning the entire path was to be consulted.
     * @param array            $paths    The paths to search for, based on $path and $segments.
     */
    $pre = apply_filters('pre_get_site_by_path', null, $domain, $path, $segments, $paths);
    if (null !== $pre) {
        return $pre;
    }
    /*
     * @todo
     * get_blog_details(), caching, etc. Consider alternative optimization routes,
     * perhaps as an opt-in for plugins, rather than using the pre_* filter.
     * For example: The segments filter can expand or ignore paths.
     * If persistent caching is enabled, we could query the DB for a path <> '/'
     * then cache whether we can just always ignore paths.
     */
    // Either www or non-www is supported, not both. If a www domain is requested,
    // query for both to provide the proper redirect.
    $domains = array($domain);
    if ('www.' === substr($domain, 0, 4)) {
        $domains[] = substr($domain, 4);
        $search_domains = "'" . implode("', '", $wpdb->_escape($domains)) . "'";
    }
    if (count($paths) > 1) {
        $search_paths = "'" . implode("', '", $wpdb->_escape($paths)) . "'";
    }
    if (count($domains) > 1 && count($paths) > 1) {
        $site = $wpdb->get_row("SELECT * FROM {$wpdb->blogs} WHERE domain IN ({$search_domains}) AND path IN ({$search_paths}) ORDER BY CHAR_LENGTH(domain) DESC, CHAR_LENGTH(path) DESC LIMIT 1");
    } elseif (count($domains) > 1) {
        $sql = $wpdb->prepare("SELECT * FROM {$wpdb->blogs} WHERE path = %s", $paths[0]);
        $sql .= " AND domain IN ({$search_domains}) ORDER BY CHAR_LENGTH(domain) DESC LIMIT 1";
        $site = $wpdb->get_row($sql);
    } elseif (count($paths) > 1) {
        $sql = $wpdb->prepare("SELECT * FROM {$wpdb->blogs} WHERE domain = %s", $domains[0]);
        $sql .= " AND path IN ({$search_paths}) ORDER BY CHAR_LENGTH(path) DESC LIMIT 1";
        $site = $wpdb->get_row($sql);
    } else {
        $site = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->blogs} WHERE domain = %s AND path = %s", $domains[0], $paths[0]));
    }
    if ($site) {
        // @todo get_blog_details()
        return $site;
    }
    return false;
}

WordPress Version: 4.3

/**
 * Retrieve a site object by its domain and path.
 *
 * @since 3.9.0
 *
 * @global wpdb $wpdb
 *
 * @param string   $domain   Domain to check.
 * @param string   $path     Path to check.
 * @param int|null $segments Path segments to use. Defaults to null, or the full path.
 * @return object|false Site object if successful. False when no site is found.
 */
function get_site_by_path($domain, $path, $segments = null)
{
    global $wpdb;
    $path_segments = array_filter(explode('/', trim($path, '/')));
    /**
     * Filter the number of path segments to consider when searching for a site.
     *
     * @since 3.9.0
     *
     * @param int|null $segments The number of path segments to consider. WordPress by default looks at
     *                           one path segment following the network path. The function default of
     *                           null only makes sense when you know the requested path should match a site.
     * @param string   $domain   The requested domain.
     * @param string   $path     The requested path, in full.
     */
    $segments = apply_filters('site_by_path_segments_count', $segments, $domain, $path);
    if (null !== $segments && count($path_segments) > $segments) {
        $path_segments = array_slice($path_segments, 0, $segments);
    }
    $paths = array();
    while (count($path_segments)) {
        $paths[] = '/' . implode('/', $path_segments) . '/';
        array_pop($path_segments);
    }
    $paths[] = '/';
    /**
     * Determine a site by its domain and path.
     *
     * This allows one to short-circuit the default logic, perhaps by
     * replacing it with a routine that is more optimal for your setup.
     *
     * Return null to avoid the short-circuit. Return false if no site
     * can be found at the requested domain and path. Otherwise, return
     * a site object.
     *
     * @since 3.9.0
     *
     * @param null|bool|object $site     Site value to return by path.
     * @param string           $domain   The requested domain.
     * @param string           $path     The requested path, in full.
     * @param int|null         $segments The suggested number of paths to consult.
     *                                   Default null, meaning the entire path was to be consulted.
     * @param array            $paths    The paths to search for, based on $path and $segments.
     */
    $pre = apply_filters('pre_get_site_by_path', null, $domain, $path, $segments, $paths);
    if (null !== $pre) {
        return $pre;
    }
    /*
     * @todo
     * get_blog_details(), caching, etc. Consider alternative optimization routes,
     * perhaps as an opt-in for plugins, rather than using the pre_* filter.
     * For example: The segments filter can expand or ignore paths.
     * If persistent caching is enabled, we could query the DB for a path <> '/'
     * then cache whether we can just always ignore paths.
     */
    // Either www or non-www is supported, not both. If a www domain is requested,
    // query for both to provide the proper redirect.
    $domains = array($domain);
    if ('www.' === substr($domain, 0, 4)) {
        $domains[] = substr($domain, 4);
        $search_domains = "'" . implode("', '", $wpdb->_escape($domains)) . "'";
    }
    if (count($paths) > 1) {
        $search_paths = "'" . implode("', '", $wpdb->_escape($paths)) . "'";
    }
    if (count($domains) > 1 && count($paths) > 1) {
        $site = $wpdb->get_row("SELECT * FROM {$wpdb->blogs} WHERE domain IN ({$search_domains}) AND path IN ({$search_paths}) ORDER BY CHAR_LENGTH(domain) DESC, CHAR_LENGTH(path) DESC LIMIT 1");
    } elseif (count($domains) > 1) {
        $sql = $wpdb->prepare("SELECT * FROM {$wpdb->blogs} WHERE path = %s", $paths[0]);
        $sql .= " AND domain IN ({$search_domains}) ORDER BY CHAR_LENGTH(domain) DESC LIMIT 1";
        $site = $wpdb->get_row($sql);
    } elseif (count($paths) > 1) {
        $sql = $wpdb->prepare("SELECT * FROM {$wpdb->blogs} WHERE domain = %s", $domains[0]);
        $sql .= " AND path IN ({$search_paths}) ORDER BY CHAR_LENGTH(path) DESC LIMIT 1";
        $site = $wpdb->get_row($sql);
    } else {
        $site = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->blogs} WHERE domain = %s AND path = %s", $domains[0], $paths[0]));
    }
    if ($site) {
        // @todo get_blog_details()
        return $site;
    }
    return false;
}

WordPress Version: 4.2

/**
 * Retrieve a site object by its domain and path.
 *
 * @since 3.9.0
 *
 * @param string   $domain   Domain to check.
 * @param string   $path     Path to check.
 * @param int|null $segments Path segments to use. Defaults to null, or the full path.
 * @return object|bool Site object if successful. False when no site is found.
 */
function get_site_by_path($domain, $path, $segments = null)
{
    global $wpdb;
    $path_segments = array_filter(explode('/', trim($path, '/')));
    /**
     * Filter the number of path segments to consider when searching for a site.
     *
     * @since 3.9.0
     *
     * @param int|null $segments The number of path segments to consider. WordPress by default looks at
     *                           one path segment following the network path. The function default of
     *                           null only makes sense when you know the requested path should match a site.
     * @param string   $domain   The requested domain.
     * @param string   $path     The requested path, in full.
     */
    $segments = apply_filters('site_by_path_segments_count', $segments, $domain, $path);
    if (null !== $segments && count($path_segments) > $segments) {
        $path_segments = array_slice($path_segments, 0, $segments);
    }
    $paths = array();
    while (count($path_segments)) {
        $paths[] = '/' . implode('/', $path_segments) . '/';
        array_pop($path_segments);
    }
    $paths[] = '/';
    /**
     * Determine a site by its domain and path.
     *
     * This allows one to short-circuit the default logic, perhaps by
     * replacing it with a routine that is more optimal for your setup.
     *
     * Return null to avoid the short-circuit. Return false if no site
     * can be found at the requested domain and path. Otherwise, return
     * a site object.
     *
     * @since 3.9.0
     *
     * @param null|bool|object $site     Site value to return by path.
     * @param string           $domain   The requested domain.
     * @param string           $path     The requested path, in full.
     * @param int|null         $segments The suggested number of paths to consult.
     *                                   Default null, meaning the entire path was to be consulted.
     * @param array            $paths    The paths to search for, based on $path and $segments.
     */
    $pre = apply_filters('pre_get_site_by_path', null, $domain, $path, $segments, $paths);
    if (null !== $pre) {
        return $pre;
    }
    /*
     * @todo
     * get_blog_details(), caching, etc. Consider alternative optimization routes,
     * perhaps as an opt-in for plugins, rather than using the pre_* filter.
     * For example: The segments filter can expand or ignore paths.
     * If persistent caching is enabled, we could query the DB for a path <> '/'
     * then cache whether we can just always ignore paths.
     */
    // Either www or non-www is supported, not both. If a www domain is requested,
    // query for both to provide the proper redirect.
    $domains = array($domain);
    if ('www.' === substr($domain, 0, 4)) {
        $domains[] = substr($domain, 4);
        $search_domains = "'" . implode("', '", $wpdb->_escape($domains)) . "'";
    }
    if (count($paths) > 1) {
        $search_paths = "'" . implode("', '", $wpdb->_escape($paths)) . "'";
    }
    if (count($domains) > 1 && count($paths) > 1) {
        $site = $wpdb->get_row("SELECT * FROM {$wpdb->blogs} WHERE domain IN ({$search_domains}) AND path IN ({$search_paths}) ORDER BY CHAR_LENGTH(domain) DESC, CHAR_LENGTH(path) DESC LIMIT 1");
    } elseif (count($domains) > 1) {
        $sql = $wpdb->prepare("SELECT * FROM {$wpdb->blogs} WHERE path = %s", $paths[0]);
        $sql .= " AND domain IN ({$search_domains}) ORDER BY CHAR_LENGTH(domain) DESC LIMIT 1";
        $site = $wpdb->get_row($sql);
    } elseif (count($paths) > 1) {
        $sql = $wpdb->prepare("SELECT * FROM {$wpdb->blogs} WHERE domain = %s", $domains[0]);
        $sql .= " AND path IN ({$search_paths}) ORDER BY CHAR_LENGTH(path) DESC LIMIT 1";
        $site = $wpdb->get_row($sql);
    } else {
        $site = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->blogs} WHERE domain = %s AND path = %s", $domains[0], $paths[0]));
    }
    if ($site) {
        // @todo get_blog_details()
        return $site;
    }
    return false;
}

WordPress Version: 9.1

/**
 * Retrieve a site object by its domain and path.
 *
 * @since 3.9.0
 *
 * @param string   $domain   Domain to check.
 * @param string   $path     Path to check.
 * @param int|null $segments Path segments to use. Defaults to null, or the full path.
 * @return object|bool Site object if successful. False when no site is found.
 */
function get_site_by_path($domain, $path, $segments = null)
{
    global $wpdb;
    $path_segments = array_filter(explode('/', trim($path, '/')));
    /**
     * Filter the number of path segments to consider when searching for a site.
     *
     * @since 3.9.0
     *
     * @param int|null $segments The number of path segments to consider. WordPress by default looks at
     *                           one path segment following the network path. The function default of
     *                           null only makes sense when you know the requested path should match a site.
     * @param string   $domain   The requested domain.
     * @param string   $path     The requested path, in full.
     */
    $segments = apply_filters('site_by_path_segments_count', $segments, $domain, $path);
    if (null !== $segments && count($path_segments) > $segments) {
        $path_segments = array_slice($path_segments, 0, $segments);
    }
    while (count($path_segments)) {
        $paths[] = '/' . implode('/', $path_segments) . '/';
        array_pop($path_segments);
    }
    $paths[] = '/';
    /**
     * Determine a site by its domain and path.
     *
     * This allows one to short-circuit the default logic, perhaps by
     * replacing it with a routine that is more optimal for your setup.
     *
     * Return null to avoid the short-circuit. Return false if no site
     * can be found at the requested domain and path. Otherwise, return
     * a site object.
     *
     * @since 3.9.0
     *
     * @param null|bool|object $site     Site value to return by path.
     * @param string           $domain   The requested domain.
     * @param string           $path     The requested path, in full.
     * @param int|null         $segments The suggested number of paths to consult.
     *                                   Default null, meaning the entire path was to be consulted.
     * @param array            $paths    The paths to search for, based on $path and $segments.
     */
    $pre = apply_filters('pre_get_site_by_path', null, $domain, $path, $segments, $paths);
    if (null !== $pre) {
        return $pre;
    }
    /*
     * @todo
     * get_blog_details(), caching, etc. Consider alternative optimization routes,
     * perhaps as an opt-in for plugins, rather than using the pre_* filter.
     * For example: The segments filter can expand or ignore paths.
     * If persistent caching is enabled, we could query the DB for a path <> '/'
     * then cache whether we can just always ignore paths.
     */
    // Either www or non-www is supported, not both. If a www domain is requested,
    // query for both to provide the proper redirect.
    $domains = array($domain);
    if ('www.' === substr($domain, 0, 4)) {
        $domains[] = substr($domain, 4);
        $search_domains = "'" . implode("', '", $wpdb->_escape($domains)) . "'";
    }
    if (count($paths) > 1) {
        $search_paths = "'" . implode("', '", $wpdb->_escape($paths)) . "'";
    }
    if (count($domains) > 1 && count($paths) > 1) {
        $site = $wpdb->get_row("SELECT * FROM {$wpdb->blogs} WHERE domain IN ({$search_domains}) AND path IN ({$search_paths}) ORDER BY CHAR_LENGTH(domain) DESC, CHAR_LENGTH(path) DESC LIMIT 1");
    } elseif (count($domains) > 1) {
        $sql = $wpdb->prepare("SELECT * FROM {$wpdb->blogs} WHERE path = %s", $paths[0]);
        $sql .= " AND domain IN ({$search_domains}) ORDER BY CHAR_LENGTH(domain) DESC LIMIT 1";
        $site = $wpdb->get_row($sql);
    } elseif (count($paths) > 1) {
        $sql = $wpdb->prepare("SELECT * FROM {$wpdb->blogs} WHERE domain = %s", $domains[0]);
        $sql .= " AND path IN ({$search_paths}) ORDER BY CHAR_LENGTH(path) DESC LIMIT 1";
        $site = $wpdb->get_row($sql);
    } else {
        $site = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->blogs} WHERE domain = %s AND path = %s", $domains[0], $paths[0]));
    }
    if ($site) {
        // @todo get_blog_details()
        return $site;
    }
    return false;
}

WordPress Version: 3.9

/**
 * Retrieve a site object by its domain and path.
 *
 * @since 3.9.0
 *
 * @param string   $domain   Domain to check.
 * @param string   $path     Path to check.
 * @param int|null $segments Path segments to use. Defaults to null, or the full path.
 * @return object|bool Site object if successful. False when no site is found.
 */
function get_site_by_path($domain, $path, $segments = null)
{
    global $wpdb;
    $path_segments = array_filter(explode('/', trim($path, '/')));
    /**
     * Filter the number of path segments to consider when searching for a site.
     *
     * @since 3.9.0
     *
     * @param int|null $segments The number of path segments to consider. WordPress by default looks at
     *                           one path segment following the network path. The function default of
     *                           null only makes sense when you know the requested path should match a site.
     * @param string   $domain   The requested domain.
     * @param string   $path     The requested path, in full.
     */
    $segments = apply_filters('site_by_path_segments_count', $segments, $domain, $path);
    if (null !== $segments && count($path_segments) > $segments) {
        $path_segments = array_slice($path_segments, 0, $segments);
    }
    while (count($path_segments)) {
        $paths[] = '/' . implode('/', $path_segments) . '/';
        array_pop($path_segments);
    }
    $paths[] = '/';
    /**
     * Determine a site by its domain and path.
     *
     * This allows one to short-circuit the default logic, perhaps by
     * replacing it with a routine that is more optimal for your setup.
     *
     * Return null to avoid the short-circuit. Return false if no site
     * can be found at the requested domain and path. Otherwise, return
     * a site object.
     *
     * @since 3.9.0
     *
     * @param null|bool|object $site     Site value to return by path.
     * @param string           $domain   The requested domain.
     * @param string           $path     The requested path, in full.
     * @param int|null         $segments The suggested number of paths to consult.
     *                                   Default null, meaning the entire path was to be consulted.
     * @param array            $paths    The paths to search for, based on $path and $segments.
     */
    $pre = apply_filters('pre_get_site_by_path', null, $domain, $path, $segments, $paths);
    if (null !== $pre) {
        return $pre;
    }
    /*
     * @todo
     * get_blog_details(), caching, etc. Consider alternative optimization routes,
     * perhaps as an opt-in for plugins, rather than using the pre_* filter.
     * For example: The segments filter can expand or ignore paths.
     * If persistent caching is enabled, we could query the DB for a path <> '/'
     * then cache whether we can just always ignore paths.
     */
    if (count($paths) > 1) {
        $paths = "'" . implode("', '", $wpdb->_escape($paths)) . "'";
        $sql = $wpdb->prepare("SELECT * FROM {$wpdb->blogs} WHERE domain = %s", $domain);
        $sql .= " AND path IN ({$paths}) ORDER BY CHAR_LENGTH(path) DESC LIMIT 1";
        $site = $wpdb->get_row($sql);
    } else {
        $site = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->blogs} WHERE domain = %s and path = %s", $domain, $paths[0]));
    }
    if ($site) {
        // @todo get_blog_details()
        return $site;
    }
    return false;
}