PHP string contains: 部分文字列を判定する方法

PHP の string contains 判定では、str_contains() を使ってある文字列に別の文字列が含まれるかを真偽値で確認します。ガード節、ルーティング判定、入力バリデーションのように、必要なのが yes/no の答えだけという場面に向いています。strpos() と比べると、0 が偽と解釈される落とし穴を避けられ、!== false も不要で読みやすくなります。str_contains() は PHP 8.0 以降で利用できます。

部分文字列を判定する PHP String Contains の例

出力:

ここに出力が表示されます...

出力:

ステータス: 発送済み

この例の仕組み

  1. $message にはステータスを表す通常の文字列を入れています。
  2. str_contains($message, "発送済み") は対象文字列(haystack)から部分文字列(needle)を探し、含まれているため true を返します。
  3. 戻り値は最初から真偽値なので、型変換を意識した比較なしで if ブロックが実行されます。

PHP の str_contains とは?

str_contains(string $haystack, string $needle): bool は PHP 8.0 の関数で、大文字小文字を区別するバイナリセーフな部分文字列チェックを行います。$needle$haystack のどこかに見つかれば true、見つからなければ false を返します。$needle が空文字の場合は常に true になり、これはバグではなく PHP 仕様で定義された挙動です。

str_contains() でよくある間違い

大文字小文字を区別しないと誤解する

悪い例:

str_contains("Hello World", "hello"); // false

正しい例:

stripos("Hello World", "hello") !== false; // true

str_contains() は大文字小文字を区別します。大文字小文字を無視した検索が必要なら、stripos() !== false を使います(または str_contains() の前に両方の文字列を正規化します)。

strpos() を真偽値として扱う(移行時の落とし穴)

悪い例:

if (strpos("発送済み", "発送")) echo "一致"; // 出力なし(0 は falsy)

正しい例:

if (strpos("発送済み", "発送") !== false) echo "一致";

PHP 8 以降で必要なのが真偽値だけなら、str_contains() を優先してください。

str_contains と strpos と stripos の違い

関数戻り値大文字小文字PHP バージョン
str_contains()bool区別する8.0+
strpos()int|false区別する4+
stripos()int|false区別しない5+

PHP 8 以降で必要なのが真偽値だけなら str_contains() を使います。一致位置が必要な場合や PHP 7.x をサポートする必要がある場合は strpos() を使います。一致位置も必要で大文字小文字を区別しない包含判定には stripos() を使います(戻り値は strpos() と同じくインデックスです)。

FAQ

str_contains は大文字小文字を区別しますか?

はい。str_contains("PHP", "php")false を返します。大文字小文字を区別しない判定が必要なら、str_contains() を呼ぶ前に strtolower() で両方を小文字化するか、stripos($haystack, $needle) !== false を使ってください。

空文字に対して str_contains が true を返すのはなぜですか?

定義上、空文字はすべての文字列の部分文字列です。これは PHP 8 で strpos("anything", "")0 を返す挙動とも一致します。これがコード上の誤判定につながる場合は、str_contains() を呼ぶ前に空入力を除外してください。

PHP 7 で string contains 判定をするには?

strpos($haystack, $needle) !== false を使います。!== false の厳密比較は必須です。strpos() は needle が先頭にあると 0 を返し、PHP では 0 が偽と評価されるためです。この落とし穴が、str_contains() が導入された主な理由です。