Signature
ucfirst(string $string): stringPurpose
ucfirst() capitalizes the first character of a string. It is a small helper for turning hello into Hello, building labels from identifiers, or producing method names such as getEmail from a field name. It only looks at the first byte of the string and never touches the rest, so it is cheap and predictable.
Signature
Parameters and defaults
$string: the input string. It is required and has no default value.
The function takes no options. It does not accept a locale, an encoding or a list of delimiters. If you need those, look at the related functions below.
Return value and failure cases
ucfirst() returns a new string. The original variable is not modified. The first character is converted only if it is an ASCII letter from a (0x61) to z (0x7a). In every other situation the string is returned unchanged.
There is no false return and no warning for odd input. An empty string simply gives back an empty string. The only failure you can run into is a type problem: passing an array, or an object that cannot be converted to a string, throws a TypeError. In strict-types mode, passing an integer or a float also throws, while in the default coercive mode scalars are converted to strings first. Convert values explicitly, and do not pass null, so your intent is clear.
Since PHP 8.2.0, the conversion no longer depends on the locale set with setlocale(). Only ASCII characters are converted, so the result is the same on every server.
Example 1: the basics
The first example shows that ucfirst() leaves the remaining letters alone. To get a conventional sentence-style result from shouting text, lowercase it first.
echo json_encode([
ucfirst('hello world'),
ucfirst('HELLO'),
ucfirst(strtolower('HELLO')),
ucfirst(''),
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
echo "\n";["Hello world","HELLO","Hello",""]
Example 2: characters that are not changed
If the first byte is a digit, a space, an underscore, a newline or a non-ASCII letter, nothing happens. This surprises people who expect the first visible letter to be capitalized.
$values = ['123abc', ' apple', '_name', 'élan', "\nline"];
$result = [];
foreach ($values as $value) {
$result[] = ucfirst($value);
}
echo json_encode($result, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";["123abc"," apple","_name","élan","\nline"]
The leading space in ' apple' blocks the conversion, and é is outside the ASCII range, so 'élan' is unchanged. The newline in the last value is shown as \n because JSON escapes it.
Example 3: building readable labels
Because ucfirst() works on one string, it combines well with array_map() when you split an identifier into words.
function formatLabel(string $key): string
{
$words = explode('_', strtolower($key));
$words = array_map('ucfirst', $words);
return implode(' ', $words);
}
echo formatLabel('FIRST_NAME'), "\n";
echo formatLabel('postal_code'), "\n";First Name Postal Code
The input is lowercased first, so mixed-case keys still produce a consistent result.
Edge cases
- Empty string: returns an empty string.
- Leading whitespace: the string is unchanged if the first byte is a space, tab or newline. Use
trim()first if that is not what you want. - Already uppercase: the string is unchanged, and the rest of the letters are never lowercased.
- Multibyte text: accented letters, Greek, Cyrillic and similar scripts are not converted. A UTF-8 character spans several bytes, and
ucfirst()only handles ASCIIatoz. For such text, combinemb_substr()withmb_strtoupper(), or considermb_convert_case(), keeping in mind that title-case mode affects every word. - Digits and symbols: they have no case, so they pass through untouched.
Common mistakes
- Expecting the rest of the string to change.
ucfirst('PHP')is stillPHP. Lowercase the string first when you need a normalized form. - Using it for names in non-English text. Names that begin with a non-ASCII letter will not be capitalized.
- Expecting every word to be capitalized.
ucfirst('hello big world')only changes the first word. Useucwords()for each word. - Ignoring the return value. The function does not modify its argument, so calling
ucfirst($name);on its own does nothing useful. Assign the result. - Relying on locale settings. Older code sometimes called
setlocale()to affect case conversion. In PHP 8.2 and later, this has no effect onucfirst().
Related functions
lcfirst(): lowercases the first character.strtolower(): lowercases the whole string.strtoupper(): uppercases the whole string.ucwords(): uppercases the first character of each word.mb_convert_case(): performs case conversion for multibyte text.
Recap
ucfirst(string $string): string returns a copy of the string with its first character uppercased, but only when that character is an ASCII letter a to z. It leaves the rest of the string unchanged, ignores locale in PHP 8.2 and later, and gives back the input as is for empty strings, leading spaces, digits and non-ASCII letters. Pair it with strtolower() for normalized output and with ucwords() or the multibyte functions when the job is bigger than one ASCII letter.
Tested examples
echo json_encode([
ucfirst('hello world'),
ucfirst('HELLO'),
ucfirst(strtolower('HELLO')),
ucfirst(''),
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
echo "\n";
["Hello world","HELLO","Hello",""]
$values = ['123abc', ' apple', '_name', 'élan', "\nline"];
$result = [];
foreach ($values as $value) {
$result[] = ucfirst($value);
}
echo json_encode($result, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
["123abc"," apple","_name","élan","\nline"]
function formatLabel(string $key): string
{
$words = explode('_', strtolower($key));
$words = array_map('ucfirst', $words);
return implode(' ', $words);
}
echo formatLabel('FIRST_NAME'), "\n";
echo formatLabel('postal_code'), "\n";
First Name Postal Code