WP_Network_Query Generator
get_networks() arguments, with the honest note that almost every install has one network and the query is only worth writing on a multi-network setup.
<?php
/**
* Networks matching the arguments below.
*
* Almost every multisite install has exactly one network, so this query returns one row and there
* is no reason to write it: is_multisite() plus get_current_network_id() answers the question.
* It earns its place on a multi-network install, which means WordPress MU-style hosting where one
* codebase serves several independent networks.
*/
// Networks only exist on multisite, and get_networks() returns an empty array otherwise.
if ( ! is_multisite() ) {
return;
}
$args = array(
'orderby' => 'domain',
'order' => 'ASC',
'number' => 20,
);
$networks = get_networks( $args );
foreach ( $networks as $network ) {
$id = (int) $network->id;
$details = $network;
if ( ! $details ) {
continue;
}
printf( "%d: %s%s\n", $id, esc_html( $details->domain ), esc_html( $details->path ) );
}
Output is valid and updates as you type.
Fix the highlighted fields to update the output.
Most multisite installs have exactly one network. On those, get_networks() returns one row and there is no
reason to call it: is_multisite() and get_current_network_id() already answer the question.
It earns its place on a multi-network install, where one WordPress codebase serves several independent networks, each with its own sites, users table sharing and settings. That is rare, it is usually a hosting arrangement rather than a product decision, and when you are in one this is the query you need.
The related thing worth knowing either way: network options are not site options. They live in sitemeta,
they are per network, and inside a loop you want get_network_option() with an explicit ID rather than
get_site_option(), which silently reads the current network’s.
How to use
- Filter by domain or path if you know them, or leave everything empty to list all networks.
- Tick the site count if you want how many sites each network has, which is an extra query each.
- Tick the option example to see the per-network read.
Example
if ( ! is_multisite() ) {
return;
}
$args = array(
'orderby' => 'domain',
'order' => 'ASC',
'number' => 20,
);
$networks = get_networks( $args );
foreach ( $networks as $network ) {
$id = (int) $network->id;
$details = $network;
printf( "%d: %s%s\n", $id, esc_html( $details->domain ), esc_html( $details->path ) );
}
With site counts turned on, each iteration runs a get_sites() with count => true, which returns an
integer and builds no site objects.
Pitfalls
One network is the normal case. If you are reaching for this on an ordinary multisite, the answer you
want is probably get_current_network_id() or get_sites().
Network options live in sitemeta. get_site_option() reads the current network’s; get_option() reads
the current site’s. The naming is historical and it is the most confusing pair in multisite. Inside a loop
over networks, use get_network_option( $id, ... ) so there is no ambiguity.
A subdirectory network has one domain for all its sites. So filtering networks by domain on a subdirectory install matches the one network, and filtering sites by domain matches all of them. The two tables store different things.
Paths carry both slashes. A root network’s path is /. Passing an empty string matches nothing.
search covers the domain and path columns only. There is nothing else in the networks table to search.
Counting sites per network is N+1 queries. Fine for a handful of networks, not for a page that runs on every request. Cache the result if it is being displayed.
Users may or may not be shared. On a multi-network install the users table is shared by default across
all of it, which means a user list is network-wide and capabilities are per site. That surprises people more
than the queries do.
Compatibility
Everything runs in the browser: nothing is uploaded and nothing is stored.
WP_Network_Query and get_networks() arrived in WordPress 4.6. orderby accepts domain, path, id,
network__in, and the two length variants, which are useful when you need the longest matching domain, as
the request routing itself does.
count => true returns an integer. fields => 'ids' returns integers rather than WP_Network objects,
and get_network() then reads from the cache the query primed.
Every string is escaped for a PHP single-quoted string. The hostile fixture includes an apostrophe, */,
?> and ${x}, and the output passes php -l with the same token structure as the default file.
Multi-network installs are not configurable from the admin: they need SUBDOMAIN_INSTALL, a
sunrise.php drop-in and a domain-mapping arrangement, which is why the code here reads networks rather
than creating them.
Frequently asked questions
What is a multi-network install?
sunrise.php drop-in and manual configuration, and plugins like WP Multi Network exist to manage it.How do I get the current network?
get_current_network_id(), or get_network() with no argument for the object. No query needed.get_site_option or get_network_option?
get_site_option() reads the current network’s option, despite the name. get_network_option() takes an
explicit network ID. Use the second one anywhere the network is not obviously the current one.