BookmarkLINEPHPで文字列比較を行うには、どのような実装を行っていけばよいでしょうか。今回は、PHPによる文字列比較の基本形を見ていきます。アジェンダ「値を比較する」という極めてベーシックな処理の中に潜む落し穴strcmp()strcasecmp()strncmp()strncasecmp()strnatcmp()strnatcasecmp()「値を比較する」という極めてベーシックな処理の中に潜む落し穴PHPに限らず、プログラミングにおいて「数値を比較する」というのは最もポピュラーで基本的な処理の一つです。「文字列を比較する」とはどういう事でしょうか?「2つの文字列が同じか、そうでないか」が、文字列比較を行う最もあるあるな理由ではあります。その場合、多くの人はこんな感じで比較を行うでしょう。false比較演算子を用いて、その文字列同士が等しいかどうかを調べています。これでも比較は行えます。反面、この場合は、「同じか同じでないか」だけが結果として返ります。比較演算子での比較には一つ落し穴があります。片側が数値の場合の以下では、結果はどうなるでしょう。true実は上記のような場合は、真(true)が返ります。Juggling(タイプジャグリング)、つまり型の相互変換が行われる事で双方の比較が行われますが、さらに比較演算子が「==」の場合は型比較が行われないので、タイプジャグリング後、文字列が数値に変換され、数値としての比較が行われます。結果、左オペランドは数値として有効な「40」のみが比較対象となり、結果として真が返る事となります。今回のテーマは文字列比較の中、敢えて数値を持ち出したのは、文字列同士でなくても、比較対象のどちらか一方でも文字列型の場合、感覚的に比較演算子だけで比較を行っていると、どこかで地雷を踏む可能性がある。そんな中、PHPには、もっと正確に文字列比較を行える関数が用意されています。文字列比較を行う関数の代表格としてstrcmp系の関数があります。これらは全てバイナリセーフで比較を行う事が出来ます。これらは全て、PHP4以降から使用できる枯れに枯れた関数になります。超ベーシック且つレガシー且つレジェンドです。strcmp()strcmp()は文字列比較を行う関数です。)引数に2つの文字列を取り、第一引数に対して第二引数を用いての比較が行われます。結果としては以下の値が返ります。0(ゼロ)詰まるところ、「0」が返れば「等しい」という事になりますが、「大きい」「小さい」というのは、バイト列の差になります。先頭の文字列同士から順に比較が行われ、同一ではなかった時点で処理は終了し、差を返します。「AAAA」と「AABA」を比較した場合、3文字目で差が出るので処理が停止し、その差を返します。-32strcasecmp()strcasecmp()はstrcmp()と同等の機能を持ちますが、唯一違う部分として、こちらは大文字と小文字を区別しません。0strncmp()strncmp()は、指定した○文字目について文字列比較を行います。//1文字目について比較します。strncasecmp()strncasecmp()は、strncmp()と同等の機能を持ちますが、こちらは大文字と小文字を区別しません。//1文字目について比較します。0等しい結果としての「0」が返されている事が確認できます。strnatcmp()strnatcmp()は、自然順アルゴリズムによる文字列比較を行います。「自然順」というのは、数値に関するアルゴリズムですが、例えば、パソコンでフォルダを開いて名前の順に並べ替えた時に、こんな経験をした事もあると思います。filename_1.phpfilename_10.phpfilename_2.phpfilename_3.phpそうです。本当なら1から順番に並んでほしいのに、10が先にきてしまうあれです。自然順アルゴリズムでは、比較対象に数値を含む場合は10進整数部分文字列は数値で比較されます。自然数アルゴリズムを用いた文字列比較です。いう結果を得る事が出来ます。strnatcasecmp()strnatcasecmp()は、strnatcmp()と同じく自然アルゴリズムを用いて文字列比較を行いますが、こちらは大文字と小文字を区別しません。-11つ目は、「a」よりも「A」の方が小さいはずですが、大文字と小文字を区別しないので、マイナスが返っている事が確認できます。10の評価結果が返されている事が確認できます。まとめstrcmp系の関数は、比較する文字列がシングルバイトエンコーディングで符号化されている前提で処理を行うので、日本語など、文字列内の各バイトが必ずしも特定の文字に変換できなくても気にせずに純粋にバイト列を比較します。細かい単位(バイト列)で比較を行う事が出来ます。堅実ながら微妙に知られていないこれらの関数を用いれば、文字列比較もがっちり安定して実装出来ます。イベントレポート2019.12.8MySQL8.0.16で追加されたCHECK制約を試してみる。2019.12.2LaravelのContracts(契約)とは。SESを使ってAPIメール送信を行う(Mailableクラス&SimpleEmailService)2019.12.3MySQL8.0.16で追加されたCHECK制約を試してみる。RitoLaboこのサイトについて利用規約プライバシーポリシ。