PHP8での数値と文字列の比較 ― PHP7からの変更点と新しい挙動を解説
PHP 8における数値比較の基本的な考え方
PHP 8では、数値と文字列を比較する際の挙動が大きく変更されました。片方が数値でもう片方が数値形式の文字列である場合、両者は数値として比較されます。一方、文字列が数値として扱えない場合は、数値が文字列に変換され、文字列として比較されます。
比較対象となる文字列は、次の3種類に分類できます。
- 数値のみの文字列:数値だけを含む文字列。例:「1234」「1.24e1」など。
- 先頭が数値の文字列(leading-numeric string):先頭が数値で始まり、その後に空白を含む非数値文字が続く文字列。例:「12xyz」など。
- 非数値文字列:数値として解釈できない文字列全般を指します。
PHP 7とPHP 8の比較例
この変更による具体的な違いを見てみましょう。
例:PHP 7
0 == 'foo' // PHP 7 では true を返す
PHP 7では、比較時に文字列「'foo'」が整数 0 に変換されるため、結果は true になりました。これは直感に反する挙動であり、予期せぬバグの原因にもなっていました。
例:PHP 8
0 == 'foo' // PHP 8 では false を返す
一方、PHP 8では非数値文字列との比較において、数値側が文字列へ変換されて文字列比較が行われます。そのため結果は false となり、より直感的で安全な比較が可能になりました。
PHP 8のサンプルプログラム
次のプログラムは、Sanerな文字列と数値の比較(string to number comparisons)を利用した例で、さまざまな形式のキーを持つ配列の挙動を示しています。
<?php
$x = [
"1" => "最初の整数",
"0123" => "先頭に0が付いた整数インデックス",
"12str" => "先頭が数値の文字列を使用",
" 1" => "先頭に空白を使用",
"2.2" => "浮動小数点数を使用",
];
print_r($x);
?>
出力結果
Array
(
[1] => 最初の整数
[0123] => 先頭に0が付いた整数インデックス
[12str] => 先頭が数値の文字列を使用
[ 1] => 先頭に空白を使用
[2.2] => 浮動小数点数を使用
)
まとめ
PHP 8の数値と文字列の比較に関する変更により、「0 == 'foo'」のような従来は true になっていた比較が false になり、意図しない挙動を防ぎやすくなりました。
数値形式の文字列は数値として比較され、非数値文字列とは文字列として比較されるという新しいルールを正しく理解しておくことで、より堅牢で読みやすいコードを書くことができます。PHP 7から移行する際は、比較演算子を使った既存コードの動作確認を行うことをおすすめします。
-
PHPのvfprintf()関数の使い方を徹底解説!書式付き文字列をストリームへ出力する方法
vfprintf()関数とはPHPのvfprintf()関数は、書式を指定した文字列(フォーマット済み文字列)を、ファイルやソケットなど特定の出力先(ストリーム)に書き込むための関数です。処理が成功すると、出力された文字列の長さを戻り値として返します。なお、似た関数として個別の引数を受け取るfprintf()がありますが、vfprintf()は引数を配列としてまとめて渡せる点が特徴です。配列に格納された複数の値を一度に扱いたい場合に便利です。基本構文vfprintf(stream, format, arg)パラメータの詳細stream − 文字列を出力する先(ファイルポインタなど)を指定します
-
PHPのfprintf()関数とは?ストリームへのフォーマット済み文字列の書き込み方法を解説
PHPのfprintf()関数は、指定したストリーム(ファイルなど)にフォーマット済みの文字列を書き込むための関数です。printf()と同じ書式指定が使えますが、出力先をブラウザではなくファイルやストリームにできる点が大きな特徴です。ログの記録やデータファイルの生成などに活用できます。 構文 fprintf(stream, format, argument1, argument2, ...) パラメータ stream − 文字列の書き込み・出力先となるストリーム(通常はfopen()で取得したファイルポインタを指定します) format − 出力する文字列と、変数の埋め込み方(書式)を指定