wppaste
WordPress

wp_basename( string $path, string $suffix = '' ): string

Since
3.1.0
Source
wp-includes/formatting.php:5676

Extracts the filename portion of a path or URL by wrapping PHP's basename() with URL-encoding so multibyte UTF-8 filenames survive intact. The optional $suffix trims an exact, case-sensitive trailing string such as a file extension. It does not sanitize or validate the result, so pair it with sanitize_file_name() before writing anything to disk.

i18n-friendly version of basename().

Compatibility

WordPress
since 3.1.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

$pathstring
A path.
$suffixstringoptional
If the filename ends in suffix this will also be cut off.Default: ''

Return value

string

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.

Get the filename from a full file system path

A plugin building a download link needs just the filename, not the full server path to a theme asset.

$path = get_stylesheet_directory() . '/style.css';
$filename = wp_basename( $path );

echo esc_html( $filename );

Strip a known extension from an uploaded filename

Code that needs the bare name of an image file, without its extension, to use as a slug or label.

$uploaded_path = '/var/www/html/wp-content/uploads/2024/01/vacation-photo.jpg';
$name_without_extension = wp_basename( $uploaded_path, '.jpg' );

echo esc_html( $name_without_extension );

The suffix match is case-sensitive, so '.JPG' would not be stripped by this call.

Common problems and fixes · 4

Why does plain basename() mangle a filename with accented or non-Latin characters, and does wp_basename fix that?

PHP's basename() is locale-dependent for multibyte strings, so a UTF-8 filename can lose characters on some servers. wp_basename works around this by urlencode()-ing the path before calling basename() and urldecode()-ing the result. - Use wp_basename() instead of basename() anywhere the filename might contain non-ASCII characters. - The workaround is only in wp_basename, plain basename() is unaffected.

Why did wp_basename split my filename on a slash-like sequence that wasn't a real path separator?

Before calling basename(), the function swaps the literal sequences %2F and %5C (which urlencode() would otherwise leave alone if they existed in the string) back to a forward slash. If your original filename genuinely contains those exact character sequences, they get treated as a path separator. - Rename files that contain encoded slash-like sequences in their name. - If you must preserve them, split the path yourself instead of relying on wp_basename.

Does the $suffix parameter strip any extension automatically, like pathinfo() can?

No. $suffix is passed straight through to PHP's basename(), which only removes it if it matches the end of the string exactly, including case. - Pass the full suffix with its dot, for example '.jpg', not just 'jpg'. - Use pathinfo() if you need extension detection that isn't an exact, case-sensitive match.

Can I hand wp_basename a full URL with a query string?

wp_basename operates on the string as given and does not parse URLs, so anything after a '?' is treated as part of the filename. - Strip the query string first, for example with wp_parse_url( $url, PHP_URL_PATH ), then pass that path to wp_basename.

Alternatives and related functions

basename
When the path is guaranteed to be plain ASCII and you don't need the UTF-8 safe encode/decode round trip.
pathinfo
When you need the extension, directory name, or filename without extension broken out separately, rather than just the base filename.
sanitize_file_name
When you're about to write the filename to disk or a database and need it stripped of unsafe or disallowed characters.
wp_check_filetype
When you need to determine or validate the file's MIME type rather than just extract its name.

Performance profile

How much work a call to wp_basename() 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

Touches nothing outside its own arguments.

Scaling
Constant

No loop in the body: the same number of instructions runs whatever you pass in.

Instructions
15

Executed per call on PHP 8.5. The body compiles to 15.

Plugin surface
None

Nothing here hands control to plugin code.

Called by
50

50 places in core call this, so the cost is paid more often than your own code shows.

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 wp_basename() can have, taken from its control-flow graph on PHP 8.5.

WhenInstructionsCalls it makes
always15urlencode(), basename(), urldecode()

Across PHP versions

PHPCompiledExecutedBranchesNotes
8.6-dev15150
8.515150
8.4151503 fewer instructions than PHP 8.3
8.318180
8.218180
8.118180
7.418180

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.

Used by · 50

Show all 50

Source code

function wp_basename( $path, $suffix = '' ) {	return urldecode( basename( str_replace( array( '%2F', '%5C' ), '/', urlencode( $path ) ), $suffix ) );}

Changelog

Introduced in 3.1.0. Unchanged from 6.7.7 through 7.1.0.

  1. 6.7.7
  2. 6.8.8
  3. 6.9.7
  4. 7.0.4
  5. 7.1.0

Signature, return type and hooks compared across 5 parsed releases.

About this page

Parsed data
Generated from the wordpress-develop 6.8.8 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.