set_url_scheme( string $url, string|null $scheme = null ): string
- Since
- 3.4.0, 4.4.0
- Source
wp-includes/link-template.php:3930
Rewrites an absolute URL to use a specific scheme, http, https, or relative, falling back to the current is_ssl() state when no valid scheme is given. It underlies functions such as home_url(), content_url(), and admin_url(), so passing an unexpected value here can ripple through generated links. Every call passes through the 'set_url_scheme' filter, so a plugin can rewrite the final URL after WordPress has already normalized it.
Compatibility
- WordPress
- since 4.4.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- Absolute URL that includes a scheme
$schemestring|nulloptional- Scheme to give $url. Currently 'http', 'https', 'login', 'login_post', 'admin', 'relative', 'rest', 'rpc', or null. Default null.Default:
null
Return value
string- URL with chosen scheme.
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.
Force a post permalink to use https regardless of the current request
Take the permalink of the seeded "Hello world!" post and rewrite its scheme explicitly.
$permalink = get_permalink( 1 );
$https_link = set_url_scheme( $permalink, 'https' );
printf( 'Original: %s', esc_html( $permalink ) );
echo '<br>';
printf( 'Forced https: %s', esc_html( $https_link ) );The 'https' scheme is applied literally here; passing an unrecognized value would fall back to whatever is_ssl() reports for the current request.
Convert an absolute URL to a scheme-relative URL
Strip the scheme from a hardcoded absolute URL so it works over both http and https.
$asset_url = 'https://example.org/wp-content/uploads/2024/01/banner.jpg';
$relative = set_url_scheme( $asset_url, 'relative' );
printf( 'Scheme-relative URL: %s', esc_html( $relative ) );Common problems and fixes · 3
- Why does set_url_scheme() ignore the scheme I passed in?
- Why do my admin or login URLs come back as https when the site isn't forcing SSL sitewide?
- Why did my double-slash protocol-relative URL turn into an http:// URL?
Why does set_url_scheme() ignore the scheme I passed in?
Why do my admin or login URLs come back as https when the site isn't forcing SSL sitewide?
Why did my double-slash protocol-relative URL turn into an http:// URL?
Alternatives and related functions
home_url- When you need the site's home URL with a scheme applied rather than rewriting an arbitrary existing URL string.
admin_url- When you need a URL inside wp-admin and want WordPress to pick the admin scheme (including force_ssl_admin() handling) for you.
content_url- When you need a URL under wp-content and want the site's default scheme applied automatically.
is_ssl- When you only need to know whether the current request is over https, without rewriting any URL.
Performance profile
How much work a call to set_url_scheme() 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
- Trivial
- Scaling
- Constant
- Instructions
- 27–57
- Plugin surface
- 1 hook
- Called by
- 46
Touches nothing outside its own arguments.
No loop in the body: the same number of instructions runs whatever you pass in.
Executed per call on PHP 8.5, depending on the branch taken. The body compiles to 81.
Third-party callbacks on 'set_url_scheme' run inside this call, and their cost is not bounded by anything here.
46 places in core call this, so the cost is paid more often than your own code shows.
What it touches
- hookthird-party callbacks
apply_filters()called directly
What one call costs · 9 distinct outcomes
One number would be a lie: the work depends on which branch runs. These are every distinct cost set_url_scheme() can have, taken from its control-flow graph on PHP 8.5.
| When | Instructions | Calls it makes |
|---|---|---|
$scheme !== "relative" | 27–43 | is_ssl(), apply_filters() |
$scheme !== "admin" && $scheme !== "login" && $scheme !== "login_post" && $scheme !== "rpc" && $scheme !== "relative" | 31–37 | apply_filters() |
$scheme === "relative" | 31–50 | is_ssl(), ltrim(), apply_filters() |
!is_ssl() && $scheme !== "relative" | 32–41 | is_ssl(), force_ssl_admin(), apply_filters() |
$scheme !== "admin" && $scheme !== "login" && $scheme !== "login_post" && $scheme !== "rpc" && $scheme === "relative" | 35–44 | ltrim(), apply_filters() |
!is_ssl() && $scheme === "relative" | 36–48 | is_ssl(), force_ssl_admin(), ltrim(), apply_filters() |
$scheme === "relative" && $url !== "" | 41–57 | is_ssl(), ltrim(), ltrim(), apply_filters() |
$scheme !== "admin" && $scheme !== "login" && $scheme !== "login_post" && $scheme !== "rpc" && $scheme === "relative" && $url !== "" | 45–51 | ltrim(), ltrim(), apply_filters() |
!is_ssl() && $scheme === "relative" && $url !== "" | 46–55 | is_ssl(), force_ssl_admin(), ltrim(), ltrim(), apply_filters() |
Across PHP versions
| PHP | Compiled | Executed | Branches | Notes |
|---|---|---|---|---|
| 8.6-dev | 81 | 27–57 | 16 | |
| 8.5 | 81 | 27–57 | 16 | |
| 8.4 | 81 | 27–57 | 16 | 11 fewer instructions than PHP 8.3 |
| 8.3 | 92 | 35–65 | 16 | |
| 8.2 | 92 | 35–65 | 16 | |
| 8.1 | 92 | 35–65 | 16 | |
| 7.4 | 92 | 35–65 | 16 |
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.
Hooks and filters fired · 1
One hook fires while set_url_scheme() runs, in this order:
- apply_filters( set_url_scheme )filterline 3965 (+35 into the body)
Filters the resulting URL after setting the scheme.
Uses · 4
- is_ssl()Determines if SSL is used.
- force_ssl_admin()Determines whether to force SSL used for the Administration Screens.
- str_starts_with()Polyfill for `str_starts_with()` function added in PHP 8.0.
- apply_filters()Calls the callback functions that have been added to a filter hook.
Used by · 46
- Custom_Background::admin_page()Displays the custom background page.
- Custom_Image_Header::show_header_selector()Displays UI for selecting one of several default headers.
- WP_Community_Events::get_events()Gets data about events near a particular location.
- WP_Customize_Manager::handle_load_themes_request()Loads themes into the theme browsing/installation UI.
- WP_List_Table::pagination()Displays the pagination.
- WP_List_Table::print_column_headers()Prints column headers, accounting for hidden and sortable columns.
- WP_REST_Pattern_Directory_Controller::get_items()Search and retrieve block patterns metadata
- _WP_Editors::editor_settings()
- _custom_background_cb()Default custom background callback.
- _wp_menu_item_classes_by_context()Adds the class property classes for the current context, if applicable.
- add_menu_page()Adds a top-level menu page.
- auth_redirect()Checks if a user is logged in, if not it redirects them to the login page.
Show all 46
- content_url()Retrieves the URL to the content directory.
- edit_form_image_editor()Displays the image and editor in the post editor
- filter_SSL()Formats a URL to use https.
- get_core_checksums()Gets and caches the checksums for the given version of WordPress.
- get_header_image()Retrieves header image for custom header.
- get_header_video_url()Retrieves header video URL for custom header.
- get_home_path()Gets the absolute filesystem path to the root of the WordPress installation.
- get_home_url()Retrieves the URL for a given site where the front end is accessible.
- get_preview_post_link()Retrieves the URL used for the post preview.
- get_rest_url()Retrieves the URL to a REST endpoint on a site.
- get_self_link()Returns the link for the currently displayed feed.
- get_site_url()Retrieves the URL for a given site where WordPress application files (e.g. wp-blog-header.php or the wp-admin/ folder) are accessible.
- install_blog()Install an empty blog.
- network_home_url()Retrieves the home URL for the current network.
- network_site_url()Retrieves the site URL for the current network.
- plugins_api()Retrieves plugin installer pages from the WordPress.org Plugins API.
- plugins_url()Retrieves a URL within the plugins or mu-plugins directory.
- themes_api()Retrieves theme installer pages from the WordPress.org Themes API.
- translations_api()Retrieve translations from WordPress Translation API.
- upgrade_682()Executes changes made in WordPress 6.8.2.
- url_is_accessable_via_ssl()Determines if the URL can be accessed over SSL.
- url_to_postid()Examines a URL and try to determine the post ID it represents.
- wp_admin_canonical_url()Removes single-use URL parameters and create canonical link based on new URL.
- wp_ajax_query_themes()Handles getting themes from themes_api() via AJAX.
- wp_calculate_image_srcset()A helper function to calculate the image sources to include in a 'srcset' attribute.
- wp_check_browser_version()Checks if the user needs a browser update.
- wp_check_php_version()Checks if the user needs to update PHP.
- wp_credits()Retrieves the contributor credits.
- wp_get_attachment_url()Retrieves the URL for an attachment.
- wp_get_popular_importers()Returns a list from WordPress.org of popular importer plugins.
- 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_version_check()Checks WordPress version against the newest version.
- wp_video_shortcode()Builds the Video shortcode output.
Source code
function set_url_scheme( $url, $scheme = null ) { $orig_scheme = $scheme; if ( ! $scheme ) { $scheme = is_ssl() ? 'https' : 'http'; } elseif ( 'admin' === $scheme || 'login' === $scheme || 'login_post' === $scheme || 'rpc' === $scheme ) { $scheme = is_ssl() || force_ssl_admin() ? 'https' : 'http'; } elseif ( 'http' !== $scheme && 'https' !== $scheme && 'relative' !== $scheme ) { $scheme = is_ssl() ? 'https' : 'http'; } $url = trim( $url ); if ( str_starts_with( $url, '//' ) ) { $url = 'http:' . $url; } if ( 'relative' === $scheme ) { $url = ltrim( preg_replace( '#^\w+://[^/]*#', '', $url ) ); if ( '' !== $url && '/' === $url[0] ) { $url = '/' . ltrim( $url, "/ \t\n\r\0\x0B" ); } } else { $url = preg_replace( '#^\w+://#', $scheme . '://', $url ); } /** * Filters the resulting URL after setting the scheme. * * @since 3.4.0 * * @param string $url The complete URL including scheme and path. * @param string $scheme Scheme applied to the URL. One of 'http', 'https', or 'relative'. * @param string|null $orig_scheme Scheme requested for the URL. One of 'http', 'https', 'login', * 'login_post', 'admin', 'relative', 'rest', 'rpc', or null. */ return apply_filters( 'set_url_scheme', $url, $scheme, $orig_scheme );}Changelog
Introduced in 3.4.0. Unchanged from 6.7.7 through 7.1.0.
Signature, return type and hooks compared across 5 parsed releases.
About this page
- Parsed data
- Generated from the wordpress-develop 7.0.4 tag, from
src/wp-includes/link-template.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.