phpでファイルへの書き込み方法について。


WEBフォームからGETで送信したワードを、
ファイルへ保存したいと思っています。

ヤフーを例にすると、
ヤフーの検索で検索したワードを
全てファイルへ保存していきたい、というイメージです。

GETの場合、URLに直接打ち込んでも検索できますが、
フォームにワードを入れて送信したときのみ
ファイルへ保存したいと思っています。

さらに、送信後の結果画面にもフォームをおき、
そこからもワードを送信できるようにしたいです。


簡単にコードを書いてみましたが、
何故か同じワードが複数個ずつ書き込みされて困っています。

うまい方法があれば、アドバイスお願いします。

■今試してみたコード
(フォーム送信時にhiddenでfrom_formに1を入れています)

switch ($query) {
case '':
break;
case ($query != ""):
if ($from_form == "1") {
kakikomi($query);
}
break;
default:
break;
}

*関数は別ファイルに書いてあり、インクルードしてます。
function kakikomi($query) {
$word = $query . "\n";
$pointer = fopen( "./hozon_text.php", "a+" );
flock( $pointer, LOCK_EX );
fwrite( $pointer, $word );
flock( $pointer, LOCK_UN );
fclose( $pointer );
}

回答の条件
  • 1人5回まで
  • 登録:2007/06/08 08:56:38
  • 終了:2007/06/12 09:08:36

ベストアンサー

id:tezcello No.1

tezcello回答回数459ベストアンサー獲得回数692007/06/08 13:25:35

ポイント100pt

http://q.hatena.ne.jp/1181172352 がまだ解決していないって事ですね?


特に問題は無さそうに思うのですが。

とりあえずチェック点を。

  • $query には何をどうやって値を入れていますか?
    • 実際には何が入っていますか?
    • switch文に入る直前で、var_dump() で(echo()よりハッキリします)で調べてみたらいいでしょう。
  • 関数にはチャンとクエリの値が伝わっていますか?
    • これもvar_dump()で
  • 書き込む内容は予定通りの内容ですか?
    • 同じくvar_dump()で
  • ファイルのオープンモードを "w+" とした場合も同じ結果ですか?
  • 書き込まれているのだから大丈夫とは思いますが、
    • fopen(), flock(), fwrite() のそれぞれ返る値は問題無いですか?
  • これも大丈夫とは思いますが、関数をインクルードするのは1回だけですか?
  • 関数を呼んでいるのは本当に1ヶ所だけですか?
id:onigirin

どうもありがとうございます。

解決していなかったので、整理して再質問してみました。

$queryには、

$query= $_GET['q'];

としています。

var_dump()したところ、

しっかり文字は正しく入っていました。

string(15) "文字列"

その他のvar_dumpも同じでした。


オープンモードを「w+」「r+」にしてみたところ、

文字列は「一度」だけきちんとファイルに書き込まれました。

そこで「a+」に戻したところ、また3連続で書き込まれてしまいました。

他のチェック項目も見てみましたが、

今のところ特に問題がなさそうでした。

PHP5.1.4みたいですが、

今借りているレンタルサーバーの仕様なんですかねぇ・・・。

ファイルに追記していく形ではなく、

他の方法も検討した方が良さそうですね。

2007/06/08 16:26:02
  • id:kn1967
    興味本位ですが
    >||
    function kakikomi($query) {
    $word = $query . "\n";
    $pointer = fopen( "./hozon_text.php", "a+" );
    fwrite( $pointer, $word );
    fclose( $pointer );
    }
    ||<
    としてみた場合はどうでしょう?

    興味本位はさておき、
    質問を複数に分けてしまうのは効率の良い質問の仕方ではないですよ。
    (penchickさんに今回の質問文と回答文が伝わらないからです)
    それと、
    phpによるファイル操作に関しても、既存のものを参照せずに
    いきなり書いているようなので、まだまだ改良しなければならない点が多すぎだと思います。
    どこまで回答すれば良いかが見えず、回答は控えていたのですが
    あえてコメント欄を汚させていただきますが・・・

    (1)hiddenにしてあってもソースを見れば簡単に見破られるものなので
    GETでの送信であるかぎりはURL欄に直接入力してしまう事を防ぐ事は出来ない。
    だからといってPOSTにすれば完璧という訳ではないが
    よほど欲しい情報でもない限りはGETよりは抑止力としてかなり上です。

    (2)ファイルオープンやファイルロックに失敗した場合を考えてますか?
    オープンやロックに失敗した場合は一呼吸(1秒以下で十分かと)置いてから再チャレンジさせ
    数回(3回程度で十分かと)再チャレンジしてもダメな場合は
    「時間を置いて再度入力してください」といったメッセージを返させる。
    といったような仕組みを組み込んでおいたほうがよろしいかと思いますよ。

    (3)そのサーバー独自の仕様なのか、それとも他でも再現される事項なのかを考えて、サーバー環境(OS、WEBサーバー、PHPの各バージョンあるいはサーバー会社名でも可)の記入は必須と考えておいたほうがよろしいかと思います。

    以上、勝手な事だけ申し上げて消えますが、確認していただければと思います。
  • id:tezcello
    > $query= $_GET['q'];
    > としています。
    POSTの時だけやりたかったのでは?

    > オープンモードを「w+」「r+」にしてみたところ、
    > 文字列は「一度」だけきちんとファイルに書き込まれました。
    > そこで「a+」に戻したところ、また3連続で書き込まれてしまいました。
    ならば、3回書き込まれているのでは?
    flock(), fclose() など関数を上書しているような事は無いでしょうか。
    例えば、アンロックはfclose()の際に実行されるらしい(出典は覚えていませんが)ので、 flock( $pointer, LOCK_UN ); をやめると書き込み回数が変わりませんか?
    また、PHPスクリプトが終了する際に、ファイルは閉じられるのでfclose() もやめてみると書き込み回数が変わりませんか?

    別な手段として、file_get_contents() で全部を読み込み、新規分を追加して書き出すのは簡単ですね。
    同じクエリがあったら書き出すのを止めておくなんて処理もできますし。
  • id:onigirin
    ■kn1967さん

    どうもありがとうございます。
    試してみましたが、やはり2,3度書き込まれました。

    hiddenは、「フォーム経由」のみ保存して、
    それ以外は特に保存しない、という
    簡単なフィルタでいいので実装したかったので、
    hiddenでやってみました。

    ファイル処理はまだ適当です・・・。
    動いてから試そうと思ってました。

    サーバーはXREAです。
    たぶん、自分のプログラムミスな気がします。。。
  • id:onigirin
    ■tezcelloさん

    どうもありがとうございます。

    POSTのときではなくて、
    フォームからGET送信のものだけ保存したいと思ってました。
    ヤフーのように、フォームからGET送信して保存、という流れです。
    (URLに直接入力のGETは特に保存しない、という程度です)

    flock系をいろいろ削除したり試行錯誤してみましたが、
    数度かかれてしまいました。

    最近グーグルにひっかかってしまったのか、
    ファイルに次々とワードが保存されていました。
    (ページ上にクリックするとそのワードで検索できるような形になっているのです)

    それらは「一度」のみ書き込まれていたので、
    正常に動作はしているような気がするので、余計謎です・・・。

    試しにfile_get_contents()にしてみましたが、
    2,3度同じものが書き込まれていました。


    htmlのフォーム記述がおかしいのか、
    自分のPCがおかしいのか、
    この辺りもみなおしてみようと思います。
  • id:tezcello
    > 試しにfile_get_contents()にしてみましたが、
    > 2,3度同じものが書き込まれていました。
    file_get_contents() で変数に読み込んで、必要なものを変数に追加したら、'w'モードでオープンして書き込めばいいのですが、'a'になっていませんか?
    でも、これは結局最後に書かれたものしか保存されていないだけで、重複書き込みの根本対策をした訳ではないです。

    XREA のサーバを利用した経験はありますが、その様な現象に出会ってはいません。なにかプログラム的に問題があるような気がします。

    テスト用に、単純化したファイルの読み書きをやってみませんか?


    回答と重複しますが、
    本当にその関数でしか書き込んでいませんか?
     kakikomi() で、 $word = $query . "\n"; の部分を  $word = $query . "000\n"; とでもして、
     000が書き込まれていない行があればどこか別のところで書き込まれています。
    その関数は1回しか呼ばれていませんか?
     以前のコメントで、fwrite() の付近で echo しても1回しか表示されていないようでしたが、現在もそうなっていますか?
    ひょっとして、送信ボタンをダブルクリックしていませんか?
     XREAってアクセス記録を閲覧できませんでしたっけ?
     連続して同じクエリでアクセスがないかチェックできれば、サーバ側かクライアント側か切り分けが出来ますよね。
     javascript を使っているとしたら、送信時に複数回送信しているなんて事は無いでしょうか
  • id:onigirin
    どうもありがとうございます。

    file_get_contents()のwでも数度書き込まれるので、
    おかしいなぁ、と思っていました。

    関数も000をつけてもしっかり000がついて何度か書き込まれます。

    さらに試行錯誤した結果、
    なんとも情けない理由が判明しました・・・。

    グーグルのアドセンス広告をとりあえず載せてあったのですが、
    それを外してみたところ
    うまく一度だけ書き込まれるようになりました。

    再度載せてみると、2,3度書き込まれました。

    公開していないのにグーグルのクローラーが来てるの
    おかしいなぁと思っていたら、
    これが原因だったのかもしれません。

    ワードを送信した後のgetでのURLに、
    クローラーも1度アクセスするため、
    2度書き込まれていたのではないかと思われます。

    このままではget送信のワードを保存していると、
    グーグル広告がある限り2度書き込まれますね。
    何か別の方法を練ってみます。


    いろいろ悩んだ結果、原因がわかり助かりました。
    テストでは動いていたはずなので混乱しまいたが、
    なんとも情けない原因でした・・・。

    いろいろアドバイス頂けて、
    なんとか原因究明まで粘ることができました。
    本当にどうもありがとうございました!

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

絞り込み :
はてなココの「ともだち」を表示します。
回答リクエストを送信したユーザーはいません