PHPの strcmp() は2つの文字列を比較し、結果を整数で返す関数です。大小関係(並び順)の判定に使いますが、if (strcmp($a, $b)) と書くと判定が逆になるという有名な落とし穴があります。この記事では戻り値の正しい読み方と、用途に応じた使い分けを解説します。
この記事の結論:
strcmp() は等しいと0、$str1が小さいと負・大きいと正を返します。等しいかを判定するなら strcmp($a, $b) === 0、あるいは単純な一致なら $a === $b を使うのが明快です。strcmpの戻り値の意味
| 関係 | 戻り値 |
|---|---|
| $str1 が $str2 より小さい | 負の整数 |
| $str1 と $str2 が等しい | 0 |
| $str1 が $str2 より大きい | 正の整数 |
基本の使い方
<?php
$result = strcmp("apple", "banana");
if ($result < 0) {
echo "apple の方が前"; // これが実行される
} elseif ($result > 0) {
echo "banana の方が前";
} else {
echo "等しい";
}
戻り値は「負・0・正」であり、必ずしも
-1 / 0 / 1 とは限りません。値の正負だけを見て判定し、「== -1」「== 1」のような厳密な値比較は避けてください。注意:if (strcmp(…)) は判定が逆になる
最も多い間違いがこれです。「等しいかどうか」を if (strcmp($a, $b)) で判定しようとすると、意図と逆の結果になります。等しいときの戻り値は 0=falsy(偽)だからです。
NG / OK: 等価判定
<?php
// NG: 等しいときに 0(偽)なので、if は「違うとき」に真になる
if (strcmp("apple", "apple")) {
echo "違う"; // 実行されない
} else {
echo "同じ"; // ← こちらが実行される(紛らわしい)
}
// OK: 0 と明示的に比較する
if (strcmp("apple", "apple") === 0) {
echo "同じ"; // 正しく判定
}
単に「文字列が一致するか」を見たいだけなら、
strcmp ではなく=== を使いましょう。if ($a === $b) のほうが読みやすく、意図も明確です。strcmp は大小(並び順)が必要なときに使う関数です。大文字・小文字を区別しない比較(strcasecmp)
strcmp() は大文字・小文字を区別します。区別せずに比較したいときは strcasecmp() を使います。
strcasecmpで大小文字を無視
<?php
var_dump(strcmp("Apple", "apple")); // 0 以外(区別する → 不一致)
var_dump(strcasecmp("Apple", "apple")); // 0(区別しない → 一致)
usortの比較関数として使う
strcmp() は「負・0・正」を返すため、並べ替えの比較関数(comparator)にそのまま使えるのが便利です。文字列の配列をアルファベット順に並べ替えられます。
usortで文字列をソート
<?php $fruits = ["banana", "apple", "cherry"]; usort($fruits, fn($a, $b) => strcmp($a, $b)); print_r($fruits); // apple, banana, cherry // 逆順なら引数を入れ替える usort($fruits, fn($a, $b) => strcmp($b, $a));
連想配列の値での並べ替えや、より複雑な比較関数は連想配列の値で並び替える方法(usortとカスタム比較関数)で詳しく解説しています。
補足:バイト比較と先頭N文字の比較
strcmp() はバイト単位で比較します。ASCIIの英数字なら辞書順になりますが、日本語などマルチバイト文字の「五十音順」にはなりません。また、先頭からN文字だけ比較したい場合は strncmp() を使います。
strncmpで先頭N文字を比較
<?php
// 先頭3文字だけ比較
var_dump(strncmp("apple", "application", 3)); // 0("app" が一致)
よくある質問(FAQ)
Qif (strcmp($a, $b)) で等しいか判定できますか?
Aできません。むしろ逆になります。等しいときの戻り値は
0(偽)なので、その if は「違うとき」に真になります。等価判定は strcmp($a, $b) === 0、もしくは単純に $a === $b を使ってください。Q文字列が一致するか調べるだけなら何を使う?
A
=== が最も明快で高速です(if ($a === $b))。strcmp は大小(並び順)が必要な場面で使う関数です。Qstrcmpの戻り値は必ず-1か1ですか?
Aいいえ。「負・0・正」であって、絶対値が1とは限りません。正負だけで判定し、
=== -1 のような厳密な値比較は避けてください。Q大文字小文字を無視して比較したいです。
A
strcasecmp() を使います。strcmp() は大文字小文字を区別しますが、strcasecmp() は区別しません。まとめ
strcmpのポイントを整理します。
- 戻り値は等しいと0・小さいと負・大きいと正(-1/1とは限らない)
if (strcmp(...))は判定が逆になる → 等価は=== 0- 単純な一致確認は
===が明快 - 大小文字を無視するなら
strcasecmp() - 「負・0・正」を返すので
usortの比較関数に最適
関連として、usortで連想配列を並び替える方法・if文による条件分岐・switch文の使い方もあわせて読むと、PHPの比較・分岐に強くなれます。

