1
0

More than 1 year has passed since last update.

PHP strrev関数のマルチバイト対応

Last updated at Posted at 2022-12-26

この記事はPHP 8.1.11を使用しています。

strrevがマルチバイト対応していないのでstrrevのマルチバイト対応関数をmb_strrevとして作成してみます。
結果から先にお伝えするとマルチバイト対応パターン1での対応が良さそうでした。

マルチバイト非対応

PHP標準関数のstrrevはマルチバイト対応に対応していないためstrrevにマルチバイト文字列を使用すると文字化けします。

$str = 'https://hogehoge.jp/りんご/バナナ/山田太郎/';
echo(strrev($str));

結果

'/��㎃骤尔籱匀�/��⊃㊃㐃㝀�/��━㓂㊂㙀�/pj.egohegoh//:sptth'

マルチバイト対応パターン1

文字列を1文字ずつ配列化 -> 要素を逆順 -> 文字列化します。

$str = 'https://hogehoge.jp/りんご/バナナ/山田太郎/';
echo implode('', array_reverse(mb_str_split($str, 1, 'UTF-8')));

結果

'/」郎太田山「/”ナナバ”/’ごんり’/pj.egohegoh//:sptth'

マルチバイト対応パターン2

文字列を1文字ずつ配列化 -> 要素を逆順 -> 文字列化します。

$str = 'https://hogehoge.jp/りんご/バナナ/山田太郎/';
$length = mb_strlen($str, 'UTF-8');
$array = [];
for ($i = 0; $i < $length; $i++){
    $text_string = mb_substr($str, $i, 1);
    $array[] = $text_string;
}

echo implode('', array_reverse($array));

結果

'/郎太田山/ナナバ/ごんり/pj.egohegoh//:sptth'

パターン1とパターン2のパフォーマンスを比較

パターン1

$str = str_repeat('https://hogehoge.jp/りんご/バナナ/山田太郎/', 100);
for ($n = 0; $n < 10; $n++) {
    $time_start = microtime(true);

    $res = implode('', array_reverse(mb_str_split($str, 1, 'UTF-8')));

    $time_end = microtime(true);
    $time = $time_end - $time_start;
    echo $time . "\n";
}

計測結果

0.00064992904663086
0.00030207633972168
0.00022697448730469
0.00016403198242188
0.00016188621520996
0.00016283988952637
0.00016283988952637
0.0001988410949707
0.00016283988952637
0.00016188621520996

パターン2

$str = str_repeat('https://hogehoge.jp/りんご/バナナ/山田太郎/', 100);
for ($n = 0; $n < 10; $n++) {
    $time_start = microtime(true);

    $length = mb_strlen($str, 'UTF-8');
    $array = [];
    for ($i = 0; $i < $length; $i++){
        $text_string = mb_substr($str, $i, 1);
        $array[] = $text_string;
    }
    $res = implode('', array_reverse($array));

    $time_end = microtime(true);
    $time = $time_end - $time_start;
    echo $time . "\n";
}

計測結果

0.11650204658508
0.13163304328918
0.11916780471802
0.11850309371948
0.12335705757141
0.12020015716553
0.11864614486694
0.12817692756653
0.11864900588989
0.13683700561523

比較したところパターン1の方が数百倍程度パフォーマンスが良い結果となりました。

関数化

パフォーマンスの良かったパターン1をmb_strrevとして関数化して完了とします。

public static function mb_strrev(string $str, string $from_encoding): string //{{{
{
    return implode('', array_reverse(mb_str_split($str, 1, $from_encoding)));
}
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0