Sie können eine nette Eigenschaft von bitweisem XOR ( ^) verwenden , um dies zu erreichen: Wenn Sie zwei Zeichenfolgen zusammen xorieren, werden die gleichen Zeichen zu Null-Bytes ( "\0"). Wenn wir also die beiden Zeichenfolgen xorieren, müssen wir nur die Position des ersten Nicht-Null-Bytes ermitteln, indem wir strspn:
$position = strspn($string1 ^ $string2, "\0");
Das ist alles dazu. Schauen wir uns also ein Beispiel an:
$string1 = 'foobarbaz';
$string2 = 'foobarbiz';
$pos = strspn($string1 ^ $string2, "\0");
printf(
'First difference at position %d: "%s" vs "%s"',
$pos, $string1[$pos], $string2[$pos]
);
Das wird ausgegeben:
Erster Unterschied an Position 7: "a" gegen "i"
Das sollte es also tun. Es ist sehr effizient, da nur C-Funktionen verwendet werden und nur eine einzige Kopie des Speichers der Zeichenfolge erforderlich ist.
Bearbeiten: Eine MultiByte-Lösung entlang derselben Linie:
function getCharacterOffsetOfDifference($str1, $str2, $encoding = 'UTF-8') {
return mb_strlen(
mb_strcut(
$str1,
0, strspn($str1 ^ $str2, "\0"),
$encoding
),
$encoding
);
}
Zuerst wird der Unterschied auf Byte-Ebene mit der obigen Methode ermittelt und dann der Offset auf die Zeichenebene abgebildet. Dies geschieht mit der mb_strcutFunktion, die im Grunde genommen substrjedoch die Grenzen von Multibyte-Zeichen berücksichtigt.
var_dump(getCharacterOffsetOfDifference('foo', 'foa'));
var_dump(getCharacterOffsetOfDifference('©oo', 'foa'));
var_dump(getCharacterOffsetOfDifference('f©o', 'fªa'));
Es ist nicht so elegant wie die erste Lösung, aber es ist immer noch ein Einzeiler (und wenn Sie die Standardcodierung etwas einfacher verwenden):
return mb_strlen(mb_strcut($str1, 0, strspn($str1 ^ $str2, "\0")));