strncasecmp

Compares the first n bytes of two strings without regard to letter case.

Signature
strncasecmp(string $string1, string $string2, int $length): int
  • Added in PHP 4.0.2

Parameters

ParameterTypeDescription
$string1stringThe first string.
$string2stringThe second string.
$lengthintThe 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

Try it yourself
Loading editor…
Press Run to execute the code.

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.

Example · php
<?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.

Example · php
<?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

  • Be the first to comment on this lesson.