PHPで文字列検索を行うstrpos関数の使い方と注意点を解説します。戻り値が0の場合の判定ミスなど初心者が陥りやすい落とし穴や、マルチバイト文字列対応のmb_strpos、そしてPHP8で導入されたより直感的なstr_contains関数まで網羅。strstr、preg_matchなど他の検索方法との使い分けも理解でき、実務で安全に文字列検索を実装できるようになります。
“`html
目次
PHP strpos関数とは?

PHPで文字列操作を行う際に頻繁に使用される関数の一つが、strpos関数です。Webアプリケーション開発において、特定の文字列が含まれているかをチェックしたり、その位置を特定したりする作業は日常的に発生します。strpos関数は、こうした文字列検索のニーズに応える基本的かつ重要な組み込み関数として、多くのPHP開発者に利用されています。
strpos関数の基本概要
strpos関数は、文字列内で指定した部分文字列が最初に現れる位置を検索するPHPの標準関数です。関数名の「strpos」は「string position(文字列の位置)」を意味しており、その名の通り文字列内での位置情報を取得することができます。
この関数は大文字と小文字を区別する(case-sensitive)という特徴があり、検索対象の文字列に対して前方から順に検索を行います。検索が成功した場合は該当する文字列が見つかった位置を整数値で返し、見つからなかった場合はfalseを返すという明確な動作仕様を持っています。
strpos関数の主な特徴は以下の通りです:
- 検索対象の文字列内で、指定した部分文字列の開始位置を返す
- 位置は0から始まるインデックス番号で表現される
- 大文字と小文字は異なる文字として扱われる
- 最初にマッチした位置のみを返す(複数存在しても最初の一つのみ)
- シングルバイト文字列の検索に最適化されている
strpos関数の役割と用途
strpos関数は、PHPプログラミングにおいて幅広い用途で活用されています。単純な文字列の存在チェックから、より複雑な文字列処理の基盤として機能することまで、その役割は多岐にわたります。
実務における主な用途として、まず文字列の包含判定が挙げられます。例えば、ユーザーが入力したメールアドレスに「@」記号が含まれているかをチェックしたり、URLに特定のドメイン名が含まれているかを確認したりする際に使用されます。この場合、戻り値がfalseでなければ文字列が含まれていると判断できます。
次に、文字列の分割や抽出の準備としての役割があります。特定の区切り文字やキーワードの位置を特定することで、substr関数などと組み合わせて文字列を適切に分割・抽出することが可能になります。例えば、ファイルパスから拡張子を取得する際に、最後のドット(.)の位置を特定するといった使い方です。
さらに、条件分岐の判定条件としても頻繁に利用されます。特定の文字列が含まれている場合とそうでない場合で処理を分けたり、文字列の位置に応じて異なる処理を実行したりする際の判定基準として活用されます。
具体的な用途の例:
- URLやファイルパスの解析と検証
- ユーザー入力のバリデーション処理
- ログファイルやCSVデータの解析
- HTMLタグやマークアップの検出
- 検索機能における簡易的なマッチング
- 文字列の前処理や整形の判定基準
このように、strpos関数はPHPにおける文字列操作の基礎となる関数であり、シンプルながらも非常に実用的な機能を提供しています。ただし、マルチバイト文字(日本語など)を扱う場合や、より複雑な検索パターンが必要な場合には、他の関数との使い分けが必要になることも理解しておくことが重要です。
“`
strpos関数の基本的な使い方

PHPで文字列検索を行う際に最も基本的な関数であるstrposは、シンプルながら強力な機能を持っています。ここでは、strpos関数を正しく使いこなすための基本的な構文から、実際のコード例まで詳しく解説していきます。正確な使い方を理解することで、文字列処理をより効率的に行えるようになります。
基本的な構文と書式
strpos関数の基本的な構文は非常にシンプルで、以下のような形式で記述します。
strpos(string $haystack, string $needle, int $offset = 0): int|falseこの関数は、$haystack(検索対象の文字列)の中から$needle(検索したい文字列)を探し、最初に見つかった位置を返すという動作を行います。第3引数の$offsetは省略可能で、指定した場合は検索開始位置を変更できます。
関数名のstrposは「string position(文字列の位置)」を意味しており、その名の通り文字列内での位置情報を取得するために設計されています。PHPの標準関数として古くから提供されているため、多くのプロジェクトで広く使用されています。
パラメータの詳細説明
strpos関数の各パラメータについて、それぞれの役割と使い方を詳しく見ていきましょう。
- $haystack(第1引数・必須):検索対象となる文字列を指定します。この文字列の中から特定の文字列を探す処理が行われます。日本語などのマルチバイト文字を含む場合は注意が必要です。
- $needle(第2引数・必須):検索したい文字列やパターンを指定します。大文字・小文字は区別されるため、「PHP」と「php」は異なる文字列として扱われます。空文字列を指定した場合は警告が発生します。
- $offset(第3引数・任意):検索を開始する位置をバイト数で指定します。デフォルトは0で、文字列の先頭から検索を開始します。正の値を指定すると、その位置から末尾方向へ検索し、負の値を指定すると末尾からのオフセットとして扱われます。
これらのパラメータを適切に組み合わせることで、柔軟な文字列検索処理を実現できます。特に$offsetパラメータを活用すると、同じ文字列が複数回出現する場合に2回目以降の位置を特定することも可能です。
戻り値の仕様について
strpos関数の戻り値は、検索結果によって異なる型を返すため、正確な理解が重要です。
検索が成功した場合、最初に見つかった文字列の位置を整数値(int)で返します。この位置は0から始まるインデックスで表され、文字列の先頭が0、次の文字が1という形式です。例えば、「Hello World」という文字列で「World」を検索した場合、戻り値は6となります。
一方、検索したい文字列が見つからなかった場合は、boolean型のfalseを返します。この仕様が、strpos関数を使用する際の最も重要な注意点に繋がります。なぜなら、文字列の先頭(位置0)で見つかった場合と、見つからなかった場合(false)を単純な条件式で判定すると、誤った結果になる可能性があるからです。
| 検索結果 | 戻り値の型 | 戻り値の例 |
|---|---|---|
| 文字列が見つかった | int(整数) | 0, 1, 2, 3… |
| 文字列が見つからなかった | false(boolean) | false |
このように、strpos関数は検索成功時にint型、失敗時にfalse型という異なる型を返す設計になっているため、戻り値の判定には型も含めた厳密な比較が必要になります。
実際のサンプルコード
ここでは、strpos関数の実際の使用例をいくつか紹介します。基本的な使い方から応用例まで、具体的なコードを見ていきましょう。
基本的な検索の例:
<?php
$text = "PHPはWeb開発に適したプログラミング言語です";
$position = strpos($text, "Web");
if ($position !== false) {
echo "「Web」は位置 {$position} に見つかりました";
} else {
echo "「Web」は見つかりませんでした";
}
// 出力:「Web」は位置 8 に見つかりました
?>このコードでは、厳密比較演算子(!==)を使用してfalseとの比較を行っている点が重要です。これにより、位置0で見つかった場合と見つからなかった場合を正確に区別できます。
検索開始位置を指定する例:
<?php
$email = "test@example.com";
$firstAt = strpos($email, "@");
$secondAt = strpos($email, "@", $firstAt + 1);
if ($secondAt !== false) {
echo "2つ目の@が見つかりました";
} else {
echo "@は1つだけです";
}
// 出力:@は1つだけです
?>この例では、$offsetパラメータを使用して、最初に見つかった位置の次から検索を再開しています。このテクニックは、同じ文字列が複数回出現する可能性がある場合に有効です。
文字列の存在確認の例:
<?php
$url = "https://example.com/page";
// URLがhttpsで始まるかチェック
if (strpos($url, "https://") === 0) {
echo "安全な接続です";
} else {
echo "接続を確認してください";
}
// 出力:安全な接続です
?>この例では、戻り値が0であることを厳密に確認することで、文字列が先頭から始まるかどうかを判定しています。=== 0という比較により、位置0で見つかった場合のみtrueとなるため、正確な判定が可能です。
大文字・小文字を区別しない検索の例:
<?php
$text = "Welcome to PHP Programming";
$search = "php";
// stripos関数を使用(大文字・小文字を区別しない)
$position = stripos($text, $search);
if ($position !== false) {
echo "「{$search}」は位置 {$position} に見つかりました";
} else {
echo "「{$search}」は見つかりませんでした";
}
// 出力:「php」は位置 11 に見つかりました
?>strpos関数は大文字・小文字を区別しますが、区別せずに検索したい場合はstripos関数を使用します。この関数は、strposと同じ構文で動作しながら、大文字・小文字の違いを無視して検索を行うことができます。
“`html
strpos関数を使う際の重要な注意点

PHP strpos関数は非常に便利な文字列検索機能ですが、正しく使用するためにはいくつかの重要な注意点があります。特に戻り値の扱いを誤ると、予期しないバグを引き起こす可能性があります。ここでは、strpos関数を使用する際に必ず理解しておくべき注意事項について詳しく解説します。
戻り値の型判定における注意事項
strpos関数の戻り値は、整数型またはfalseのいずれかになります。文字列が見つかった場合は見つかった位置(整数値)を返し、見つからなかった場合はfalse(論理値)を返すという仕様です。この異なる型が返される可能性があるため、戻り値を適切に判定しないと正常に動作しません。
特に問題となるのは、厳密な比較演算子(===)を使用する必要があるという点です。通常の比較演算子(==)では、0とfalseが同じ値として扱われてしまうため、正確な判定ができません。以下のように必ず厳密な比較演算子を使用してください。
<?php
$text = "Hello World";
$pos = strpos($text, "H");
// 正しい判定方法
if ($pos !== false) {
echo "文字列が見つかりました。位置: " . $pos;
} else {
echo "文字列が見つかりませんでした。";
}
// 誤った判定方法
if ($pos != false) {
// 0が返された場合でもfalseと判定されてしまう
echo "この判定は正しく動作しません";
}
?>この型判定を間違えると、デバッグが困難なバグの原因となりますので、常に厳密な比較演算子(===、!==)を使用することを習慣づけましょう。
falseと0の判定で気をつけるべきこと
strpos関数で最も注意が必要なのは、検索文字列が先頭にある場合に戻り値が0になるという点です。PHPでは0は「偽(false)」として評価されるため、通常のif文やwhile文では意図しない動作を引き起こします。
具体的な問題と解決策を以下のコード例で確認してください。
<?php
$text = "PHPは便利なプログラミング言語です";
$pos = strpos($text, "PHP");
// 誤った判定例
if ($pos) {
echo "見つかりました";
} else {
echo "見つかりませんでした"; // 0は偽として評価されるため、こちらが実行される
}
// 正しい判定例
if ($pos !== false) {
echo "見つかりました。位置: " . $pos; // 正しく「見つかりました。位置: 0」と表示される
} else {
echo "見つかりませんでした";
}
// 別の正しい判定例
if (is_int($pos)) {
echo "見つかりました。位置: " . $pos;
} else {
echo "見つかりませんでした";
}
?>このように、必ずfalseとの厳密な比較、またはis_int関数を使用した型チェックを行うことで、正確な判定が可能になります。特に検索対象の文字列が先頭に存在する可能性がある場合は、この点を必ず意識してコーディングしてください。
検索開始位置を指定する方法
strpos関数には、第3引数として検索開始位置を指定できるという便利な機能があります。この機能を活用することで、文字列の途中から検索を開始したり、同じ文字列が複数回出現する場合に2回目以降の位置を見つけたりすることができます。
検索開始位置の基本的な使い方は以下の通りです。
<?php
// 基本構文
// strpos(検索対象文字列, 検索文字列, 検索開始位置)
$text = "apple banana apple orange apple";
// 最初の"apple"を検索
$pos1 = strpos($text, "apple");
echo "1回目: " . $pos1 . "\n"; // 結果: 0
// 最初の"apple"の次から検索
$pos2 = strpos($text, "apple", $pos1 + 1);
echo "2回目: " . $pos2 . "\n"; // 結果: 13
// さらに次の"apple"を検索
$pos3 = strpos($text, "apple", $pos2 + 1);
echo "3回目: " . $pos3 . "\n"; // 結果: 26
?>この機能を利用すると、文字列内に含まれるすべての特定文字列の位置を取得することも可能です。以下は実践的な応用例です。
<?php
$text = "PHP is great. PHP is powerful. PHP is popular.";
$search = "PHP";
$positions = [];
$offset = 0;
// すべての"PHP"の位置を配列に格納
while (($pos = strpos($text, $search, $offset)) !== false) {
$positions[] = $pos;
$offset = $pos + 1; // 次の検索は見つかった位置の次から
}
echo "「" . $search . "」が見つかった位置: ";
print_r($positions);
// 結果: Array ( [0] => 0 [1] => 14 [2] => 31 )
?>ただし、検索開始位置に負の値を指定するとエラーになるため注意が必要です。また、開始位置が文字列の長さを超えている場合は、falseが返されます。検索開始位置を動的に指定する場合は、値の範囲チェックを行うことをおすすめします。
| パラメータ | 説明 | 注意点 |
|---|---|---|
| 第1引数 | 検索対象の文字列 | 必須 |
| 第2引数 | 検索する文字列 | 必須 |
| 第3引数 | 検索開始位置(省略可) | 0以上の整数を指定、負の値はエラー |
検索開始位置を適切に活用することで、より高度な文字列処理が可能になります。繰り返し検索を行う場合や、特定の位置以降だけを対象にしたい場合などに非常に有効な機能です。
“`
mb_strposによるマルチバイト文字列の検索

PHPで日本語などのマルチバイト文字列を扱う際には、通常のstrpos関数では正しく動作しないケースがあります。これは、strpos関数が1バイトを1文字として扱うため、日本語のような複数バイトで構成される文字列の位置を正確に取得できないためです。このような場合に使用するのがmb_strpos関数です。本セクションでは、マルチバイト文字列を正確に検索するための方法について詳しく解説します。
mb_strpos関数とは
mb_strpos関数は、マルチバイト対応の文字列検索関数で、日本語(UTF-8、Shift_JIS、EUC-JPなど)や中国語、韓国語などの2バイト以上で構成される文字列を正確に扱うことができます。通常のstrpos関数がバイト単位で位置を返すのに対し、mb_strpos関数は文字単位で位置を返すという重要な違いがあります。
この関数は、PHPのマルチバイト文字列拡張モジュール(mbstring)に含まれており、多くのPHP環境でデフォルトで有効になっています。日本語サイトやアジア圏向けのWebアプリケーションを開発する際には、必須の関数といえるでしょう。
mb_strposの基本的な使い方
mb_strpos関数の基本構文は以下の通りです。文字エンコーディングを指定することで、様々な文字コードに対応できます。
mb_strpos(string $haystack, string $needle, int $offset = 0, ?string $encoding = null): int|false各パラメータの意味は次の通りです。
- $haystack: 検索対象となる文字列
- $needle: 検索する文字列
- $offset: 検索を開始する位置(省略可能、デフォルトは0)
- $encoding: 文字エンコーディング(省略可能、デフォルトは内部エンコーディング)
実際の使用例を見てみましょう。
<?php
// 日本語文字列での検索
$text = "こんにちは、世界!";
$position = mb_strpos($text, "世界", 0, "UTF-8");
if ($position !== false) {
echo "「世界」は{$position}文字目に見つかりました。"; // 結果: 「世界」は6文字目に見つかりました。
} else {
echo "見つかりませんでした。";
}
// 通常のstrposとの比較
$pos_strpos = strpos($text, "世界");
$pos_mb_strpos = mb_strpos($text, "世界", 0, "UTF-8");
echo "strposの結果: " . $pos_strpos . "\n"; // バイト単位の位置
echo "mb_strposの結果: " . $pos_mb_strpos . "\n"; // 文字単位の位置
?>この例では、mb_strpos関数を使用して日本語文字列内で「世界」という単語を検索しています。文字単位で正確な位置を取得できるため、マルチバイト文字列の処理に最適です。
日本語文字列を扱う際のポイント
日本語をはじめとするマルチバイト文字列を扱う際には、いくつかの重要なポイントを押さえておく必要があります。これらを理解することで、バグの少ない堅牢なコードを書くことができます。
文字エンコーディングの明示的な指定
mb_strpos関数を使用する際は、文字エンコーディングを明示的に指定することを強く推奨します。省略した場合は内部エンコーディングが使用されますが、環境によって異なる可能性があるため、予期しない動作を防ぐために明示的に指定しましょう。
<?php
// 良い例: エンコーディングを明示的に指定
$position = mb_strpos($text, $search, 0, "UTF-8");
// 避けるべき例: エンコーディングを省略
$position = mb_strpos($text, $search);
?>戻り値の型チェック
mb_strpos関数もstrpos関数と同様に、文字列が見つからない場合はfalseを返します。そのため、厳密な比較演算子(===)を使用して判定する必要があります。
<?php
$text = "今日はいい天気です";
$position = mb_strpos($text, "今日", 0, "UTF-8");
// 正しい判定方法
if ($position !== false) {
echo "文字列が見つかりました。";
}
// 誤った判定方法(0の場合にfalseと判定されてしまう)
if ($position) {
echo "文字列が見つかりました。";
}
?>内部エンコーディングの設定
プログラム全体で同じエンコーディングを使用する場合は、mb_internal_encoding関数で内部エンコーディングを設定しておくと便利です。これにより、毎回エンコーディングを指定する手間を省くことができます。
<?php
// スクリプトの冒頭で内部エンコーディングを設定
mb_internal_encoding("UTF-8");
// エンコーディングパラメータを省略可能に
$position = mb_strpos($text, $search);
?>大文字小文字を区別しない検索
マルチバイト文字列で大文字小文字を区別しない検索を行いたい場合は、mb_stripos関数を使用します。これはstrposとstriposの関係と同様です。
<?php
$text = "Hello World こんにちは";
$position = mb_stripos($text, "hello", 0, "UTF-8");
if ($position !== false) {
echo "大文字小文字を区別せずに見つかりました。";
}
?>| 関数名 | 特徴 | 使用場面 |
|---|---|---|
| mb_strpos | マルチバイト対応、大文字小文字を区別 | 日本語などのマルチバイト文字列の正確な検索 |
| mb_stripos | マルチバイト対応、大文字小文字を区別しない | 英数字を含むマルチバイト文字列の柔軟な検索 |
| strpos | シングルバイト専用、大文字小文字を区別 | 英数字のみの文字列検索 |
これらのポイントを押さえることで、日本語をはじめとするマルチバイト文字列を安全かつ正確に扱うことができます。特にUTF-8環境での開発が主流となっている現在、mb_strpos関数の適切な使用は必須のスキルといえるでしょう。
“`html
strpos以外の文字列検索方法

PHPには文字列検索を行うための関数がstrpos以外にも複数用意されています。検索目的や条件によって最適な関数を使い分けることで、より効率的で可読性の高いコードを書くことができます。ここでは、strposの代替となる主要な文字列検索関数について、それぞれの特徴と使い方を詳しく解説します。
strstr関数による検索方法
strstr関数は、文字列内で指定した文字列を検索し、見つかった位置から文字列の最後までを返す関数です。strposが位置を数値で返すのに対し、strstr関数は文字列そのものを返すという点で異なります。文字列の存在確認だけでなく、検索語以降の部分を取得したい場合に特に有効です。
strstr関数の基本仕様
strstr関数の構文は以下の通りです。
strstr(string $haystack, string $needle, bool $before_needle = false): string|false第1引数には検索対象の文字列、第2引数には検索する文字列を指定します。第3引数はオプションで、trueを指定すると検索文字列より前の部分を返します。文字列が見つからなかった場合はfalseを返すため、厳密な比較(===)を使った判定が推奨されます。
- haystack: 検索対象となる文字列
- needle: 検索したい文字列
- before_needle: trueの場合、検索文字列より前の部分を返す
- 戻り値: 検索文字列以降の部分文字列、または検索文字列より前の部分文字列(before_needleがtrueの場合)。見つからない場合はfalse
strstr関数の使用例
実際の使用例を見てみましょう。
<?php
$email = "user@example.com";
// @以降を取得
$domain = strstr($email, '@');
echo $domain; // 出力: @example.com
// @より前を取得(ユーザー名の取得)
$username = strstr($email, '@', true);
echo $username; // 出力: user
// 存在確認
$text = "PHPプログラミング入門";
if (strstr($text, 'PHP') !== false) {
echo "PHPという文字列が見つかりました";
}
// 見つからない場合
$result = strstr($text, 'Python');
var_dump($result); // 出力: bool(false)
?>strstr関数は、特にメールアドレスのドメイン部分やユーザー名部分を抽出するような、検索文字列を基準に文字列を分割したい場合に非常に便利です。単に位置情報だけが必要な場合はstrposの方が適していますが、部分文字列の取得まで行いたい場合はstrstrが効率的です。
preg_match関数を使った正規表現検索
より複雑なパターンマッチングが必要な場合には、正規表現を使用するpreg_match関数が最適です。単純な文字列の一致だけでなく、パターンに基づいた柔軟な検索が可能になります。メールアドレスの形式チェックや、特定のパターンに合致する文字列の抽出など、高度な文字列処理に対応できます。
preg_match関数の基本構文
preg_match関数の構文は以下のようになります。
preg_match(string $pattern, string $subject, array &$matches = null, int $flags = 0, int $offset = 0): int|false第1引数には正規表現パターンを、第2引数には検索対象の文字列を指定します。第3引数には一致した結果が格納される配列を指定でき、マッチした文字列を取得することができます。戻り値は一致した回数(0または1)を返し、エラー時にはfalseを返します。
- pattern: 検索パターンを表す正規表現(デリミタで囲む必要がある)
- subject: 検索対象となる文字列
- matches: マッチした結果を格納する配列(オプション)
- flags: 検索オプションのフラグ(オプション)
- offset: 検索開始位置(オプション)
preg_match関数のサンプルコード
様々な検索パターンでの使用例を紹介します。
<?php
// 基本的な文字列検索
$text = "PHPは人気のあるプログラミング言語です";
if (preg_match('/PHP/', $text)) {
echo "PHPが見つかりました\n";
}
// メールアドレスの形式チェック
$email = "test@example.com";
if (preg_match('/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/', $email)) {
echo "有効なメールアドレスです\n";
}
// 数字のみの文字列チェック
$number = "12345";
if (preg_match('/^\d+$/', $number)) {
echo "数字のみの文字列です\n";
}
// マッチした文字列を取得
$url = "https://example.com/page";
if (preg_match('/https?:\/\/([^\/]+)/', $url, $matches)) {
echo "ドメイン: " . $matches[1]; // 出力: example.com
}
// 大文字小文字を区別しない検索
$text = "php programming";
if (preg_match('/PHP/i', $text)) {
echo "PHPが見つかりました(大文字小文字を区別しない)\n";
}
// 複数のパターンから選択
$text = "私はPythonとPHPが好きです";
if (preg_match('/(PHP|Python|Ruby)/', $text, $matches)) {
echo "見つかった言語: " . $matches[1] . "\n";
}
?>preg_match関数は、strposやstrstrでは実現できない柔軟なパターンマッチングが可能です。ただし、正規表現の処理は単純な文字列検索よりも処理負荷が高いため、単純な文字列の存在確認だけであれば他の関数の使用を検討すべきです。バリデーションや複雑な条件での検索が必要な場合に、その真価を発揮します。
str_contains関数での文字列判定(PHP8以降)
PHP 8.0で新たに追加されたstr_contains関数は、文字列に特定の文字列が含まれているかを判定するための専用関数です。従来はstrposを使って位置を取得し、それをfalseと厳密比較する必要がありましたが、str_contains関数を使うことでより直感的で可読性の高いコードが書けるようになりました。
str_contains関数とは
str_contains関数は、指定した文字列が検索対象の文字列内に含まれているかをbool値で返すシンプルな関数です。構文は以下の通りです。
str_contains(string $haystack, string $needle): bool第1引数に検索対象の文字列、第2引数に検索したい文字列を指定します。戻り値は含まれている場合はtrue、含まれていない場合はfalseというシンプルな仕様です。位置情報を取得する必要がなく、単に含まれているかどうかだけを判定したい場合に最適な関数です。
- haystack: 検索対象となる文字列
- needle: 検索したい文字列(空文字列の場合は常にtrueを返す)
- 戻り値: 文字列が含まれている場合はtrue、含まれていない場合はfalse
str_contains関数の使い方
実際の使用例を見てみましょう。
<?php
// 基本的な使い方
$text = "PHPは強力なプログラミング言語です";
if (str_contains($text, 'PHP')) {
echo "PHPという文字列が含まれています\n";
}
if (!str_contains($text, 'Python')) {
echo "Pythonという文字列は含まれていません\n";
}
// 複数の検索条件
$url = "https://example.com/blog/php-tutorial";
if (str_contains($url, 'https://')) {
echo "HTTPSプロトコルです\n";
}
if (str_contains($url, 'php') || str_contains($url, 'tutorial')) {
echo "PHPまたはtutorialが含まれています\n";
}
// 空文字列の扱い
if (str_contains($text, '')) {
echo "空文字列は常にtrueを返します\n";
}
// 大文字小文字は区別される
$word = "PHP";
if (str_contains("php programming", $word)) {
echo "見つかりました\n";
} else {
echo "大文字小文字が異なるため見つかりません\n";
}
?>str_contains関数は大文字小文字を区別する点に注意が必要です。大文字小文字を区別せずに検索したい場合は、両方の文字列をstrtolower関数などで小文字に変換してから比較するか、strstriposなどの別の関数を使用する必要があります。
従来の方法との比較
str_contains関数の登場により、文字列の存在確認がどれだけ簡潔になったかを比較してみましょう。
| 方法 | コード例 | 特徴 |
|---|---|---|
| strpos(従来) | strpos($text, 'PHP') !== false | 厳密比較(!==)が必要。falseと0の混同を避けるため注意が必要 |
| strstr(従来) | strstr($text, 'PHP') !== false | 文字列を返すため、存在確認には不要なオーバーヘッドがある |
| preg_match(従来) | preg_match('/PHP/', $text) | 正規表現エンジンを使うため処理が重い。単純な検索には不向き |
| str_contains(PHP8以降) | str_contains($text, 'PHP') | 直感的で可読性が高い。bool値を返すため条件式に最適 |
<?php
$text = "PHPプログラミング入門";
// 従来の方法(strpos)
if (strpos($text, 'PHP') !== false) {
echo "見つかりました(strpos)\n";
}
// 従来の方法(strstr)
if (strstr($text, 'PHP') !== false) {
echo "見つかりました(strstr)\n";
}
// 新しい方法(str_contains) - PHP 8.0以降
if (str_contains($text, 'PHP')) {
echo "見つかりました(str_contains)\n";
}
// 否定の場合の比較
// 従来の方法
if (strpos($text, 'Python') === false) {
echo "見つかりませんでした(strpos)\n";
}
// 新しい方法
if (!str_contains($text, 'Python')) {
echo "見つかりませんでした(str_contains)\n";
}
?>PHP 8.0以降を使用できる環境であれば、単純な文字列の存在確認にはstr_contains関数の使用が強く推奨されます。コードの意図が明確になり、バグの混入リスクも減らすことができます。ただし、文字列内の位置情報が必要な場合や、マルチバイト文字列を扱う場合は、それぞれstrposやmb_strposなどの適切な関数を使い分ける必要があります。
“`
配列内の文字列をstrposで検索する方法

配列に格納された複数の文字列に対して特定の文字列が含まれているかをstrposで検索したい場面は、実務でよく発生します。例えば、複数のメールアドレスから特定のドメインを含むものを抽出したり、URLのリストから特定のパスを持つものを探したりする場合などです。strpos関数は単一の文字列に対してのみ動作するため、配列内の各要素に対して繰り返し処理を行う必要があります。
基本的なアプローチは、foreachループやarray_filter関数を使って配列の各要素に対してstrposを実行する方法です。以下に具体的な実装例を紹介します。
foreachループを使った検索方法
最もシンプルで理解しやすいのは、foreachループを使って配列の各要素を順番にチェックする方法です。
<?php
$urls = [
'https://example.com/blog/article1',
'https://example.com/news/update',
'https://sample.jp/blog/post1',
'https://test.com/about'
];
$search = 'blog';
$results = [];
foreach ($urls as $url) {
if (strpos($url, $search) !== false) {
$results[] = $url;
}
}
print_r($results);
// 出力: 'blog'を含むURLのみが抽出される
?>このコードでは、配列内の各URLに対してstrposで’blog’という文字列を検索し、見つかった場合は結果配列に追加しています。必ず !== false で判定することが重要で、これにより文字列の先頭(位置0)で見つかった場合も正しく判定できます。
array_filter関数を使った効率的な検索
より関数型プログラミング的なアプローチとして、array_filter関数とコールバック関数を組み合わせる方法があります。
<?php
$keywords = ['PHP', 'JavaScript', 'Python', 'Ruby'];
$search = 'Py';
$filtered = array_filter($keywords, function($keyword) use ($search) {
return strpos($keyword, $search) !== false;
});
print_r($filtered);
// 出力: Array ( [2] => Python )
?>array_filter関数を使うことで、コードがより簡潔になり、元の配列を変更せずに新しいフィルタリングされた配列を取得できます。use構文を使って検索文字列をコールバック関数内で利用できるようにしている点がポイントです。
複数の検索条件に対応する方法
実務では、複数の検索キーワードのいずれかが含まれているかをチェックしたい場合もあります。このような場合は、ネストしたループを使用します。
<?php
$texts = [
'PHPは人気のサーバーサイド言語です',
'JavaScriptはフロントエンド開発に使われます',
'Pythonはデータ分析に適しています',
'Rubyはシンプルな記法が特徴です'
];
$searchWords = ['PHP', 'Python'];
$matched = [];
foreach ($texts as $text) {
foreach ($searchWords as $word) {
if (strpos($text, $word) !== false) {
$matched[] = $text;
break; // 1つ見つかれば次の文章へ
}
}
}
print_r($matched);
// 出力: PHPまたはPythonを含む文章が抽出される
?>このコードでは、内側のループで複数の検索キーワードをチェックし、いずれか1つでも見つかればbreak文で内側のループを抜けて次の要素に進みます。これにより、同じ文章が重複して結果に追加されることを防いでいます。
検索結果の位置情報も取得する方法
strposの戻り値である位置情報も保存したい場合は、連想配列を使って結果を格納します。
<?php
$messages = [
'エラー: ファイルが見つかりません',
'処理が正常に完了しました',
'エラー: 接続がタイムアウトしました'
];
$search = 'エラー';
$results = [];
foreach ($messages as $index => $message) {
$position = strpos($message, $search);
if ($position !== false) {
$results[] = [
'index' => $index,
'message' => $message,
'position' => $position
];
}
}
print_r($results);
// 各エラーメッセージと、その中での'エラー'の位置が取得できる
?>この方法を使えば、どの配列要素の何文字目に検索文字列が見つかったかという詳細な情報を保持できます。ログ解析やエラー検出などの用途で特に有用です。
大文字小文字を区別しない検索
配列内の文字列を検索する際、大文字小文字を区別したくない場合はstripos関数を使用します。
<?php
$usernames = ['AdminUser', 'testuser', 'GUEST', 'moderator'];
$search = 'user';
$found = array_filter($usernames, function($username) use ($search) {
return stripos($username, $search) !== false;
});
print_r($found);
// 出力: Array ( [0] => AdminUser [1] => testuser )
?>stripos関数はstrposの大文字小文字を区別しないバージョンで、ユーザー入力の検索など、柔軟なマッチングが必要な場面で活用できます。配列の検索においても、状況に応じてstrposとstriposを使い分けることが重要です。
PHP8以降における文字列検索の新しいアプローチ

PHP8では文字列検索に関する新しい関数が導入され、従来の方法よりも直感的でバグの起きにくいコードが書けるようになりました。strposやstrstrといった古くから使われてきた関数には、使い方によっては予期しない動作を引き起こす問題があったため、PHP8以降では新しい関数の利用が推奨されています。ここでは、モダンなPHP開発における文字列検索のベストプラクティスについて解説します。
str_contains関数を推奨する理由
PHP8で導入されたstr_contains関数は、文字列の包含判定において最も推奨される方法です。この関数が推奨される理由は、コードの意図が明確で可読性が高く、型判定のミスが起こりにくいという点にあります。
従来のstrpos関数では、戻り値が数値の0とbooleanのfalseの両方を返す可能性があるため、厳密な比較演算子(===)を使わなければバグの温床となっていました。例えば、検索文字列が先頭にある場合、strposは0を返しますが、if文で単純に判定すると0がfalseと評価されてしまい、誤った処理が実行される危険性があります。
// 従来のstrposを使った場合(バグの危険性あり)
if (strpos($text, '検索語') !== false) {
// 処理
}
// str_containsを使った場合(シンプルで安全)
if (str_contains($text, '検索語')) {
// 処理
}str_contains関数は、文字列が含まれている場合はtrue、含まれていない場合はfalseという明確なboolean値を返すため、比較演算子を使わずに直接条件式に使用できます。これにより、コードがシンプルになり、レビューやメンテナンスも容易になります。
また、関数名そのものが「含む(contains)」という動作を表現しているため、他の開発者がコードを読んだときに何をしているのかが一目で理解できます。このような意味的な明確さは、チーム開発において特に重要です。
strposを使うべきでないケース
PHP8以降の環境では、単純な文字列の包含判定のためにstrposを使うべきではありません。strposは文字列の位置を取得する関数として設計されているため、位置情報が不要な場合には不適切な選択となります。
strposを避けるべき具体的なケースは以下の通りです:
- 文字列が含まれているかの単純な判定:位置情報が不要な場合は
str_containsを使用すべきです。strposを使うと不要な数値情報を処理することになり、さらに厳密な型比較(!== false)を忘れるとバグが発生します。 - コードの可読性を重視する場合:strposと厳密比較演算子の組み合わせは、PHPに詳しくない開発者にとって理解しづらいコードになります。
str_containsであれば誰が見ても直感的に理解できます。 - 複数の文字列検索を行う場合:複数の条件でstrposを使うと、比較演算子の記述ミスが起こりやすくなります。
str_containsなら一貫してシンプルな記述が可能です。
// 悪い例:strposを包含判定に使用
if (strpos($email, '@') !== false && strpos($email, '.') !== false) {
// メールアドレスの簡易チェック
}
// 良い例:str_containsを使用
if (str_contains($email, '@') && str_contains($email, '.')) {
// メールアドレスの簡易チェック
}ただし、文字列が最初に出現する位置を知る必要がある場合は、依然としてstrposを使用するのが適切です。位置情報が必要な処理では、strposやmb_strposを引き続き使用してください。
strstrを使うべきでないケース
strstr関数も、PHP8以降では限定的な用途でのみ使用すべきです。この関数は検索文字列以降(または以前)の部分文字列を返すため、単純な包含判定には過剰な機能であり、パフォーマンスとメモリの無駄になります。
strstrを避けるべきケースは以下の通りです:
- 文字列が含まれているかだけを知りたい場合:strstrは部分文字列を生成して返すため、その結果を使わない場合は無駄な処理とメモリ消費が発生します。
str_containsなら単純なboolean判定のみで済みます。 - 大きな文字列を扱う場合:strstrは検索位置以降の文字列全体をコピーするため、大きなテキストデータを扱う際にはメモリ使用量が増大します。包含判定だけなら
str_containsの方が効率的です。 - 複数回の検索を行う場合:ループ内で何度も文字列検索を行う場合、strstrによる部分文字列の生成は累積的なパフォーマンス低下を引き起こします。
// 悪い例:strstrを包含判定に使用
if (strstr($url, 'https://')) {
// HTTPSのURLである
}
// 良い例:str_containsを使用
if (str_contains($url, 'https://')) {
// HTTPSのURLである
}一方で、検索文字列以降の部分を実際に取得して使用する場合は、strstrが適切です。例えば、メールアドレスからドメイン部分を抽出するような処理では、strstrの特性を活かすことができます。
| 目的 | PHP8以降の推奨関数 | 非推奨な方法 |
|---|---|---|
| 文字列の包含判定 | str_contains | strpos、strstr |
| 文字列の位置取得 | strpos(マルチバイトはmb_strpos) | – |
| 部分文字列の抽出 | strstrまたはsubstr | – |
PHP8以降の開発では、各関数の本来の目的に沿った使い方を心がけることで、より安全で保守性の高いコードを実現できます。
文字列検索における用途別の使い分け

PHPで文字列検索を行う際には、目的に応じて適切な関数を選択することが重要です。strposをはじめとする各種関数は、それぞれ異なる特性を持っており、用途によって使い分けることでコードの可読性とパフォーマンスを向上させることができます。ここでは、実際の開発現場で遭遇する代表的なケースごとに、最適な関数の選択方法を解説します。
位置情報が必要な場合
文字列内で特定の文字や部分文字列がどの位置にあるのかを知りたい場合は、strpos関数またはmb_strpos関数が最適です。これらの関数は検索対象が見つかった位置を整数値で返すため、その位置情報を使って文字列の切り出しや加工を行うことができます。
<?php
$text = "PHPプログラミング";
$position = mb_strpos($text, "プログラミング");
if ($position !== false) {
echo "「プログラミング」は{$position}文字目から始まります";
// 位置情報を使って前後の文字列を分割
$before = mb_substr($text, 0, $position);
$after = mb_substr($text, $position);
}
?>このように、位置情報を取得することで文字列操作の幅が大きく広がります。例えば、URLからドメイン部分だけを抽出したい場合や、ログファイルの特定の区切り文字以降のデータを処理したい場合などに有効です。マルチバイト文字を扱う場合は必ずmb_strposを使用し、文字数のカウントを正確に行いましょう。
含まれるかどうかだけを判定したい場合
特定の文字列が含まれているかどうかだけを判定したい場合、PHP8以降ではstr_contains関数の使用が推奨されます。この関数はtrueまたはfalseを返すため、型判定の問題を気にする必要がなく、コードの意図が明確になります。
<?php
// PHP8以降
$email = "user@example.com";
if (str_contains($email, "@")) {
echo "有効なメールアドレスの可能性があります";
}
// PHP7以前の環境
if (strpos($email, "@") !== false) {
echo "有効なメールアドレスの可能性があります";
}
?>str_contains関数を使用することで、strposで頻繁に発生する「falseと0の判定ミス」を完全に回避できます。特に条件分岐だけが目的の場合、strposの戻り値を厳密比較演算子(!==)で判定する必要がなくなるため、コードがシンプルで読みやすくなります。PHP7以前の環境では引き続きstrposを使用しますが、必ず厳密比較を行うよう注意してください。
- PHP8以降の環境:str_contains関数を第一選択に
- 単純な存在確認:型判定の問題がないため安全
- 可読性の向上:関数名から処理内容が明確
- パフォーマンス:内部的に最適化されている
パターンマッチングが必要な場合
複雑な検索条件や柔軟なパターンマッチングが必要な場合は、preg_match関数による正規表現検索が適切です。単純な文字列検索ではstrposの方が高速ですが、以下のようなケースでは正規表現の使用が不可欠となります。
<?php
$text = "電話番号:03-1234-5678";
// 電話番号のパターンを検索
if (preg_match('/\d{2,4}-\d{2,4}-\d{4}/', $text, $matches)) {
echo "電話番号が見つかりました:" . $matches[0];
}
// メールアドレスの形式をチェック
$email = "test@example.com";
if (preg_match('/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/', $email)) {
echo "有効なメールアドレス形式です";
}
// 複数の候補から検索
if (preg_match('/(error|warning|fatal)/i', $log_message)) {
echo "エラー関連のメッセージが含まれています";
}
?>正規表現を使用すべき具体的なケースは以下の通りです。
| 用途 | 推奨関数 | 理由 |
|---|---|---|
| 数字、アルファベットなどの文字種判定 | preg_match | 柔軟なパターン指定が可能 |
| 繰り返しパターンの検索 | preg_match | 量指定子が使用できる |
| 複数の候補から検索 | preg_match | OR条件を簡潔に記述可能 |
| 大文字小文字を区別しない検索 | preg_match | フラグで簡単に制御可能 |
ただし、単純な固定文字列の検索にpreg_matchを使用するのは避けるべきです。正規表現のパース処理がオーバーヘッドとなり、strposやstr_containsに比べて処理速度が遅くなります。パフォーマンスが重要な場面では、まず単純な文字列検索で済まないか検討し、必要な場合のみ正規表現を使用するという判断基準を持つことが大切です。
“`html
まとめ

本記事では、PHPのstrpos関数について、基本的な使い方から注意点、代替手段まで幅広く解説してきました。最後に、これまでの内容を振り返りながら、実務での適切な使い分けについて整理しましょう。
strpos関数は文字列内の特定の文字列の位置を検索する基本的な関数であり、戻り値として検索した文字列の位置(整数)またはfalseを返します。特に重要なのは、戻り値の判定では必ず厳密等価演算子(===または!==)を使用することです。0とfalseを区別しないと、文字列の先頭で見つかったケースを誤って「見つからなかった」と判定してしまう危険性があります。
マルチバイト文字列を扱う場合は、strposではなくmb_strpos関数を使用する必要があります。日本語を含む文字列を検索する際は、必ず文字エンコーディングを正しく指定して、文字数ベースでの位置取得を行いましょう。
PHP8以降では、文字列検索のためのより直感的な関数が追加されています。単に文字列が含まれているかどうかを判定したいだけの場合は、str_contains関数を使用することが推奨されます。この関数は真偽値を返すため、戻り値の型判定で混乱することがなく、コードの可読性も向上します。一方、検索位置の情報が必要な場合や、PHP7以前の環境で動作させる必要がある場合には、引き続きstrposやmb_strposが有効な選択肢となります。
実務において関数を選択する際のポイントをまとめると、以下のようになります。
- 位置情報が必要な場合:strposまたはmb_strposを使用し、厳密等価演算子で判定する
- 含まれるかどうかの判定のみの場合:PHP8以降ならstr_containsを優先的に使用する
- 複雑なパターンマッチングが必要な場合:preg_match関数による正規表現検索を検討する
- マルチバイト文字列を扱う場合:必ずmb系の関数を使用し、文字エンコーディングを指定する
これらの知識を適切に活用することで、より安全で効率的な文字列検索処理を実装できます。strpos関数は基本的でありながら奥深い機能を持つため、その特性を理解した上で、状況に応じた最適な関数選択を心がけることが重要です。
“`

