sanitize_key( string $key ): string
- Since
- 3.0.0
- Source
wp-includes/formatting.php:2190
Strips a string down to lowercase letters, numbers, dashes and underscores so it can be safely used as an internal identifier like a meta key, option name or transient name. Non-scalar input (arrays, objects) is silently converted to an empty string rather than raising an error. Pass the result through the sanitize_key filter if a plugin needs to adjust generated keys globally.
Description
Keys are used as internal identifiers. Lowercase alphanumeric characters, dashes, and underscores are allowed.
Compatibility
- WordPress
- since 3.0.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
$keystring- String key.
Return value
string- Sanitized key.
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.
Building a safe meta key from user-supplied input before calling get_post_meta
A form field or query var might arrive with stray casing or whitespace, so run it through sanitize_key() before using it as a meta key lookup.
$user_supplied = ' Price ';
$meta_key = sanitize_key( $user_supplied );
$price = get_post_meta( 2, $meta_key, true );
printf( 'Sanitized key: %s | Value: %s', esc_html( $meta_key ), esc_html( $price ) );The trailing/leading space and mixed case are stripped, so ' Price ' becomes 'price' and matches the existing post meta on post 2.
Turning a category name into a safe PHP array key
Category names can contain spaces or punctuation that make poor array keys, so sanitize each one before grouping term IDs by name.
$categories = get_categories( array( 'hide_empty' => false ) );
$grouped = array();
foreach ( $categories as $category ) {
$key = sanitize_key( $category->name );
$grouped[ $key ] = $category->term_id;
}
print_r( $grouped );Common problems and fixes · 3
- Why does sanitize_key() return an empty string for my value?
- Why did my uppercase letters and spaces disappear from the key?
- Can a plugin change the value sanitize_key() returns?
Why does sanitize_key() return an empty string for my value?
Why did my uppercase letters and spaces disappear from the key?
Can a plugin change the value sanitize_key() returns?
Alternatives and related functions
sanitize_title- When the string is meant to become a URL slug and you want spaces converted to dashes rather than removed.
sanitize_html_class- When the sanitized value will be output as an HTML class attribute rather than used as an internal array or meta key.
sanitize_text_field- When you are cleaning general free-text user input, not a fixed-format identifier like a key or slug.
sanitize_file_name- When the string will be used as a filename rather than a database or array key.
Performance profile
How much work a call to sanitize_key() 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
- 10–17
- Plugin surface
- 1 hook
- Called by
- 50
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 17.
Third-party callbacks on 'sanitize_key' run inside this call, and their cost is not bounded by anything here.
50 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 · 2 distinct outcomes
One number would be a lie: the work depends on which branch runs. These are every distinct cost sanitize_key() can have, taken from its control-flow graph on PHP 8.5.
| When | Instructions | Calls it makes |
|---|---|---|
!is_scalar($key) | 10 | apply_filters() |
is_scalar($key) | 17 | strtolower(), apply_filters() |
Across PHP versions
| PHP | Compiled | Executed | Branches | Notes |
|---|---|---|---|---|
| 8.6-dev | 17 | 10–17 | 1 | |
| 8.5 | 17 | 10–17 | 1 | |
| 8.4 | 17 | 10–17 | 1 | 3 fewer instructions than PHP 8.3 |
| 8.3 | 20 | 10–20 | 1 | |
| 8.2 | 20 | 10–20 | 1 | |
| 8.1 | 20 | 10–20 | 1 | 2 fewer instructions than PHP 7.4 |
| 7.4 | 22 | 12–22 | 1 |
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 sanitize_key() runs, in this order:
Uses · 1
- apply_filters()Calls the callback functions that have been added to a filter hook.
Used by · 50
- TwentyTwenty_Customize::sanitize_select()Sanitizes a select input.
- WP_Comments_List_Table::prepare_items()Prepares the comments list items.
- WP_Customize_Manager::__construct()Constructor.
- WP_Customize_Manager::handle_load_themes_request()Loads themes into the theme browsing/installation UI.
- WP_Customize_Nav_Menu_Item_Setting::sanitize()Sanitize an input.
- WP_Customize_Nav_Menus::ajax_load_available_items()Ajax handler for loading available menu items.
- WP_Duotone::render_duotone_support()Render out the duotone CSS styles and SVG.
- WP_List_Table::__construct()Constructor.
- WP_Meta_Query::get_sql()Generates SQL clauses to be appended to a main query.
- WP_Plugin_Dependencies::check_plugin_dependencies_during_ajax()Checks plugin dependencies after a plugin is installed via AJAX.
- WP_Plugins_List_Table::__construct()Constructor.
- WP_Query::parse_orderby()Converts the given orderby alias (if allowed) to a properly-prefixed value.
Show all 50
- WP_Query::parse_query()Parses a query string and sets query type booleans.
- WP_Screen::get()Fetches a screen object.
- WP_Style_Engine_CSS_Declarations::sanitize_property()Sanitizes property names.
- WP_Tax_Query::transform_query()Transforms a single query, from one field to another.
- WP_Theme::get_post_templates()Returns the theme's post templates.
- WP_User_Query::prepare_query()Prepares the query variables.
- _get_last_post_time()Gets the timestamp of the last time any post was modified or published.
- _wp_customize_include()Includes and instantiates the WP_Customize_Manager class.
- _wp_filter_post_meta_footnotes()Strips all HTML from the content of footnotes, and sanitizes the ID.
- _wp_personal_data_handle_actions()Handle list table actions.
- _wp_preview_terms_filter()Filters terms lookup to set the post format.
- _wp_translate_postdata()Renames `$_POST` data from form names to DB post columns.
- add_metadata()Adds metadata for the specified object.
- bulk_edit_posts()Processes the post data for the bulk editing of posts.
- delete_metadata()Deletes metadata for the specified object.
- delete_metadata_by_mid()Deletes metadata by meta ID.
- edit_post()Updates an existing post with values provided in `$_POST`.
- export_wp()Generates the WXR export file for download.
- has_post_format()Check if a post has any of the given formats, or any format.
- post_preview()Saves a draft or manually autosaves for the purpose of showing a post preview.
- register_post_status()Registers a post status. Do not use before init.
- register_post_type()Registers a post type.
- set_post_format()Assign a format to a post
- set_screen_options()Saves option for number of rows when listing posts, pages, comments, etc.
- update_meta_cache()Updates the metadata cache for the specified objects.
- update_metadata()Updates metadata for the specified object. If no value already exists for the specified object ID and metadata key, the metadata will be added.
- update_metadata_by_mid()Updates metadata by meta ID.
- update_user_status()Update the status of a user in the database.
- wp_ajax_ajax_tag_search()Handles tag search via AJAX.
- wp_ajax_closed_postboxes()Handles closed post boxes via AJAX.
- wp_ajax_delete_plugin()Handles deleting a plugin via AJAX.
- wp_ajax_dismiss_wp_pointer()Handles dismissing a WordPress pointer via AJAX.
- wp_ajax_get_tagcloud()Handles getting a tagcloud via AJAX.
- wp_ajax_heartbeat()Handles the Heartbeat API via AJAX.
- wp_ajax_hidden_columns()Handles hidden columns via AJAX.
- wp_ajax_inline_save_tax()Handles Quick Edit saving for a term via AJAX.
- wp_ajax_install_plugin()Handles installing a plugin via AJAX.
- wp_ajax_install_theme()Handles installing a theme via AJAX.
Source code
function sanitize_key( $key ) { $sanitized_key = ''; if ( is_scalar( $key ) ) { $sanitized_key = strtolower( $key ); $sanitized_key = preg_replace( '/[^a-z0-9_\-]/', '', $sanitized_key ); } /** * Filters a sanitized key string. * * @since 3.0.0 * * @param string $sanitized_key Sanitized key. * @param string $key The key prior to sanitization. */ return apply_filters( 'sanitize_key', $sanitized_key, $key );}Changelog
Introduced in 3.0.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/formatting.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.