Funktion mb_strrpos() - Das letzte Vorkommen eines Teil-Strings in UTF-8 suchen

Wenn man in einer Zeichenkette das letzte Vorkommen eines Teil-Strings sucht, kann man hierfür die Funktion strrpos() verwenden. Die Position des gesuchten Teil-Strings wird hierbei nicht anhand der Vorhandenen Anzahl der Zeichen ermittelt, sondern anhand der Bytes, die diese belegen. Hierbei wird davon ausgegangen, dass 1 Zeichen 1 Byte belegt.

Wie viele Bytes ein Zeichen belegt, hängt jedoch von der Zeichenkodierung ab. Beispielsweise belegen die Umlaute in der Zeichenkodierung UTF-8 zwei Bytes. Beim folgenden Beispiel wird die Position des Zeichens ß ermittelt. Obwohl das Zeichen bereits an vierter Stelle vorkommt, ist der Rückgabewert 6.

<?php

$str = 'äöüßÄÖÜ';
$needle = 'ß';

// Ausgabe 6
echo strrpos($str, $needle);

?>

Die Ausgabe ist deshalb 6, weil die Umlaute die Bytes wie folgt belegen.

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

Falls man die Zeichenkodierung UTF-8 verwendet (oder eine andere Multibyte-Zeichenkodierung), kann man statt strrpos() die Funktion mb_strrpos() verwenden. Hierbei kann man als vierten Parameter auch die Zeichenkodierung angeben, sodass das Belegen von mehreren Bytes von einem Zeichen berücksichtigt wird. Die Parameter werden die 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 ist der Rückgabewert 3 und das entspricht der Position des Zeichens ß.

<?php

$str = 'äöüßÄÖÜ';

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

?>

Man erhält bei mb_strrpos() als Rückgabewert die Position des letzten Vorkommens vom gesuchten Teil-String. Der Datentyp ist dabei int. Wenn der gesuchte Teil-String nicht in der Zeichenkette enthalten ist, ist der Rückgabewert FALSE (Datentyp bool).

Falls der gesuchte Teil-String in der Zeichenkette zu Beginn (Position 0) vorkommt, ist der Rückgabewert 0 (Datentyp int). Wenn man in solch einem Fall anschließend den Rückgabewert auf FALSE abfragt, z.B. mit der if-, else-Abfrage und dem Vergleichsoperator ==, wird 0 (Datentyp int) als FALSE (Datentyp bool) ausgewertet und das wäre nicht richtig, da der Integer-Wert 0 das Vorkommen zu Beginn der Zeichenkette angibt und FALSE dass der Teil-String nicht enthalten ist.

In solchen Fällen sollte als Vergleichsoperator === (oder !== bei Prüfung auf Ungleichheit) verwendet werden. Damit wird neben dem Wert auch der Datentyp überprüft und der Integer-Wert 0 wird nicht als boolescher Wert FALSE ausgewertet.

<?php

$str = 'äöüßÄÖÜ';

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

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

?>

Die Parameter offset und encoding sind optional und können auch entfallen. In dem Fall gilt für offset als Standardwert 0 und für den vierten Parameter die interne Zeichenkodierung. Falls diese unbekannt ist, kann man die Funktion mb_internal_encoding() verwenden und mit echo ausgeben lassen.

<?php

echo mb_internal_encoding();

?>

Falls man die interne Zeichenkodierung anpassen möchte, kann man die PHP-Konfigurationsdatei php.ini z.B. über den Eintrag mbstring.internal_encoding = UTF-8 ändern. Ab der PHP-Version 5.6 gelten die beiden Funktionen mb_internal_encoding und mbstring.internal_encoding als deprecated und sollen nicht mehr zum Ändern der internen Zeichenkodierung verwendet werden. Stattdessen soll der Eintrag default_charset angepasst werden (ebenfalls in php.ini).

Wie die übrigen Multibyte-Funktionen ist mb_strrpos() nur verfügbar, wenn die PHP-Erweiterung mbstring auf dem Server verfügbar ist. Um das zu überprüfen, kann man die Funktion phpinfo() verwenden. Die unterstützten Zeichenkodierungen werden mit der Funktion mb_list_encodings() ausgelesen. Der Rückgabewert ist hierbei ein Array und kann beispielsweise über eine foreach-Schleife ausgelesen werden.