wp_parse_url( string $url, int $component = -1 ): mixed
- Since
- 4.4.0, 4.7.0
- Source
wp-includes/http.php:761
Parses a URL into its components (scheme, host, path, query, etc.) while correcting inconsistencies PHP's own parse_url() has across versions. Pass a PHP_URL_* constant as the second argument to get a single piece back instead of the full array. Useful for pulling the host or query string out of a permalink, REST endpoint, or user-supplied URL before validating or rewriting it.
Description
Across various PHP versions, schemeless URLs containing a ":" in the query are being handled inconsistently. This function works around those differences.
Compatibility
- WordPress
- since 4.7.0
- PHP
- 7.4–8.6-dev
- 6.7.7
- 6.8.8
- 6.9.7
- 7.0.4
- 7.1.0
Present in every tracked release (6.7.7 to 7.1.0), and compiles on PHP 7.4 through 8.6-dev.
Parameters
$urlstring- The URL to parse.
$componentintoptional- The specific component to retrieve. Use one of the PHP predefined constants to specify which one.
Defaults to -1 (= return all parts as an array).Default:-1
Return value
mixed- False on parse failure; Array of URL components on success; When a specific component has been requested: null if the component doesn't exist in the given URL; a string or - in the case of PHP_URL_PORT - integer when it does. See parse_url()'s return values.
Code examples
Every example is editable and runs in a real WordPress booted in your browser by WordPress Playground. Press Run, then edit the code: clicking away re-runs it. Nothing is sent anywhere until you do.
Break a post permalink into its URL components
Grab the full permalink for post ID 1 and inspect its scheme, host, path and query as an array.
$permalink = get_permalink( 1 );
$parts = wp_parse_url( $permalink );
echo esc_html( 'Permalink: ' . $permalink ) . "\n";
echo '<pre>' . esc_html( print_r( $parts, true ) ) . '</pre>';Read just the query string from a URL without parsing the whole thing
Build a link to post 2 with an extra query var and pull out only the query component using the PHP_URL_QUERY constant.
$url = home_url( '/?p=2&source=featured' );
$query = wp_parse_url( $url, PHP_URL_QUERY );
echo esc_html( 'Query string: ' . $query ) . "\n";
$host = wp_parse_url( '//example.com/path/to/page', PHP_URL_HOST );
echo esc_html( 'Host from a protocol-relative URL: ' . $host );For a protocol-relative URL (starting with //) there is no scheme, so requesting PHP_URL_SCHEME here would return null rather than an empty string.
Common problems and fixes · 3
- Why does asking for PHP_URL_SCHEME on my URL come back null instead of an empty string?
- Why did wp_parse_url() return false?
- Why do I still get an array back even though I passed a component?
Why does asking for PHP_URL_SCHEME on my URL come back null instead of an empty string?
Why did wp_parse_url() return false?
false === $result before treating the return value as an array or scalar.
- Cast or sanitize the input first (the function itself just casts $url to a string, it does not validate it).Why do I still get an array back even though I passed a component?
wp_parse_url( $url, PHP_URL_HOST ) for just the host.
- wp_parse_url( $url ) (or -1) for the full array.Alternatives and related functions
parse_url- When you are not working around the schemeless URL quirks this function fixes and plain PHP behavior is acceptable.
wp_parse_str- When you already have an isolated query string and need it turned into an array of variables rather than parsing a whole URL.
esc_url- When the goal is to output a URL safely in HTML rather than to inspect or read its individual components.
add_query_arg- When you need to add or modify query parameters on a URL rather than just read its existing pieces.
Performance profile
How much work a call to wp_parse_url() does, and what it touches: the algorithmic scaling, the Zend instruction count per call across PHP versions, the hooks it hands control to, and the core code that calls it. Measured from the compiled opcodes, not a stopwatch, so every number is identical on any machine running the same PHP version, and every function in core is ranked by cost.
- Cost class
- Light
- Scaling
- Scales with input
- Instructions
- 16–26
- Plugin surface
- None
- Called by
- 34
Touches nothing outside its own arguments.
The body loops, so the work grows with what you pass in.
Executed per call on PHP 8.5, depending on the branch taken. The body compiles to 33.
Nothing here hands control to plugin code.
34 places in core call this, so the cost is paid more often than your own code shows.
What one call costs · 2 distinct outcomes
One number would be a lie: the work depends on which branch runs. These are every distinct cost wp_parse_url() can have, taken from its control-flow graph on PHP 8.5.
| When | Instructions | Calls it makes |
|---|---|---|
$parts === false | 16–19 | parse_url() |
$parts !== false | 22–26 | parse_url(), _get_component_from_parsed_url_array() |
Across PHP versions
| PHP | Compiled | Executed | Branches | Notes |
|---|---|---|---|---|
| 8.6-dev | 33 | 16–26 | 5 | |
| 8.5 | 33 | 16–26 | 5 | |
| 8.4 | 33 | 16–26 | 5 | 6 fewer instructions than PHP 8.3 |
| 8.3 | 39 | 21–32 | 5 | |
| 8.2 | 39 | 21–32 | 5 | |
| 8.1 | 39 | 21–32 | 5 | |
| 7.4 | 39 | 21–32 | 5 |
An instruction is not a fixed amount of time, so a matching count is not necessarily the same speed; what it rules out is a difference in the work itself.
Uses · 2
- str_starts_with()Polyfill for `str_starts_with()` function added in PHP 8.0.
- _get_component_from_parsed_url_array()Retrieves a specific component from a parsed URL array.
Used by · 34
- WP_Customize_Manager::add_state_query_params()Adds customize state query params to a given URL if preview is allowed.
- WP_Customize_Manager::customize_preview_settings()Prints JavaScript settings for preview frame.
- WP_Customize_Manager::is_cross_domain()Determines whether the admin and the frontend are on different domains.
- WP_Http::make_absolute_url()Converts a relative URL to an absolute URL relative to a given URL.
- WP_Http::parse_url()Used as a wrapper for PHP's parse_url() function that handles edgecases in < PHP 5.4.7.
- WP_Image_Editor_Imagick::load()Loads image from $this->file into new Imagick Object.
- WP_REST_Attachments_Controller::create_item_from_url()Sideloads an external image from a URL into the media library.
- WP_REST_Server::serve_batch_request_v1()Serves the batch/v1 request.
- WP_URL_Pattern_Prefixer::get_default_contexts()Returns the default contexts used by the class.
- _load_script_textdomain_from_src()Resolves and loads the translation JSON file for a given script or script module source URL.
- _make_clickable_rel_attr()Helper function used to build the "rel" attribute for a URL when creating an anchor using make_clickable().
- _wp_kses_allow_pdf_objects()Helper function to check if this is a safe PDF URL.
Show all 34
- do_robots()Displays the default robots.txt file content.
- esc_url()Checks and cleans a URL.
- get_oembed_response_data_for_url()Retrieves the oEmbed response data for a given URL.
- render_block_core_cover()Renders the `core/cover` block on server.
- strip_fragment_from_url()Strips the #fragment from a URL, if one is present.
- wp_dependencies_unique_hosts()Retrieves a list of unique hosts of all enqueued scripts and styles.
- wp_internal_hosts()Returns an array of URL hosts which are considered to be internal hosts.
- wp_is_authorize_application_redirect_url_valid()Validates the redirect URL protocol scheme.
- wp_is_home_url_using_https()Checks whether the current site URL is using HTTPS.
- wp_is_internal_link()Determines whether or not the specified URL is of a host included in the internal hosts list.
- wp_is_site_url_using_https()Checks whether the current site's URL where WordPress is stored is using HTTPS.
- wp_mail()Sends an email, similar to PHP's mail function.
- wp_notify_postauthor()Notifies an author (and/or others) of a comment/trackback/pingback on a post.
- wp_resource_hints()Prints resource hints to browsers for pre-fetching, pre-rendering and pre-connecting to websites.
- wp_should_replace_insecure_home_url()Checks whether WordPress should replace old HTTP URLs to the site with their HTTPS counterpart.
- wp_update_plugins()Checks for available updates to plugins based on the latest versions hosted on WordPress.org.
- wp_update_themes()Checks for available updates to themes based on the latest versions hosted on WordPress.org.
- wp_video_shortcode()Builds the Video shortcode output.
- wpmu_signup_blog_notification()Sends a confirmation request email to a user when they sign up for a new site. The new site will not become active until the confirmation link is clicked.
- wpmu_signup_user_notification()Sends a confirmation request email to a user when they sign up for a new user account (without signing up for a site at the same time). The user account will not become active until the confirmation link is clicked.
- wpmu_welcome_notification()Notifies the site administrator that their site activation was successful.
- wpmu_welcome_user_notification()Notifies a user that their account activation has been successful.
Source code
function wp_parse_url( $url, $component = -1 ) { $to_unset = array(); $url = (string) $url; if ( str_starts_with( $url, '//' ) ) { $to_unset[] = 'scheme'; $url = 'placeholder:' . $url; } elseif ( str_starts_with( $url, '/' ) ) { $to_unset[] = 'scheme'; $to_unset[] = 'host'; $url = 'placeholder://placeholder' . $url; } $parts = parse_url( $url ); if ( false === $parts ) { // Parsing failure. return $parts; } // Remove the placeholder values. foreach ( $to_unset as $key ) { unset( $parts[ $key ] ); } return _get_component_from_parsed_url_array( $parts, $component );}Changelog
Introduced in 4.4.0. Unchanged from 6.7.7 through 7.1.0.
Signature, return type and hooks compared across 5 parsed releases.
$component parameter was added for parity with PHP's parse_url().from the docblockAbout this page
- Parsed data
- Generated from the wordpress-develop 7.1.0 tag, from
src/wp-includes/http.php, and regenerated for each WordPress release so it tracks the code rather than a snapshot of it. - Corrections
- Something wrong on this page? Report it and it gets fixed in the next regeneration.