strncasecmp
Compares the first n bytes of two strings without regard to letter case.
strncasecmp(string $string1, string $string2, int $length): int- Added in PHP 4.0.2
Parameters
| Parameter | Type | Description |
|---|---|---|
$string1 | string | The first string. |
$string2 | string | The second string. |
$length | int | The length of strings to be used in the comparison. |
Return value
intA value less than 0 if string1 is less than string2, a value greater than 0 if string1 is greater than string2, and 0 if they are equal. No particular meaning can be reliably inferred from the value aside from its sign.
Errors
Throws a ValueError if length is negative.
Changelog
- PHP 8.2.0This function is no longer guaranteed to return strlen($string1) - strlen($string2) when string lengths are not equal, but may now return -1 or 1 instead.
strncasecmp() compares at most the first n bytes of two strings, ignoring ASCII letter case. It is the case-insensitive form of strncmp() and the length-limited form of strcasecmp().
When to reach for it
It is the natural fit for prefix tests where the source controls the capitalisation and you do not: HTTP header names, URL schemes, file extensions, command keywords typed at a prompt. Because it stops after n bytes, it does no work on the rest of a long string.
if (strncasecmp($url, 'https://', 8) === 0) { /* secure */ }For a plain case-sensitive prefix test, str_starts_with() reads better. There is no case-insensitive equivalent, so strncasecmp() with strlen($prefix) remains the idiomatic way to write one.
What trips people up
The comparison counts bytes, not characters, so a length chosen by eye can cut a UTF-8 character in half. Derive it with strlen($prefix) instead of hard-coding a number.
Only ASCII A-Z is folded; accented letters are compared by byte value and are never equal to their uppercase forms. A negative length throws a ValueError.
Compare the result with === 0; only the sign is meaningful.
Example
When to use it
- Detect an HTTP header by name when the client's capitalisation is unpredictable.
- Check whether a URL starts with https:// regardless of how the scheme was typed.
- Match a user-typed command keyword such as "QUIT" or "quit" against a fixed list.
Frequently asked questions
What is the difference between strncasecmp and strncmp?
They are identical except that strncasecmp ignores ASCII letter case. strncmp('A', 'a', 1) is non-zero while strncasecmp('A', 'a', 1) is 0.
Is there a case-insensitive str_starts_with in PHP?
No built-in one exists. Use strncasecmp($haystack, $prefix, strlen($prefix)) === 0, which does the same job and stops after the prefix length.
Does strncasecmp work with UTF-8?
It compares bytes and only folds ASCII A-Z, so accented letters never match their uppercase forms. Use mb_strtolower() on both strings first, or mb_stripos(), for real multibyte comparison.
More examples
A case-insensitive starts-with test
The uppercase HTTPS:// URL is reported as secure, which str_starts_with($u, 'https://') would have missed. Deriving the length from strlen($prefix) keeps the check correct if the prefix ever changes.
<?php
$prefix = 'https://';
$urls = ['HTTPS://example.com', 'http://example.com', 'ftp://example.com'];
foreach ($urls as $u) {
$secure = strncasecmp($u, $prefix, strlen($prefix)) === 0;
echo $u, ' => ', $secure ? 'secure' : 'not secure', PHP_EOL;
}Oversized and negative lengths
A length larger than both strings is harmless when the strings are identical, but the second call is non-zero because 'php!' has an extra byte. The final block prints the ValueError message PHP 8 raises for a negative length.
<?php
var_dump(strncasecmp('PHP', 'php', 100)); // int(0)
var_dump(strncasecmp('PHP', 'php!', 100)); // negative — lengths differ
try {
strncasecmp('a', 'b', -1);
} catch (ValueError $e) {
echo 'ValueError: ', $e->getMessage(), PHP_EOL;
}
Discussion