Funktion mb_stripos() - Position eines Teil-Strings bei UTF-8

In PHP-Programmen muss häufig geprüft werden, ab welcher Position in einer Zeichenkette ein bestimmter Teil-String vorkommt. Eine Funktion für solche Überprüfungsaufgaben ist stripos(). Hierbei wird die Position eines Teil-Strings unabhängig von der Groß- und Kleinschreibung ermittelt. Dabei wird davon ausgegangen, dass 1 Zeichen genau 1 Byte belegt. Das kann jedoch dazu führen, dass der Rückgabewert von stripos() ungenau ist, da die Belegung der Bytes abhängig von der Zeichenkodierung ist. Beispielsweise belegen die Umlaute in UTF-8 nicht 1 Byte sondern 2 Bytes.

Dementsprechend kann der Rückgabewert der Funktion stripos() unrichtig sein, da hierbei die Zeichenkodierung und die von den Zeichen belegte Anzahl an Bytes unberücksichtigt wird. Beim folgenden Beispiel ist der Rückgabewert 6, obwohl das Zeichen ß bereits an der 4. Stelle vorkommt und man daher den Rückgabewert 3 erwarten würde.

<?php

$str = 'äöüß';

// Ausgabe 6
echo stripos($str, 'ß');

?>

Der "fehlerhafte" Rückgabewert 6 resultiert dadurch, dass die Umlaute die Bytes wie folgt belegen.

  • 0 und 1: ä
  • 2 und 3: ö
  • 4 und 5: ü
  • 6 und 7: ß

Zeichenkodierung mit mb_stripos() berücksichtigen

Falls man eine Zeichenkodierung verwendet, bei der ein Zeichen mehr als 1 Byte belegen kann (z.B. in UTF-8), kann man statt stripos() die Multibyte-Funktion mb_stripos() verwenden. Hierbei ist es möglich, als vierten Parameter die Zeichenkodierung anzugeben und man erhält dadurch genauere Ergebnisse. Ansonsten sind die beiden Funktionen identisch. Die Parameter werden somit wie folgt angegeben.

  1. Die Zeichenkette, in der nach dem Teil-String gesucht werden soll (haystack).
  2. Der Teil-String, nach dem in der Zeichenkette gesucht werden soll (needle).
  3. Die Startposition, ab der der Teil-String gesucht werden soll (offset, optional).
  4. Die Zeichenkodierung (encoding, optional).

Beim folgenden Beispiel enthält die Zeichenkette die Zeichen ä, ö, ü und ß. Das gesuchte Zeichen ist ß und der Rückgabewert der Funktion mb_stripos() ist 3, was somit der tatsächlichen Position des Zeichens entspricht.

<?php

$str = 'äöüß';

// Ausgabe 3
echo mb_stripos($str, 'ß', 0, 'UTF-8');

?>

Der Rückgabewert von mb_stripos() ist ein Integer-Wert, der die Position in der Zeichenkette angibt. Falls der gesuchte Teil-String nicht enthalten ist, ist der Rückgabewert FALSE (Typ bool). Wie bei der Funktion stripos() ist auch bei mb_stripos() zu beachten, dass falls der gesuchte Teil-String sich am Anfang der Zeichenkette befindet, der Rückgabewert 0 (entspricht dem Beginn) ist. Das kann bei einer weiteren Verarbeitung, z.B. mit der if-, else-Abfrage und dem Vergleichsoperator ==, zu unerwünschten Ergebnissen führen, da der Integer-Wert 0 als boolescher Wert FALSE ausgewertet wird.

Das kann verhindert werden, indem man bei der if-, else-Abfrage die Vergleichsoperatoren === (für Gleichheit) oder !== (für Ungleichheit) verwendet, mit denen auch eine Typprüfung vorgenommen wird.

<?php

$str = 'äöüß';

// Rückgabe Integer-Wert 0
$pos = mb_stripos($str, 'ä', 0, 'UTF-8');

if ($pos === FALSE)
{
  echo 'Zeichenkette enthält nicht ä';
}
else
{
  echo 'Zeichenkette enthält ä';
}

?>

Der dritte (offset) und vierte Parameter (Zeichenkodierung) kann auch entfallen. In dem Fall wird für die Zeichenkette die interne Zeichenkodierung zugrunde gelegt. Welche das ist, kann man mit mb_internal_encoding() ermitteln und ausgeben lassen.

<?php

echo mb_internal_encoding();

?>

Falls die interne Zeichenkodierung nicht wie erwünscht ist, kann man diese ändern. Hierfür kann man in der PHP-Konfigurationsdatei php.ini den Eintrag mbstring.internal_encoding = anpassen. Ab der PHP-Version 5.6 gelten die beiden Funktionen mb_internal_encoding und mbstring.internal_encoding jedoch als deprecated und man soll sie nicht mehr verwenden. Stattdessen ist vorgesehen, in der Datei php.ini den Eintrag default_charset anzupassen. Die Funktion mb_stripos() ist nur verfügbar, wenn auf dem Server die PHP-Erweiterung mbstring aktiviert ist. Ob die Erweiterung verfügbar ist, kann man mit der Funktion phpinfo() überprüfen. Die unterstützten Zeichenkodierungen kann man mit mb_list_encodings() überprüfen. Der Rückgabewert hierbei ist ein Array, den man z.B. mit der foreach-Schleife ausgeben lassen kann.