Strings7 min readExamples run on PHP 8.5.10

str_decrement()

Learn how PHP 8.4 str_decrement() steps an alphanumeric ASCII string backwards, how carries work, and when it throws ValueError.

Signature

str_decrement(string $string): string
Available since PHP 8.3.07.48.08.18.28.38.48.5All versions →

Purpose

str_decrement() moves an alphanumeric ASCII string one step backwards, the way a counter that uses digits and letters would. It is the counterpart of str_increment(). The manual lists it as available since PHP 8.3.0, so it is also present in PHP 8.4. Typical uses are stepping backwards through spreadsheet-style column labels, short codes or alphanumeric identifiers.

The function works on the characters, not on numeric values. The string "19" is treated as two characters and becomes "18", which is still a string.

Signature

Parameters and defaults

  • $string: the input. It must be a non-empty string made only of ASCII letters and digits. There are no optional parameters and no defaults.

Return value and failure cases

The function returns the decremented string. When a position underflows, it wraps and borrows from the position to its left, so "ZA" becomes "YZ". When the leftmost character underflows, the result gets shorter, so "AA" becomes "Z".

It throws a ValueError in three situations:

  1. The string is empty.
  2. The string is not alphanumeric ASCII, for example it contains a hyphen or a space.
  3. The string cannot be decremented at all. The manual gives "A" and "0" as examples, because there is nothing before them.

There is no false or null return for failure, so use try/catch when the input is not trusted.

Example 1: basic stepping

The first example decrements a run of capital letters, a digit string and a lowercase string. Letter case is kept, and a lowercase borrow wraps to z.

Example
<?php
$values = ['ABC', '19', 'ba'];
$results = array_map('str_decrement', $values);
echo json_encode($results, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
Output
["ABB","18","az"]

Expected result: ["ABB","18","az"].

Example 2: borrowing across positions

When the last character is already the first of its range, it wraps to the last of that range and the next character on the left is decremented. If the leftmost character cannot go lower, the string loses one character.

Example
<?php
$words = ['ZA', 'BA', 'AA'];
foreach ($words as $word) {
    echo $word, ' -> ', str_decrement($word), "\n";
}
Output
ZA -> YZ
BA -> AZ
AA -> Z

The three lines show a normal borrow (ZA to YZ), a borrow that produces A on the left (BA to AZ), and a borrow that shortens the string (AA to Z).

Example 3: handling invalid input safely

Because invalid input throws, a small wrapper makes the behaviour easy to see. Here each failure is replaced with the word error.

Example
<?php
function tryDecrement(string $value): string
{
    try {
        return str_decrement($value);
    } catch (ValueError $error) {
        return 'error';
    }
}

$inputs = ['', 'A', '0', 'A-1', 'ABC'];
$results = array_map('tryDecrement', $inputs);
echo json_encode($results), "\n";
Output
["error","error","error","error","ABB"]

The empty string, the non-alphanumeric A-1, and the two strings that have no predecessor (A and 0) all fail. Only ABC succeeds.

Edge cases

  • The lowest value of a sequence has no predecessor, so "A" and "0" throw rather than returning an empty string.
  • Whitespace, punctuation and non-ASCII letters are rejected, even when they sit at the edge of the string.
  • The result is always a string. Do not expect an integer for digit-only input.
  • The function does not trim input. A trailing newline makes the string invalid.

Common mistakes

  • Treating it like $n - 1. Arithmetic on numeric strings gives numbers; str_decrement() edits characters and returns a string.
  • Forgetting the exception. Passing user input directly can crash a script with an uncaught ValueError. Validate the input or catch the error.
  • Assuming it mirrors -- on strings. In PHP, -- on a non-numeric string does not behave like this function, so call str_decrement() explicitly.
  • Expecting the shortened result to stay padded. "AA" becomes "Z", not "ZZ" or "A".
  • Mixing it up with str_increment(). They are inverse operations in the usual cases, but each one has its own error conditions.
  • str_increment() steps an alphanumeric string forward.
  • ord() and chr() work on single bytes if you need custom alphabets.
  • ctype_alnum() can help pre-check input, though you should still account for empty strings and strings that cannot go lower.

Recap

str_decrement() takes one non-empty ASCII alphanumeric string and returns its predecessor, borrowing to the left when needed and shortening the string when the leftmost character underflows. It throws ValueError for empty, non-alphanumeric, or lowest-value input such as "A" and "0". Wrap it in try/catch whenever the input is not controlled.

Tested examples

Basic decrementing of letters and digits
<?php
$values = ['ABC', '19', 'ba'];
$results = array_map('str_decrement', $values);
echo json_encode($results, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
Output
["ABB","18","az"]
Borrowing across positions
<?php
$words = ['ZA', 'BA', 'AA'];
foreach ($words as $word) {
    echo $word, ' -> ', str_decrement($word), "\n";
}
Output
ZA -> YZ
BA -> AZ
AA -> Z
Catching ValueError for invalid input
<?php
function tryDecrement(string $value): string
{
    try {
        return str_decrement($value);
    } catch (ValueError $error) {
        return 'error';
    }
}

$inputs = ['', 'A', '0', 'A-1', 'ABC'];
$results = array_map('tryDecrement', $inputs);
echo json_encode($results), "\n";
Output
["error","error","error","error","ABB"]