【大阪 / 横浜】インフラ / サーバーサイドエンジニア募集中!

【大阪 / 横浜】インフラ / サーバーサイドエンジニア募集中!

【2024年2月~】25年卒 エンジニア新卒採用の募集を開始!

【2024年2月~】25年卒 エンジニア新卒採用の募集を開始!

【導入実績 500社以上】AWS 構築・運用保守・監視サービス

【導入実績 500社以上】AWS 構築・運用保守・監視サービス

【CentOS 後継】AlmaLinux OS サーバー構築・移行サービス

【CentOS 後継】AlmaLinux OS サーバー構築・移行サービス

【WordPress 専用】クラウドサーバー『ウェブスピード』

【WordPress 専用】クラウドサーバー『ウェブスピード』

【格安】Webサイト セキュリティ自動診断「クイックスキャナー」

【格安】Webサイト セキュリティ自動診断「クイックスキャナー」

【低コスト】Wasabi オブジェクトストレージ 構築・運用サービス

【低コスト】Wasabi オブジェクトストレージ 構築・運用サービス

【予約システム開発】EDISONE カスタマイズ開発サービス

【予約システム開発】EDISONE カスタマイズ開発サービス

【100URLの登録が0円】Webサイト監視サービス『Appmill』

【100URLの登録が0円】Webサイト監視サービス『Appmill』

【中国現地企業に対応】中国クラウド / サーバー構築・運用保守

【中国現地企業に対応】中国クラウド / サーバー構築・運用保守

【YouTube】ビヨンド公式チャンネル「びよまるチャンネル」

【YouTube】ビヨンド公式チャンネル「びよまるチャンネル」

[PHP] 指定した文字列/パターンを含むかチェックする際の注意点

PHP

はじめに

WEBチームの日下部です。
よくstrpos()やpreg_match()の返り値がどうなってたか忘れて調べるので忘備録ついでに地味な注意点とともにまとめました。
指定した文字列/パターンを含むかどうかにだけ焦点を当てており、一部機能だけの説明となるため、各関数の詳細はマニュアルを参照してください。

全体的に言えること

値の比較には、理由がない限り ==, != ではなく ===, !== を使いましょう。
特に 0 == FALSE が TRUE になることを意外に感じる場合は、型の比較表を見ることを推奨します。

目次

  • 指定した文字列を含むかチェックする
  • 指定したパターンを含むかチェックする
  • 配列からパターンにマッチする要素を抽出する

指定した文字列を含むかチェックする

strpos() [Manual]

int strpos(string $heystack, mixed $needle)

引数

heystack: 検索対象の文字列。
needle: 探す文字列。文字列型以外の指定も可能ですが...(後述)

返り値

heystackの中で最初にneedleが出現する位置(先頭が0)を返します。
heystackの中にneedleが含まれない場合はFALSEを返すので、

strpos($heystack, $needle) !== FALSE

の値をみることで存在チェックが可能。

注意点1

heystackの先頭にneedleが出現する場合の返り値は0のため

strpos($heystack, $needle) != FALSE

は「文字列が先頭に出現する」ときにFALSEとなってしまいます。必ず型も比較するようにしましょう。

注意点2

マニュアルに

needleが文字列でない場合は、それを整数に変換し、その番号に対応する文字として扱います。

とありますが、これは
「needleが文字列でなければ整数にキャストしてから文字列にキャストする」
ということではありません。(整数にキャストまでは合っています)
needleが文字列でないときは、整数にキャストしたneedleを10進ASCIIコードとみなした場合に対応する文字として扱います。
つまり次の2つは等価ではなく、

strpos('2100', 100)
strpos('2100', (string)(int)100) // needleは文字列の100になる

次の3つは等価です。

strpos('2100', 100)
strpos('2100', chr((int)100))
strpos('2100', 'd')

意図しない結果を避けるため、特別な事情がない限りneedleには文字列を指定したほうがよいでしょう。
chr()についてはこちら
PHP: chr - Manual

注意点3

needleに配列をつっこんでもエラーとなりませんが、これはneedleを複数指定できるわけではなく、ただ配列が整数にキャストされるだけです。

#PHP 7.0時点では配列を整数にキャストすると、空の配列の場合は0に、空でない場合は1になります。


strstr() [Manual]

needleが最初に現れる位置を見つけ、そこから文字列の終わりまでを返す関数です。
needleが見つからない場合はFALSEを返すので、存在チェックに利用できますが、そのためだけにこの関数を使うことは推奨されません。

注意:
もし特定の haystack に needle があるかどうかを調べるだけの場合、より高速でメモリ消費も少ない strpos() を代わりに使用してください。


指定したパターンを含むかチェックする

preg_match() [Manual]

int preg_match(string $pattern, string $subject)

返り値

subject内にpatternにマッチする文字列があれば1を、なければ0を、マッチング処理にエラーが発生した場合はFALSEを返します。存在チェックをする場合は

preg_match($pattern, $subject) === 1

がTRUEかどうかをみれば良いです。

注意点

マッチしなかったのかエラーが発生したのかを区別する必要がある場合は、0 == FALSE がTRUEになることに気を付けましょう。


配列からパターンにマッチする要素を抽出する

ここでは配列

$input = ['first', 'second', 'third', 'fourth', 'fifth'];

から末尾がthで終わる要素を取り出す例を考えます。
これにはpreg_grep()を使うのが簡単です。

preg_grep() [Manual]

array preg_grep(string $pattern, array $input)

返り値

inputの要素のうち、patternにマッチする要素を抽出した配列
例:

preg_grep('/th$/', $input) // ['fourth', 'fifth']

これは

array_filter($input, function($s) { return preg_match('/th$/', $s) === 1; })

と等価です。

注意点

preg_grep()の第三引数に定数PREG_GREP_INVERTを指定すると、パターンにマッチしない要素を取り出します。マッチング処理がエラーとなる場合も取り出します。つまり次の二つは等価です。

preg_grep('/th$/', $input, PREG_GREP_INVERT)	 	 
array_filter($input, function($s) { return preg_match('/th$/', $s) !== 1; })

#「パターンにマッチ"する"要素を取り出す」ことを明示的に指定するための定数は定義されていないため、マッチする要素を取り出す場合は第三引数を省略するか、0を指定します。

この記事がお役に立てば【 いいね 】のご協力をお願いいたします!
2
読み込み中...
2 票, 平均: 1.00 / 12
6,962
X facebook はてなブックマーク pocket
【2024.6.30 CentOS サポート終了】CentOS サーバー移行ソリューション

【2024.6.30 CentOS サポート終了】CentOS サーバー移行ソリューション

【2024年2月~】25年卒 エンジニア新卒採用の募集を開始いたします!

【2024年2月~】25年卒 エンジニア新卒採用の募集を開始いたします!

【大阪 / 横浜】インフラエンジニア・サーバーサイドエンジニア 積極採用中!

【大阪 / 横浜】インフラエンジニア・サーバーサイドエンジニア 積極採用中!

この記事をかいた人

About the author