number_format_i18n( float $number, int $decimals = 0 ): string
- Since
- 2.3.0
- Source
wp-includes/functions.php:420
Formats a numeric value using the current locale's decimal point and thousands separator instead of PHP's number_format() defaults. It rounds to the number of decimal places you pass in $decimals (0 by default) and always returns a string, not a float or int. If the global $wp_locale object isn't set yet, it silently falls back to plain number_format() output with a period and comma, so calling it too early in the request can produce unlocalized results.
Compatibility
- WordPress
- since 2.3.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
$numberfloat- The number to convert based on locale.
$decimalsintoptional- Precision of the number of decimal places. Default 0.Default:
0
Return value
string- Converted number in string format.
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.
Display a price stored in post meta with locale-aware formatting
Post 2 has a price value stored in post meta that should be shown with the site's decimal separator.
$price = get_post_meta( 2, 'price', true );
if ( '' === $price ) {
$price = 0;
}
$formatted_price = number_format_i18n( (float) $price, 2 );
echo esc_html( 'Price: ' . $formatted_price );get_post_meta() always returns a string, so cast it to float before passing it in.
Format the average number of comments per post
Loop over posts 1 through 5, average their comment counts, and format the result to one decimal place.
$post_ids = array( 1, 2, 3, 4, 5 );
$total_comments = 0;
foreach ( $post_ids as $post_id ) {
$total_comments += (int) get_comments_number( $post_id );
}
$average = $total_comments / count( $post_ids );
echo esc_html( 'Average comments per post: ' . number_format_i18n( $average, 1 ) );Common problems and fixes · 4
- Why does number_format_i18n give me a period and comma even though my site is in another language?
- Why did my decimal places disappear from the formatted number?
- Can I get number_format_i18n to return a negative number of decimal places or skip rounding entirely?
- How do I change the formatted output site-wide without editing every call?
Why does number_format_i18n give me a period and comma even though my site is in another language?
Why did my decimal places disappear from the formatted number?
Can I get number_format_i18n to return a negative number of decimal places or skip rounding entirely?
How do I change the formatted output site-wide without editing every call?
Alternatives and related functions
number_format- When you don't need locale-aware separators and just want PHP's native rounding and formatting behavior.
size_format- When you're formatting a byte count (like a file or upload size) rather than an arbitrary number.
WP_Locale- When you need the raw decimal_point or thousands_sep strings for the current locale instead of a fully formatted number.
Performance profile
How much work a call to number_format_i18n() 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
- 20–27
- 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 35.
Third-party callbacks on 'number_format_i18n' 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 · 1 distinct outcome
One number would be a lie: the work depends on which branch runs. These are every distinct cost number_format_i18n() can have, taken from its control-flow graph on PHP 8.5.
| When | Instructions | Calls it makes |
|---|---|---|
| always | 20–27 | absint(), number_format(), apply_filters() |
Across PHP versions
Compiles the same on PHP 7.4, 8.1, 8.2, 8.3, 8.4, 8.5 and 8.6-dev: 35 instructions, 20–27 executed per call, 1 branch. The work does not change between versions.
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 number_format_i18n() runs, in this order:
- apply_filters( number_format_i18n )filterline 439 (+19 into the body)
Filters the number formatted based on the locale.
Uses · 2
- absint()Converts a value to non-negative integer.
- apply_filters()Calls the callback functions that have been added to a filter hook.
Used by · 50
- Twenty_Fourteen_Ephemera_Widget::widget()Output the HTML for this widget.
- WP_Comments_List_Table::get_views()
- WP_Customize_Manager::handle_load_themes_request()Loads themes into the theme browsing/installation UI.
- WP_Customize_Manager::save_changeset_post()Saves the post for the loaded changeset.
- WP_Customize_Nav_Menus::customize_register()Adds the customizer settings and controls.
- WP_Customize_Nav_Menus::enqueue_scripts()Enqueues scripts and styles for Customizer pane.
- WP_Customize_Widgets::enqueue_scripts()Enqueues scripts and styles for Customizer panel and export data to JavaScript.
- WP_List_Table::ajax_response()Handles an incoming ajax request (called from admin-ajax.php)
- WP_List_Table::comments_bubble()Displays a comment count bubble.
- WP_List_Table::pagination()Displays the pagination.
- WP_MS_Sites_List_Table::column_users()Handles the users column output.
- WP_MS_Sites_List_Table::get_views()Gets links to filter sites by status.
Show all 50
- WP_MS_Themes_List_Table::get_views()
- WP_MS_Users_List_Table::get_views()
- WP_Plugin_Install_List_Table::display_rows()Generates the list table rows.
- WP_Plugins_List_Table::get_views()
- WP_Posts_List_Table::get_views()
- WP_Privacy_Requests_Table::get_views()Gets an associative array ( id => link ) with the list of views available on this table.
- WP_Screen::render_screen_layout()Renders the option for number of columns on the page.
- WP_Site_Health::get_test_page_cache()Tests if a full page cache is available.
- WP_Terms_List_Table::column_links()
- WP_Terms_List_Table::column_posts()
- WP_User_Search::do_paging()Handles paging for the user search query.
- WP_Users_List_Table::get_views()Returns an associative array listing all the views that can be used with this table.
- WP_Users_List_Table::single_row()Generates HTML for a single row on the users.php admin panel.
- WP_Widget_Media::display_media_state()Filters the default media display states for items in the Media list table.
- Walker_Category::start_el()Starts the element output.
- Walker_CategoryDropdown::start_el()Starts the element output.
- _wp_ajax_delete_comment_response()Sends back current comment total and new page links if they need to be updated.
- comments_popup_link()Displays the link to the comments for the current post ID.
- get_comments_number_text()Displays the language string for the number of comments the current post has.
- install_plugin_information()Displays plugin information in dialog box form.
- list_plugin_updates()Display the upgrade plugins form.
- list_theme_updates()Display the upgrade themes form.
- media_handle_upload()Saves a file submitted from a POST request and create an attachment post for it.
- media_upload_library_form()Outputs the legacy media upload form for the media library.
- paginate_links()Retrieves paginated links for archive post pages.
- post_submit_meta_box()Displays post submit form fields.
- print_embed_comments_button()Prints the necessary markup for the embed comments button.
- render_block_core_comments_title()Renders the `core/comments-title` block on the server.
- rest_validate_array_value_from_schema()Validates an array value based on a schema.
- rest_validate_object_value_from_schema()Validates an object value based on a schema.
- rest_validate_string_value_from_schema()Validates a string value based on a schema.
- size_format()Converts a number of bytes to the largest unit the bytes will fit into.
- timer_stop()Retrieves or displays the time from the page start to when function is called.
- wp_admin_bar_comments_menu()Adds edit comments link with awaiting moderation count bubble.
- wp_admin_bar_updates_menu()Provides an update link if theme/plugin/core updates are available.
- wp_ajax_query_themes()Handles getting themes from themes_api() via AJAX.
- wp_ajax_replyto_comment()Handles replying to a comment via AJAX.
- wp_dashboard_quota()Displays file upload quota on dashboard.
Source code
function number_format_i18n( $number, $decimals = 0 ) { global $wp_locale; if ( isset( $wp_locale ) ) { $formatted = number_format( $number, absint( $decimals ), $wp_locale->number_format['decimal_point'], $wp_locale->number_format['thousands_sep'] ); } else { $formatted = number_format( $number, absint( $decimals ) ); } /** * Filters the number formatted based on the locale. * * @since 2.8.0 * @since 4.9.0 The `$number` and `$decimals` parameters were added. * * @param string $formatted Converted number in string format. * @param float $number The number to convert based on locale. * @param int $decimals Precision of the number of decimal places. */ return apply_filters( 'number_format_i18n', $formatted, $number, $decimals );}Changelog
Introduced in 2.3.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 6.7.7 tag, from
src/wp-includes/functions.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.