Navigation
 Startseite
 Fachbücher
 Anzeigenmarkt
 Forum
 Webmaster News
 Script Newsletter
 Push Meldungen
 Kontakt
 Script Installation
 Php
 Php Tutorials
 Lernpfade
 Webhoster Vergleich
 Impressum

Community-Bereich
 kostenlos Registrieren
 Anmelden
 Benutzerliste

Script Datenbank
 Script Archiv
 Script Top 20
 Screenshots
 Testberichte

Suche
 

Unsere Php Scripts
 Counter Script
 Umfrage Script
 Bilder Upload Script
 Terminverwaltung
 Simple PHP Forum
 RSS Grabber

Tools und Generatoren
 .htpasswd Generator
 md5 Generator
 base64 Generator
 Markdown to HTML
 Colorpicker
 Unix timestamp Tool
 Unit Test Generator
 TLD Liste
 Webkatalog‑Verzeichnis

Artfiles.de
Bietet Serviceorientierte...
https://www.Artfiles.de
Hosterplus.de
Bekommen Sie Speicherplatz (Webspace), Domains...
https://www.Hosterplus.de
 
 
 

PHP strncmp() Function: Syntax, Parameter, String-Vergleich

Sie befinden sich: Home > Php Tutorial > PHP strncmp() Function: Syn...

PHP strncmp() Function: Syntax, Parameter, String-Vergleich
Veröffentlicht am:
25.10.2026
Hits / Besucher:
8
Sprache:
  Deutsch
Tutorial Art:
eigenes
Eingetragen von:
Merkliste:
 
Beschreibung

Aus einer Logdatei mit einigen tausend Zeilen werden nur die gebraucht, die mit „ERROR“ beginnen. Wer dafür strpos() nimmt, findet das Wort auch mitten im Satz. Ganze Zeichenketten vergleicht strcmp(). PHP strncmp() schaut nur auf den Anfang: Die Funktion vergleicht so viele Bytes, wie der dritte Parameter vorgibt, und ignoriert den Rest.

Illustration zum Tutorial: PHP strncmp() Function: Syntax, Parameter, String-Vergleich

Drei Eigenheiten sorgen in der Praxis für Fehler: der Rückgabewert, der unter Linux anders aussieht als unter Windows, die Bedingung, die bei Gleichheit falsch herum läuft, und Umlaute, die zwei Bytes belegen.

Was PHP strncmp() macht

Ein typischer Fall ist die Prüfung, ob eine Eingabe mit einem bestimmten Kürzel beginnt, etwa eine deutsche IBAN mit „DE“:

<?php

$iban = 'DE89370400440532013000';

if (strncmp($iban, 'DE', 2) === 0) {
echo 'Deutsche IBAN';
}

Die 0 bedeutet „gleich“. Eine negative Zahl heißt, der erste String würde im Byte-Alphabet vor dem zweiten stehen, eine positive das Gegenteil. Wie PHP strncmp() zu diesem Ergebnis kommt, zeigt der Ablauf:

flowchart TD
    A[zwei Strings und Anzahl n]
    B[die ersten n Bytes nehmen]
    C{gleich bis zum kürzeren Ende?}
    D[Vorzeichen zeigt den kleineren]
    E{beide Teile gleich lang?}
    F[0, der Anfang ist gleich]
    G[kürzerer String ist kleiner]
    A --> B
    B --> C
    C -->|nein| D
    C -->|ja| E
    E -->|ja| F
    E -->|nein| G

Syntax und Parameter im Original

Alle drei Parameter sind Pflicht:

strncmp(

string $string1,
string $string2,
int $length
): int

/* Binary safe string comparison of the first
n characters (PHP 4, PHP 5, PHP 7, PHP 8).
Similar to strcmp(), with the difference
that you can specify how many characters
of each string are compared.

$string1 the first string to compare
$string2 the second string
$length number of characters to use in
the comparison

Return value: returns a value less than 0
if string1 is less than string2, a value
greater than 0 if string1 is greater than
string2, and 0 if the two strings are equal.

Related functions: strncasecmp(),
substr_compare() */

Mit „characters“ meint das Handbuch Bytes, das wird bei Umlauten wichtig. Bis PHP 7 hießen die Parameter $str1, $str2 und $len. Wer benannte Argumente mit diesen alten Namen übergibt, bekommt Error: Unknown named parameter $str1. Richtig ist strncmp(string1: $a, string2: $b, length: 4).

Der Rückgabewert von PHP strncmp() unter Linux und Windows

Oft liest man, seit PHP 8.2 gebe die Funktion nur noch -1, 0 und 1 zurück. Die Messung zeigt etwas anderes:

Aufruf Windows Linux
strncmp('Haus', 'Hausboot', 4) 0 0
strncmp('Haus', 'Hausboot', 5) -1 -1
strncmp('a', 'z', 1) -1 -25
strncmp('apfel', 'Apfel', 5) 1 32

Festgelegt hat PHP 8.2 nur den Fall unterschiedlich langer Strings, wie in der zweiten Zeile. Unterscheiden sich die Bytes selbst, reicht PHP das Ergebnis der C-Bibliothek durch. Unter Linux ist das die Differenz der Bytes, a hat den Wert 97 und z 122. Das galt unter PHP 8.4 und 8.5 gleichermaßen. Ein Test, der -1 erwartet, läuft unter Windows also grün und in einer Linux-Pipeline rot. Geprüft wird deshalb nur das Vorzeichen:

<?php

$ergebnis = strncmp('Haus', 'Hausboot', 5);

if ($ergebnis < 0) {
echo 'Haus kommt zuerst';
} elseif ($ergebnis > 0) {
echo 'Hausboot kommt zuerst';
} else {
echo 'Die ersten 5 Bytes sind gleich';
}

Die Falle: 0 heißt gleich

Weil Gleichheit als 0 zurückkommt und 0 in einer Bedingung als falsch gilt, läuft eine Kurzschreibweise genau verkehrt herum. Gedacht war, Kommentarzeilen zu überspringen:

<?php

$zeilen = ['# Kommentar', 'Berlin;10115'];

foreach ($zeilen as $zeile) {
if (strncmp($zeile, '#', 1)) {
continue;
}
echo $zeile;
}
/* Ausgabe: # Kommentar */

Übersprungen wird jede Zeile, die nicht mit „#“ beginnt. Richtig lautet die Bedingung strncmp($zeile, '#', 1) === 0. Wer immer ausdrücklich mit === 0 oder !== 0 vergleicht, tappt nicht hinein.

Der Parameter $length: 0, zu groß, negativ

Mit 0 als Länge ist das Ergebnis immer 0, auch für 'abc' und 'xyz'. Eine Länge über dem längeren String ist erlaubt, dann zählt der ganze String, und der kürzere ist kleiner: strncmp('abc', 'abcdef', 1000) ergab auf beiden Systemen -1. Eine negative Länge wirft einen ValueError:

<?php

try {
strncmp('abc', 'abc', -1);
} catch (ValueError $e) {
echo $e->getMessage();
}
/* strncmp(): Argument #3 ($length) must be
greater than or equal to 0 */

Ein Text als Länge, etwa 'zwei', führt zu einem TypeError, 2.5 zu einer Deprecation-Meldung und dem Wert 2. Wer null als String übergibt, bekommt seit PHP 8.1 ebenfalls eine Deprecation-Meldung, verglichen wird dann mit dem leeren String.

Präfix prüfen: strncmp() oder str_starts_with()?

Seit PHP 8.0 gibt es für die Frage „beginnt mit“ die Funktion str_starts_with(), die das Tutorial zu str_contains() und seinen Geschwistern vorstellt. In zehn Randfällen lieferten alle gängigen Schreibweisen dasselbe Ergebnis, darunter Treffer, kürzerer String, leerer Präfix (immer wahr), leerer String, Umlaut, Nullbyte sowie Groß- gegen Kleinschreibung. Unterschiede zeigten sich nur in der Laufzeit:

Schreibweise 2 Mio. Aufrufe, kurzer String 2000 Aufrufe, 1 MB ohne Präfix
strncmp($s, $p, strlen($p)) === 0 69 ms 0,1 ms
str_starts_with($s, $p) 37 ms unter 0,1 ms
substr($s, 0, strlen($p)) === $p 63 ms 0,1 ms
strpos($s, $p) === 0 49 ms 16 ms

Gemessen wurde unter Linux mit PHP 8.4, unter Windows lagen die Werte meist höher. Ein Aufruf mit kurzen Strings kostete einige Dutzend Nanosekunden, und die Reihenfolge der Varianten wechselte bei Wiederholungen. Der Ausreißer ist strpos(): Steht der Präfix nicht am Anfang, sucht es weiter, im ungünstigsten Fall durch den ganzen String. Für neuen Code ist str_starts_with() die lesbarere Wahl. PHP strncmp() bleibt nützlich, wenn eine Reihenfolge gebraucht wird oder die Länge nicht vom Präfix kommt.

Bytes statt Zeichen: Umlaute im String-Vergleich

Ein „Ä“ belegt in UTF-8 zwei Bytes, und beide Umlaute Ä und Ö beginnen mit demselben Byte. Wer ein Stichwortverzeichnis nach dem ersten Buchstaben gruppiert, bekommt deshalb falsche Treffer:

<?php

var_dump(strncmp('Äpfel', 'Öl', 1));
/* int(0): nur das erste Byte verglichen */

$p = 'Ä';
var_dump(strncmp('Öl', $p, strlen($p)) === 0);
/* bool(false), richtig */

$a = mb_substr('Äpfel', 0, 1);
$b = mb_substr('Öl', 0, 1);
var_dump($a === $b); /* bool(false) */

Die Regel lautet: Die Länge kommt immer aus strlen() des Präfixes, nie aus mb_strlen(). Wer Buchstaben statt Bytes vergleichen will, schneidet sie mit mb_substr() heraus. Umlaute sortiert PHP strncmp() außerdem hinter „z“, weil ihre Bytes größer sind. Für ein „é“, das einmal als ein Zeichen und einmal als „e“ plus Akzent gespeichert ist, meldet die Funktion Ungleichheit. Solche Texte vereinheitlicht man vorher mit dem Normalizer.

Binärsicher: Nullbytes und Dateisignaturen

In C endet eine Zeichenkette am ersten Nullbyte, und die C-Funktion gleichen Namens hört dort auf zu vergleichen. PHP strncmp() arbeitet binärsicher: strncmp("a\0b", "a\0c", 3) ergab -1, der Vergleich ging also hinter dem Nullbyte weiter. Damit taugt die Funktion für Binärdaten, etwa für die Signatur einer hochgeladenen Datei:

<?php

$kopf = file_get_contents($datei, false, null, 0, 8);

$png = "\x89PNG\r\n\x1a\n";
if (strncmp($kopf, $png, 8) === 0) {
echo 'PNG-Datei';
}

if (strncmp($kopf, "\xFF\xD8\xFF", 3) === 0) {
echo 'JPEG-Datei';
}

Gegen echte PNG- und JPEG-Dateien erkannte der Test beide Formate richtig. Die Signatur ist allerdings nur ein erster Filter, denn eine Datei kann mit den richtigen Bytes beginnen und trotzdem etwas anderes enthalten. Wie man den Typ zuverlässig prüft, zeigt das Tutorial zu finfo und Magic Bytes.

Praxis: Logzeilen, Autoloader und ein Array nach Präfix sortieren

Zurück zur Logdatei aus der Einleitung. Das Leerzeichen gehört zum Präfix, damit „ERRORS“ und „ERROR:“ nicht mitgezählt werden:

<?php

$fehler = array_filter(
file('app.log', FILE_IGNORE_NEW_LINES),
fn ($z) => strncmp($z, 'ERROR ', 6) === 0
);
/* trifft "ERROR 12:01 Datenbank weg",
nicht "ERRORS ..." und nicht "error ..." */

Dasselbe Muster steckt im Autoloader aus dem Tutorial zu PSR-4 Autoloading. Dort prüft PHP strncmp(), ob ein Klassenname mit dem Namespace beginnt. Der Backslash am Ende des Präfixes ist kein Zierrat:

<?php

$klasse = 'App2\Service\Mail';

$prefix = 'App\\';
$laenge = strlen($prefix);
var_dump(strncmp($prefix, $klasse, $laenge) === 0);
/* bool(false), richtig */

var_dump(strncmp('App', $klasse, 3) === 0);
/* bool(true), App2 rutscht durch */

Als Vergleichsfunktion für usort() sortiert PHP strncmp() nur nach den ersten Zeichen, hier nach dem Postleitzahlbereich:

<?php

$plz = ['28195 Bremen', '10115 Berlin',
'28203 Bremen', '10178 Berlin', '20095 Hamburg'];

usort($plz, fn ($a, $b) => strncmp($a, $b, 2));
echo implode(', ', $plz);
/* 10115 Berlin, 10178 Berlin, 20095 Hamburg,
28195 Bremen, 28203 Bremen */

Innerhalb eines Bereichs bleibt die ursprüngliche Reihenfolge erhalten, weil die Sortierung seit PHP 8.0 stabil ist.

Wo PHP strncmp() nicht passt

Versionsnummern gehören nicht in einen Byte-Vergleich. strncmp('8.40.1', '8.4', 3) liefert 0 und hält Version 8.40 damit für eine 8.4. Die Funktion version_compare() versteht die Teilnummern und ist hier richtig.

Auch für Geheimnisse eignet sich der Vergleich nicht. Er bricht beim ersten abweichenden Byte ab, und die Laufzeit verrät damit, wie viele Zeichen eines Tokens stimmen. Ein öffentlicher Präfix wie sk_live_ darf so geprüft werden, der Schlüssel selbst nur mit hash_equals(). Warum das für den ganzen String genauso gilt, steht im Sicherheitshinweis des Tutorials zu strcmp().

Soll die Groß- und Kleinschreibung keine Rolle spielen, ist strncasecmp() das Gegenstück, das wie strcasecmp() nur ASCII-Buchstaben angleicht. Wer den Vergleich nicht am Anfang, sondern ab einer bestimmten Position braucht, nimmt substr_compare().

Fazit

PHP strncmp() beantwortet eine einzige Frage: Stimmen die ersten n Bytes zweier Strings überein? Dafür ist die Funktion binärsicher und seit PHP 4 überall vorhanden. Ihre Zahl taugt nur als Vorzeichen, unter Linux kommt die Byte-Differenz, unter Windows -1 oder 1.

Für die meisten Präfixprüfungen in PHP 8 liest sich str_starts_with() besser. Wo PHP strncmp() bleibt, gilt: immer === 0 schreiben, die Länge mit strlen() bestimmen und für Versionen und Geheimnisse die Werkzeuge nehmen, die dafür gebaut sind.

 

Tags:

 

 

Kommentare (0)

Noch keine Kommentare. Sei der Erste!

Melde dich an, um einen Kommentar zu schreiben.
Bücherregal mit drei Büchern: 'PHP 4 - Grundlagen und Profiwissen' von Hanser Verlag, 'Webdesign in a Nutshell' von O'Reilly Verlag, und 'Webgestaltung' von Galileo Computing.