Strings7 min readExamples run on PHP 8.5.10

lcfirst()

Learn how PHP 8.4 lcfirst() lowercases only the first ASCII letter of a string, with examples, edge cases, and common mistakes.

Signature

lcfirst(string $string): string
Available since PHP 5.3.07.48.08.18.28.38.48.5All versions →

Purpose

lcfirst() makes the first character of a string lowercase. It leaves every other character exactly as it was. It is the mirror image of ucfirst(), and it is most often used when you need a camelCase identifier, such as turning UserName into userName for an array key, a method name or a JSON field.

The function only touches one character: the first byte of the string, and only if that byte is an ASCII capital letter from A to Z. Anything else is returned unchanged.

Signature

Parameters and defaults

  • $string: the input string. It is required and has no default value.

There are no flags, no locale argument and no optional parameters. The function always works the same way for the same input.

Return value and failure cases

lcfirst() returns a new string. The original value is not modified, so you must use the return value. If the first character is not an uppercase ASCII letter, the returned string is identical to the input. An empty string produces an empty string.

The function does not return false and does not emit warnings for unusual text. Failure is limited to type problems. Under declare(strict_types=1), passing a non-string such as an integer throws a TypeError. Passing an array always throws a TypeError. Pass a real string, and convert other values deliberately before you call it.

The PHP manual records one change: as of PHP 8.2.0, case conversion no longer depends on the locale set with setlocale(). Only ASCII characters are converted. In PHP 8.4 the result does not vary with the environment.

Example 1: basic behavior

Only the first letter changes. The rest of the text keeps its case, and a string that already starts in lowercase is returned as it is.

Example
<?php
echo lcfirst('HelloWorld'), PHP_EOL;
echo lcfirst('HELLO WORLD!'), PHP_EOL;
echo lcfirst('already lower'), PHP_EOL;
Output
helloWorld
hELLO WORLD!
already lower

The output is helloWorld, then hELLO WORLD!, then already lower. Notice that the second result is not fully lowercase. If you want every letter lowered, use strtolower().

Example 2: building camelCase names

A common pattern is to normalize a name, capitalize each word with ucfirst(), join the words and finally apply lcfirst() so the first word starts in lowercase.

Example
<?php
function toCamel(string $name): string
{
    $parts = explode('_', strtolower($name));
    $camel = '';
    foreach ($parts as $part) {
        $camel .= ucfirst($part);
    }
    return lcfirst($camel);
}

echo json_encode([
    toCamel('USER_FIRST_NAME'),
    toCamel('order_id'),
    toCamel('Status'),
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), PHP_EOL;
Output
["userFirstName","orderId","status"]

The output is ["userFirstName","orderId","status"]. The call to strtolower() first makes the input consistent, which matters when the source is uppercase like USER_FIRST_NAME.

Example 3: edge cases

Because lcfirst() has a strict, narrow rule, several inputs pass through untouched.

Example
<?php
$values = ['', 'Éclair', ' Hello', '9Lives', 'Z'];
$result = array_map('lcfirst', $values);
echo json_encode($result, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), PHP_EOL;
Output
["","Éclair"," Hello","9Lives","z"]

The output is ["","Éclair"," Hello","9Lives","z"]. The empty string stays empty. Éclair begins with a non-ASCII letter, so it is not converted. The string with a leading space is unchanged because the first character is the space, not the H. The digit-first string is unchanged for the same reason. A single Z becomes z.

Edge cases to remember

  • Leading whitespace: the function does not skip spaces. Use ltrim() first if the text may be padded.
  • Non-ASCII letters: characters such as É or Ä are not lowercased. lcfirst() is a byte-oriented ASCII helper, not a multibyte-aware one. For Unicode text you need a multibyte approach, for example splitting the first character with the mb_ functions.
  • Acronyms: URLParser becomes uRLParser. That is correct for the function but may not be what a naming convention expects.
  • Whole-word results: it never changes more than one character.

Common mistakes

  1. Expecting full lowercase. lcfirst('ABC') is aBC, not abc. Use strtolower() for the whole string.
  2. Ignoring the return value. Calling lcfirst($name); on its own statement does nothing useful because strings are passed by value. Assign the result.
  3. Assuming Unicode support. Accented capitals at the start are left alone, since only ASCII A to Z is converted.
  4. Forgetting to trim. Input from forms or text files often begins with spaces, which blocks the conversion.
  5. Relying on old locale behavior. Before PHP 8.2 the result could depend on the locale. Code written for PHP 8.4 should assume ASCII-only conversion.
  • ucfirst() makes the first character uppercase.
  • strtolower() lowercases the whole string.
  • strtoupper() uppercases the whole string.
  • ucwords() uppercases the first character of each word.

Recap

lcfirst(string $string): string returns a copy of the string with its first character lowercased, but only when that character is an ASCII capital letter. Everything else, including the empty string, non-ASCII letters, spaces and digits, is returned as is. Combine it with ucfirst() and strtolower() to build camelCase names, and always use the returned value.

Tested examples

Basic lcfirst() behavior
<?php
echo lcfirst('HelloWorld'), PHP_EOL;
echo lcfirst('HELLO WORLD!'), PHP_EOL;
echo lcfirst('already lower'), PHP_EOL;
Output
helloWorld
hELLO WORLD!
already lower
Building camelCase names
<?php
function toCamel(string $name): string
{
    $parts = explode('_', strtolower($name));
    $camel = '';
    foreach ($parts as $part) {
        $camel .= ucfirst($part);
    }
    return lcfirst($camel);
}

echo json_encode([
    toCamel('USER_FIRST_NAME'),
    toCamel('order_id'),
    toCamel('Status'),
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), PHP_EOL;
Output
["userFirstName","orderId","status"]
Edge cases with lcfirst()
<?php
$values = ['', 'Éclair', ' Hello', '9Lives', 'Z'];
$result = array_map('lcfirst', $values);
echo json_encode($result, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), PHP_EOL;
Output
["","Éclair"," Hello","9Lives","z"]