はじめに
PHPの文字列比較関数 strncmp() は「バイナリセーフな文字列比較を行う」と説明されています。
一見シンプルですが、「バイナリセーフって何?」「マルチバイト対応とはどう違うの?」と戸惑う方も多いはずです。この記事では、strncmp() の動作とバイナリセーフの意味を整理し、試験対策ポイントをわかりやすく解説します。
目次
strncmp() の基本動作
strncmp(string $string1, string $string2, int $length): int
先頭から $length
文字分を比較する
- バイナリセーフ(後述)
- 戻り値は以下の通り
- string1 < string2 → 負の値
- string1 > string2 → 正の値
- 等しい → 0
実例コード
<?php
declare(strict_types=1);
error_reporting(-1);
$string1 = 'abcdefg';
$string2 = 'abcDEFG';
$r = strncmp($string1, $string2, 3);
if ($r === 0) {
echo "2つの引数の比較結果は「等しい」でした";
} else {
echo "2つの引数の比較結果は「等しくない」でした";
}
実行結果
2つの引数の比較結果は「等しい」でした
理由:strncmp()
は 先頭3文字のみを比較するため、 "abc"
と "abc"
が一致 → 0 を返す。
もし strncmp($string1, $string2, 4)
とすると "d"
と "D"
の違いが現れ「等しくない」判定になる。
バイナリセーフとは?
バイナリセーフ = バイト列として文字列を扱い、ヌル文字 \0
を含んでも途中で切らないこと。
例
$a = "abc\0def";
$b = "abc";
echo strlen($a); // 7
echo strcmp($a, $b); // 正しく比較される
C言語由来の文字列処理なら \0
で終了扱いになりますが、PHPの文字列関数はバイナリセーフなので "def"
も含めて処理されます。
バイナリセーフ vs マルチバイト対応
項目 | バイナリセーフ | マルチバイト対応 |
---|---|---|
定義 | 文字列を バイト列としてそのまま処理する | UTF-8などの「複数バイトで1文字」を理解して処理する |
主な対象 | バイナリデータや特殊文字を含む場合 | 日本語や中国語などマルチバイト文字列 |
例 | strlen("abc\0def") → 7 | mb_strlen("あいう") → 3 |
関数群 | strlen , strcmp , strncmp , substr など | mb_strlen , mb_substr , mb_strpos など |
注意点 | 1文字=1バイトとして扱うためUTF-8で文字化けしやすい | 文字単位で処理できるが mbstring が必要 |
まとめ
strncmp()
は n文字分をバイナリセーフに比較する- バイナリセーフ =
\0
を含んでも処理が途中で切れない - マルチバイト対応とは別物(UTF-8の文字単位処理は
mbstring
系関数を使う)