Funktion mb_substr() - Teil eines strings zurückgeben

Häufig steht man bei der PHP-Programmierung vor der Aufgabe, nur Teile einer Zeichenkette verwenden zu müssen. Ein typisches Beispiel hierfür ist die Postleitzahl und der Ort, die häufig in einer Zeichenkette vorkommen. Wenn man z.B. nur den Ort benötigt, die Postleitzahl 5 Zeichen lang ist und danach ein Leerzeichen folgt, könnte man die ersten 6 Zeichen unberücksichtigt lassen und den Rest der Zeichenkette verwenden. Hierfür gibt es in PHP die Funktion substr(). Dabei wird davon ausgegangen, dass jedes Zeichen ein Byte belegt, sodass die ersten Bytes unberücksichtigt und der Rest zurückgegeben wird.

Wie viele Bytes von einem Zeichen belegt werden, hängt von der Zeichenkodierung ab, sodass man nicht immer davon ausgehen kann, dass 1 Zeichen 1 Byte belegt. Mit UTF-8 kann man wesentlich mehr Zeichen darstellen als mit ISO-8859-1. Daher werden immer mehr PHP-Seiten auf UTF-8 umgestellt bzw. damit entwickelt. Hierbei entsteht jedoch das Problem, dass für die Vielfalt der Zeichen in UTF-8 mehr Platz benötigt wird, sodass einzelne Zeichen mehr als nur 1 Byte belegen. Da mit der Funktion substr() davon ausgegangen wird, dass 1 Zeichen 1 Byte belegt, kommt es bei der Verwendung von UTF-8 zu unerwünschten Ergebnisse.

Beim folgenden Beispielcode enthält die Zeichenkette zu Beginn entweder vier Sonderzeichen oder Umlaute, die in UTF-8 zwei Bytes belegen. Danach folgt ein Bindestrich sowie die Zeichen ABCD. Wenn man die Funktion substr() mit dem Parameter 5 verwendet, könnte man annehmen, dass die ersten 5 Zeichen unberücksichtigt werden, sodass der Rückgabewert ABCD ist. Das ist jedoch nicht der Fall. Denn, die verwendeten Sonderzeichen und die Umlaute belegen in UTF-8 pro Zeichen 2 Bytes. Gibt man als Parameter die Zahl 5 an, bleiben somit Reste aus den Sonderzeichen übrig und der Rückgabewert enthält kryptische Zeichen.

<?php

$str = '¡¡¡¡-ABCD';

// Ausgabe �¡-ABCD
echo substr($str, 5);


$str = '££££-ABCD';

// Ausgabe �£-ABCD
echo substr($str, 5);


$str = 'ÄÄÄÄ-ABCD';

// Ausgabe �Ä-ABCD
echo substr($str, 5);


$str = 'ÖÖÖÖ-ABCD';

// Ausgabe �Ö-ABCD
echo substr($str, 5);

?>

Zeichenkodierung mit mb_substr() berücksichtigen

Eine Lösung hierfür kann die Multibyte-Funktion mb_substr() bieten. Sie funktioniert im Grunde genauso wie substr(), nur mit dem Unterschied, dass dabei auch die Zeichenkodierung berücksichtigt wird. Die Parameter der Funktion werden wie folgt angegeben.

  1. Zeichenkette.
  2. Anzahl der Zeichen, die zu Beginn nicht berücksichtigt werden sollen.
  3. Begrenzung des Rückgabewerts (optional).
  4. Zeichenkodierung (optional).

Wichtig ist dabei, den 3. Parameter anzugeben, wenn man die Zeichenkodierung angibt, da der PHP-Interpreter diese in der Reihenfolge erwartet. Falls der Rückgabewert aber nicht begrenzt werden soll, kann man als 3. Parameter null angeben, wodurch keine Begrenzung des Rückgabewerts erfolgt. Beim folgenden Beispielcode erhält man das gewünschte Ergebnis.

<?php

$str = '¡¡¡¡-ABCD';

// Ausgabe ABCD
echo mb_substr($str, 5, null, 'UTF-8');


$str = '££££-ABCD';

// Ausgabe ABCD
echo mb_substr($str, 5, null, 'UTF-8');


$str = 'ÄÄÄÄ-ABCD';

// Ausgabe ABCD
echo mb_substr($str, 5, null, 'UTF-8');


$str = 'ÖÖÖÖ-ABCD';

// Ausgabe ABCD
echo mb_substr($str, 5, null, 'UTF-8');

?>

Zeichenkodierung mit mb_internal_encoding() angeben.

Es ist auch möglich, die Zeichenkodierung nicht mit der Funktion mb_substr() anzugeben und dafür als Parameter über die Funktion mb_internal_encoding() festzulegen. Hierbei muss man darauf achten, diese vor dem erstmaligen Aufruf von mb_substr() zu setzen. Dadurch kann auch die Angabe des 3. Parameters mit null entfallen.

<?php

mb_internal_encoding('UTF-8');

$str = 'ÖÖÖÖ-ABCD';

// Ausgabe ABCD
echo mb_substr($str, 5);

?>

Ist die Zeichenkodierung weder mit mb_substr(), noch mit mb_internal_encoding() angegeben worden, wird die interne Zeichenkodierung verwendet. Man kann sie mit dem folgenden Code ermitteln.

<?php

echo mb_internal_encoding();

?>

Die interne Zeichenkodierung kann in der PHP-Konfigurationsdatei php.ini angepasst werden, z.B. mit dem Eintrag mbstring.internal_encoding = UTF-8. Ab der PHP-Version 5.6 gelten die Funktionen mbstring.internal_encoding und mb_internal_encoding als deprecated. Stattdessen soll der Eintrag default_charset in der php.ini angepasst werden. Die Funktion mb_substr() kann außerdem nur verwendet werden, wenn auf dem Server die PHP-Erweiterung mbstring aktiviert worden ist. Ob die Erweiterung verfügbar ist, kann man mit phpinfo() ermitteln. Die unterstützten Zeichenkodierungen kann man mit der Funktion mb_list_encodings() ermitteln. Der Rückgabewert der Funktion ist ein Array.