Funktion mb_strpos() - Position von Teil-Strings ermitteln in UTF-8

Bei der Verarbeitung von Strings steht man häufig vor der Aufgabe, die Position des ersten Vorkommens von einem Zeichen bzw. einer Zeichenfolge zu ermitteln. Das kann beispielsweise notwendig sein, wenn man ermitteln möchte, ob eine Internetadresse mit http oder nur mit www beginnt. Für solche Überprüfungsaufgaben kann man die Funktion strpos() verwenden. Sie funktioniert im Grunde genauso wie stripos(). Der Unterschied zwischen den beiden Funktionen ist, dass strpos() case-sensitive ist und somit die Groß- und Kleinschreibung beachtet wird.

Mit der Funktion strpos() werden die Bytes bis zum ersten Vorkommen der gesuchten Zeichenfolge gezählt und es wird davon ausgegangen, dass ein Zeichen 1 Byte belegt. Das ist jedoch nicht immer der Fall, da es von der Zeichenkodierung abhängt, wie viele Bytes von einem Zeichen belegt werden. Die Umlaute belegen in der Zeichenkodierung UTF-8 z.B. zwei Bytes. Daher kann der Rückgabewert von strpos() unrichtig sein. Beim folgenden Beispiel wird das erste Vorkommen von ß ermittelt. Der Rückgabewert ist 6, obwohl das Zeichen an der 4. Stelle enthalten ist und die Funktion daher eine 3 zurückgeben müsste.

<?php

$str = 'äöüß';

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

?>

Der Rückgabewert ist "fälschlicherweise" 6, weil die einzelnen Zeichen die Bytes wie folgt belegen.

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

Zeichenkodierung mit der Funktion mb_strpos() berücksichtigen

Falls eine Zeichenkodierung verwendet wird, in der gewisse Zeichen mehr als 1 Byte belegen, beispielsweise in UTF-8, kann man statt strpos() die sogenannte Multibyte-Funktion mb_strpos() verwenden. Der Vorteil dabei ist, dass man als vierten Parameter die Zeichenkodierung angeben kann und damit das Belegen von mehreren Bytes von den Zeichen berücksichtigt wird. Die Parameter werden in mb_strpos() 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 wird das erste Vorkommen von ß ermittelt. Als Zeichenkodierung wird UTF-8 verwendet. Der Rückgabewert von mb_strpos() ist 3 und entspricht somit der tatsächlichen Position des Zeichens ß.

<?php

$str = 'äöüß';

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

?>

Der Rückgabewert von mb_strpos() entspricht der Position des ersten Vorkommens und ist vom Datentyp int. Falls das Zeichen jedoch nicht gefunden wird, ist der Rückgabewert FALSE und vom Datentyp bool. Das kann im weiteren Programmverlauf zu Ungenauigkeiten führen. Denn, falls das Zeichen zu Beginn gefunden wird, ist der Rückgabewert 0. Wenn man den Rückgabewert im weiteren Verlauf auf FALSE abfragt, z.B. mit der if-, else-Abfrage und dem Vergleichsoperator ==, wird 0 als FALSE ausgewertet und das wäre nicht richtig, da der Integer-Wert 0 das Vorkommen des gesuchten Zeichens darstellt und FALSE nicht.

In solchen Fällen ist es notwendig, als Vergleichsoperator === (bei Prüfung auf Gleichheit) oder !== (bei Prüfung auf Ungleichheit) zu verwenden, da damit auch eine Prüfung des Datentyps vorgenommen wird.

<?php

$str = 'äöüß';

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

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

?>

Der dritte und vierte Parameter (offset und encoding) kann auch weggelassen werden. In dem Fall wird bei der Verwendung der Funktion mb_strpos() die interne Zeichenkodierung zugrunde gelegt. Falls man die interne Zeichenkodierung ermitteln möchte, kann man die Funktion mb_internal_encoding() verwenden.

<?php

echo mb_internal_encoding();

?>

Die interne Zeichenkodierung kann geändert werden. Hierfür kann in der Konfigurationsdatei php.ini der Eintrag mbstring.internal_encoding = angepasst werden. Ab PHP 5.6 gelten die beiden Funktionen mb_internal_encoding und mbstring.internal_encoding als deprecated und man solle sie nicht mehr verwenden. Stattdessen ist es vorgesehen, in der php.ini den Eintrag default_charset anzupassen.

Die Funktion mb_strpos() ist außerdem nicht verfügbar, wenn auf dem Server die PHP-Erweiterung mbstring nicht aktiviert ist. Ob die Erweiterung aktiviert und zur Verfügung steht, kann man mit der Funktion phpinfo() ermitteln. Welche Zeichenkodierungen unterstützt werden, kann man mit mb_list_encodings() ermitteln. Den Rückgabewert kann man z.B. mit einer foreach-Schleife auslesen, da es sich hierbei um ein Array handelt.