strcmp
Compares two strings byte by byte and returns a negative, zero or positive integer.
strcmp(string $string1, string $string2): int- Added in PHP 4.0
Parameters
| Parameter | Type | Description |
|---|---|---|
$string1 | string | The first string. |
$string2 | string | The second string. |
Return value
intA value less than 0 if string1 sorts before string2, greater than 0 if it sorts after, and 0 if they are identical.
Changelog
- PHP 8.2.0No longer guaranteed to return strlen($string1) - strlen($string2) for different-length strings; it may now return -1 or 1. Only the sign is meaningful.
strcmp compares two strings by their raw byte values and tells you which sorts first. It is binary-safe, so it handles strings containing null bytes, and it is case-sensitive: uppercase letters have lower byte values than lowercase ones, which is why 'Zebra' sorts before 'apple'.
When to reach for it
Its main job today is as a comparator for usort and friends, where a signed integer is exactly what the sort expects. It is also the right tool when you need a strict, non-juggling comparison of two strings that might both look numeric — '10' == '1e1' is true in PHP because both are numeric strings, while strcmp('10', '1e1') is non-zero.
What trips people up
As with strcasecmp, 0 means equal, so if (strcmp($a, $b)) fires when the strings differ. Test with === 0.
Since PHP 8.2 the magnitude is undefined — only the sign is contractual. Do not use the return value as a distance or length difference.
It sorts by bytes, not by human alphabet: digits come before uppercase, uppercase before lowercase, and UTF-8 accented letters land after all ASCII. For human-friendly ordering use strnatcmp for embedded numbers or Collator::compare() for locale-correct alphabetisation. For plain equality, $a === $b is simpler and faster than strcmp.
Example
When to use it
- Provide a comparator to usort for sorting an array of strings deterministically
- Compare two strings strictly when both might be numeric-looking and == would juggle them
- Order records by a text key inside a multi-field sort callback
Frequently asked questions
Should I use strcmp or === to compare strings in PHP?
Use === for a plain equality check; it is simpler and faster. Use strcmp when you need a signed ordering result, such as the return value of a usort comparator.
Why does strcmp return -1 instead of the difference in length?
PHP 8.2 dropped the guarantee that strcmp returns strlen($string1) - strlen($string2). Only the sign of the result is defined, so treat the value as less-than, equal or greater-than and nothing more.
Is strcmp case-sensitive?
Yes. 'Hello' and 'hello' compare as different because uppercase and lowercase letters have different byte values. Use strcasecmp for a case-insensitive comparison.
More examples
Sorting with a comparator
strcmp yields Apple, apple, banana, cherry because uppercase A (65) sorts before every lowercase letter. strcasecmp groups Apple and apple together at the front and ignores the case difference entirely.
<?php
$words = ['banana', 'Apple', 'cherry', 'apple'];
usort($words, 'strcmp');
print_r($words);
usort($words, 'strcasecmp');
print_r($words);Multi-field sorting
Output is dev/Ada, dev/Bob, ops/Zoe. The ?: operator falls through to the name comparison only when the department comparison returns 0, which is the standard tie-breaking idiom.
<?php
$rows = [
['dept' => 'ops', 'name' => 'Zoe'],
['dept' => 'dev', 'name' => 'Ada'],
['dept' => 'dev', 'name' => 'Bob'],
];
usort($rows, fn($a, $b) => strcmp($a['dept'], $b['dept'])
?: strcmp($a['name'], $b['name']));
foreach ($rows as $r) { echo $r['dept'], '/', $r['name'], "\n"; }Natural order versus byte order
strcmp gives img1, img12, img2 because '1' sorts before '2' character by character. strnatcmp gives img1, img2, img12, which is what a human expects from numbered files.
<?php
$files = ['img12.png', 'img2.png', 'img1.png'];
$a = $files; usort($a, 'strcmp'); print_r($a);
$b = $files; usort($b, 'strnatcmp'); print_r($b);
Discussion