PHPののstrtr関数について検証してみた
- 2015/12/06
- 12:00

目次
strtr関数の可能性を探る
ハロー、みなさん。エジソンです。PHPerの皆様におきましては、ご健勝の候うんぬんで御座いますが、PHPerじゃない方にも閲覧していただけると幸いです。
さて本日のお題ですが、みなさんは、PHPのstrtr関数をご存知でしょうか。
strtr
string strtr ( string $str , string $from , string $to )
引数を三つ渡した場合、この関数は str のコピーを返します。その際に、文字列中に from の各文字 (シングルバイト) があれば to の対応する文字に変換します。つまり、すべての $from[$n] が $to[$n] に置換されることになります。ここで $n は、どちらの引数でも共通に有効なオフセットです。 …
上記は、文字列の置換を実施する関数ですが、一方でポピュラーな関数として、真っ先に思い浮かべるのは、str_replace関数でしょう。こちらの関数も同様に文字列の置換が可能です。
そうなると、strtr関数の存在意義が薄れてしまうものですが、悩むこと数日を経て一つの考えが胸中に浮かび上がりました。
それは、strtr関数はパフォーマンスに優れた関数なのではないか、という事です。その考えが正しいのかを検証してみました。
strtr関数とstr_replace関数を比較してみよう
strtr関数とstr_replace関数の実行速度を比較してみました。ソース
<?php $str = 'hello world!'; /* * strtr 引数3つ */ $startTime = microtime(true); for ($i = 0; $i < 1000; $i++) { $conv = strtr($str, 'l', 'o'); } echo "strtr elapsed time : " . $conv . ' ' . sprintf("%.6F", (microtime(true) - $startTime)) . PHP_EOL; /* * strtr 引数2つ */ $startTime = microtime(true); $convPattern = array('l' => 'o'); for ($i = 0; $i < 1000; $i++) { $conv = strtr($str, $convPattern); } echo "strtr array elapsed time : " . $conv . ' ' . sprintf("%.6F", (microtime(true) - $startTime)) . PHP_EOL; /* * str_replace */ $startTime = microtime(true); for ($i = 0; $i < 1000; $i++) { $conv = str_replace('l', 'o', $str); } echo "str_replace elapsed time : " . $conv . ' ' . sprintf("%.6F", (microtime(true) - $startTime)) . PHP_EOL; ?>
結果
strtr elapsed time : heooo worod! 0.000364 strtr array elapsed time : heooo worod! 0.008314 str_replace elapsed time : heooo worod! 0.000349
結果から判明した事は、str_replace関数が一番早いという事でした。…、予想が外れました。ちなみに実行環境は、ローカルPCではなく、paiza.ioというWebサービスでコーディングしました。Webブラウザでプログラムコードを書いて、そのまま実行できるという有用なサイトです。
paiza.io
strtr関数の使い所について
strtr関数の公式マニュアルを読むと、”一度部分文字列の置換を行うと、 置換後の文字列がさらに置換の対象となることはありません。”とあります。この動作が、str_replace関数と唯一動作が異なる部分です。以下のサンプルコードで動作を確認してみる事にします。
サンプルコード
<?php $targetStr = '123 456 789'; // strtrで複数の検索&置換 echo strtr($targetStr, array('123' => '456', '456' => '123')) . PHP_EOL; // str_replaceで複数の検索&置換 echo str_replace(array('123' => '456'), array('456' => '123'), $targetStr) . PHP_EOL; ?>
結果
456 123 789 123 123 789
strtr関数では、一度置換された箇所が再度置換対象になることはありませんが、str_replace関数は一度置換された箇所も全てが置換対象となっていることがわかります。
要するに、str_replace関数は、一回目の置換が完了した後に置換後の文字列に対して新しく置換を実行していると言えます。一方で、strtr関数は、一回目の置換が完了すると、置換された部分はマーキングされ、二回目の置換では対象外になるのです。
このような違いがあることにより、strtr関数の有用性を見出すことができました。何かの時のために、これらの挙動が違うということを覚えておくと良いかと思います。