自動型変換の罠
PHP で, 改行区切りの数値を処理しようとして, めっちゃはまったのでメモ.
下記のようなテキストファイルを読み込み, 最小値から最大値までをループといった処理をする場合,
test.txt
1 3 2 0
こんな感じになると思います.
<?php $contents = file('./test.txt'); sort($contents, SORT_NUMERIC); $min = min($contents); $max = max($contents); for ($i = $min; $i < $max; $i++) { // some processing... } ?>
このように, テキストファイルを読み込み, 配列に代入した段階では, まだ改行コードが残っています.
しかし, PHP の賢い(?)自動型変換機能は, 改行コードが含まれていようと, 数値とみなしてソートまでしてくれます.
<?php $contents = file('./test.txt'); sort($contents, SORT_NUMERIC); var_dump($contents); array(4) { [0]=> string(2) "0 " [1]=> string(2) "1 " [2]=> string(2) "2 " [3]=> string(2) "3 " } ?>
もちろん, 改行コードが含まれていようが, 最小値, 最大値も求めてくれます.
<?php $min = min($contents); $max = max($contents); var_dump($min); var_dump($max); string(2) "0 " string(2) "3 " ?>
比較演算子も完璧です.
<?php var_dump($min < $max); bool(true) ?>
しかし, 大きな罠が...
<?php for ($i = $min; $i < $max; $i++) { // some processing... } ?>
上記のように, for でループさせようとした場合, $i < $max で, ループの条件を評価するまでは良いんです.
<?php $min = min($contents); var_dump($min); string(2) "0 " $min++; var_dump($min); string(2) "0 " ?>
このように, 改行コードが含まれている場合, インクリメント演算子(++)で, インクリメントできません...
結果, 冒頭のプログラムは無限ループに陥ります(失笑)
ちなみに, 下記のように int にキャストするか trim してやれば問題ないです.
<?php $min = (int) min($contents); $min++; var_dump($min); int(1) ?>
<?php $min = trim(min($contents)); $min++; var_dump($min); int(1) ?>