人力検索はてな
モバイル版を表示しています。PC版はこちら
i-mobile

注釈つけて書き直します。

PHP+textdbで、友人間のイベントへの参加履歴などを管理しています。
textdbへのレコード登録は上手く作れたのですが、レコードの編集や削除(パスワード認証)が作れません。

textdb書式
$no<>$name<>$hostname<>$password<>$date<>$memo<>$flag

例:(一行目は多重判断や$noの生成に使っています)
2<>B<>hogefuga<>08/06/30 00:00:00
2<>B<>hogefuga<>password<>08/06/30 00:00:00<>Bのメモ<>0<>
1<>A<>hogehoge<>password<>08/06/28 00:00:00<>Aのメモ<>0<>

$memoや$flagを編集し、レコードの順番や$noを変更せずに保存するにはどのようにしたら良いのでしょうか。

●質問者: 草加
●カテゴリ:コンピュータ ウェブ制作
✍キーワード:00 28 FLAG name password
○ 状態 :終了
└ 回答数 : 1/1件

▽最新の回答へ

1 ● 牛乳先生(tukihatu)
●100ポイント ベストアンサー

まず、やりたいことと、PHPの命令仕様を整理してみましょう。

書いていないのでわからないですが、おそらくtextdbをfopenのrで開いて読み出し、その後fopenのwで開いて新しいデータ+今までの中身を書き込んでいる、またはa+で開いてポインタ先頭に戻してetc...ということをやっているんだと予想します。

とすると上の状態の場合で、2のレコードを編集するとなると、

textdbを開き読み込み変数に代入し→全文検索して2のレコードがある行を探し→その部分の内容を書き換え→textdbを書き込みモードで開き→新たに上書きする

という処理を行えばいいわけです。

これをソースで簡単に書くとこうなります。

$textdbfile = "txt.dat";
$input["no"] = "2";//例えばフォームで入力したレコード番号が2なら
$textdb_dat = file($textdbfile);//ファイルを配列で読み込む

foreach($textdb_dat as $key => $var){
 $i = sprit("<>",$var);//さらに細かく切る
 if($i[0] == $input["no"]){//入力したNOとレコードの先頭のデータが同じなら
 $textdb_dat[$key] = $input['no'] . "<>" . $input['name'] . "\n";//入れたい項目が続く
 }else{
 $textdb_dat[$key] += "\n"; 
 }
}

//書き換え終わったら
$write_dat = join("",$textdb_dat);
$fp = fopen($textdbfile, "w");
fwrite($fp,$write_dat);
fclose($fp);

とこんな感じになります。テストしていないですけど、流れはこれです。

とすると削除も同じように、

if($i[0] == $input["no"]){//入力したNOとレコードの先頭のデータが同じなら
 $textdb_dat[$key] = $input['no'] . "<>" . $input['name'] . "\n";//入れたい項目が続く
}

この部分を

if($i[0] == $input["no"] && $i[3] == $input["pass"]){//入力したNOとレコードの先頭のデータが同じで、さらにパスワードが同じなら
 $textdb_dat[$key] = "";
}

こうすれば良いですよね^^

ただ、textdbの全文検索や全文書き込みはあんまりお勧めしません。

・textdbが死んだら簡単には復旧できない

・textdbが1mb超えたりしたら多分重いし書き込み大変

なので、textdbは一つにせず、レコード番号のついたテキストで分割するのを進めます。

例えば1.dat、2.dat...

バーミッション問題が少し難しいかもしれませんが、なれるとこちらのほうが楽ですね。

◎質問者からの返答

素晴らしい回答ありがとうございます。

何分PHPをいじり始めたのがつい最近で、関数のノウハウがまだ溜まっておりませんでした。

全文読み込み、対象要素の比較、一致、不一致時の処理…等、一先ず作っては見たのですが

編集したレコード以外が全て消えたりしておりました。

>書いていないのでわからないですが、おそらくtextdbをfopenのrで開いて読み出し、その後fopenのwで開いて新しいデータ+今までの中身を書き込んでいる、またはa+で開いてポインタ先頭に戻してetc...ということをやっているんだと予想します。

ご明察の通りです。学習参考にしたメールフォームのソース等が上記のような処理をしていて、

ファイルポインタの位置やらなんやらに苦労していました。

ファイルの扱いは

・open

・lock

・処理

・close

だと思っていた(理想だとも思っていた)ので、

$write_dat = join("",$textdb_dat);

$fp = fopen($textdbfile, "w");

fwrite($fp,$write_dat);

fclose($fp);

この処理が考えられませんでした。

レコードナンバーの管理ファイル、各種レコード番号のレコードファイル、と分散したほうが

確かに処理も軽くリスクも少ないですね。

とても勉強になりました。

上記を参考に、書いてみたいと思います。ありがとうございました。

関連質問


●質問をもっと探す●



0.人力検索はてなトップ
8.このページを友達に紹介
9.このページの先頭へ
対応機種一覧
お問い合わせ
ヘルプ/お知らせ
ログイン
無料ユーザー登録
はてなトップ