アキラ
PHPで、javascriptみたいなstartWidthとかendWidthないから不便だよね。
ワタル
あるよ。
アキラ
えっ。あんの?
ワタル
うん。PHP8からできた。
str_starts_with — 文字列が指定された部分文字列で始まるかを調べる
str_ends_with — 文字列が、指定された文字列で終わるかを調べる。
アキラ
この記事終わりだね。
ワタル
いやいやPHP8使えない環境あるでしょ。
アキラ
ワタル
そんなぁ。話進めるよ。
アキラ
登録してみるといい会社結構あるのに...
🐎
<?php
function startsWith($haystack, $needle) {
return @strncmp($haystack, $needle, strlen($needle)) === 0;
}
function endsWith($haystack, $needle) {]
return !@strlen($needle) ?: (substr_compare($haystack, $needle, -strlen($needle)) === 0);
}
echo(var_export(startsWith('aabbcc', 'aab')) . \"n"); // true
echo(var_export(startsWith('aabbcc', 'bcc')) . "\n"); // false
echo(var_export(startsWith('aabbcc', '')) . "\n"); // true
echo(var_export(endsWith('aabbcc', 'aab')) . "\n"); //false
echo(var_export(endsWith('aabbcc', 'bcc')) . "\n"); // true
echo(var_export(endsWith('aabbcc', '')) . "\n"); // true
ワタル
解説するよ。
アキラ
よろしく。
ワタル
ポイントは2つ。
まずは、startsWithで、
まずは、startsWithで、
strncmp
使っているところアキラ
あまり聞かないよね
ワタル
うん。 ネットとかでstartsWith作るときに
strpos
が0かどうかで判定してるコード落ちてたりするけど、strpos
だと$haystackの先頭になくても、場所を返す関数だから最後まで$needleを探しに行くから効率的じゃない。その点strncmp
はstrncmp — 最初の n 文字についてバイナリセーフな文字列比較を行う
ワタル
なので、最初しか見ないんだ。
アキラ
なるほど。
ワタル
2つ目のポイントは、endsWithで最初に
!@strlen($needle) ?:
なんてややこしいことやってるけど、これは、PHP8純正のstr_ends_with
に挙動を合わせてるんだ。アキラ
というと?
🐢
<?php
echo(var_export(str_ends_with('aabbcc', '')) . "\n"); // true
echo(var_export(str_ends_with('aabbcc', null)) . "\n"); // true
echo(var_export(str_ends_with('aabbcc', false)) . "\n"); // true
echo(var_export(str_ends_with('aabbcc', true)) . "\n"); // false
echo(var_export(str_ends_with('aabbcc', 0)) . "\n"); // false
ワタル
空文字とかnullを入れたときの戻りのことね。ここらへんがずれてるとめでたくPHP8導入して
str_ends_with
に置き換えたときに変なバグになるからね。アキラ
そういうバグ見つけにくいんだよねー。