アクセスカウンターを作成していて、fopenとfputsで、ハマったので覚書しておきます。
(タイトルを正確に言うと、不具合ではなくて、仕様の理解不足です。)
まず、fopen関数のモードについて。
r+ は上書き。
w は書き出しです。
この2つのモードでのfputsの挙動を記しておきます。
元のファイルが一行で以下の場合。
1234567890
これにwモードで、「abcde」と書き込むと以下の結果になります。
abcde
1234567890は消え去り、書き込まれたabcdeに置き換わっています。当たり前といえば当たり前です。
次に、同じ「1234567890」にr+モードで「abcde」を書き込んでみます。
元は、
1234567890
r+モードで「abcde」を書きこみします。
abcde67890
すると、結果がおかしなことになっています。というか、これが正常な結果のようです。
どういうことかというと、abcdeを書き込んだのに、元からあった文字の重ならない部分が、そのまま残ってしまっているのです。(赤字部分)
abcde67890
wモードだと、一度、ファイルを空にしてから書き込むので、元の文字列のくずは残りません。
これに対して、r+モードだと、元の文字列の上に上書きするので、元の文字列のくずが残ってしまいます。
これは、r+モードの良さでも有り、悪さでもあります。
例えば、アクセスカウンターを扱う場合に、r+モードだと、内容がゼロになる瞬間は(多分)ないのでファイルが壊れる可能性は低くなります。これが良い点。
しかし、元の文字列と桁数が異なるような場合には、元の文字列のクズが残るので、不具合の原因になります。これが悪い点です。
最後に蛇足です。
file_put_contents関数は、fopenのwモードで動く(と思われる)ので、アクセスカウンターには向きません。wモード同様にファイルがゼロになる瞬間があるのでファイルの内容が消えてしまうことがあります。
アクセスカウンターを作るなら、r+モードで桁数に注意して作成することをお勧めします。
ピンバック: PHPで作るアクセスカウンター【昨日・今日・合計】 | WEBマスターの知恵ブログ