このサイトはPHPを独習する際に作成したスクリプトを基に、プログラム言語初心者のための入門講座として作成しました。PHPは初心者に親しみやすく、解りやすいプログラム言語です。これからプログラムを学ぶ人の参考になればと思います。
ファイル操作
ファイル操作では、ファイルを開いたり閉じたり、さらに書き込みや削除を行う方法を取り上げます。 見る側が何かを記入し、それをサーバー側に記憶させるシステムです。ファイルを作ったり削除したり、追加で書き込みを行ったり・・・これを発展させたものが掲示板、さらにはブログの基本の仕組みなのです。 このファイル操作アップロードの仕組みや条件分岐、配列などの仕組みを組み合わせた4つのスクリプトを紹介します。 1、1つのファイルに書込みを行う最も基本的なメモ帳 2、書込みと削除だけが行える日記帳 3、画像もつけられる日記帳 4、条件分岐・配列を利用した2択クイズ
13-1 メモ帳
サーバー側にファイルを作り、メモを書くプログラムです。ファイルは1つだけで、毎回上書されます。ファイルは"w+"で開くので、毎回ファイルの内容を削除して、新しく書込みます。 ファイルへの書込みは、ファイルを開く→ロックをかける→ファイルに書く→ロックをはずす→ファイルを閉じる5段階で行われています。
$filepointer=fopen("ファイル名", "w+"); flock($filepointer, LOCK_EX); fputs($filepointer, 内容); flock($filepointer, LOCK_UN); fclose($filepointer);
また、書込みの文字数に制限を設けています。
$length = strlen($data); //文字数を数える if($length < 250){ ・・・ }
以前は日記帳からだったのですが、よりシンプルな形式のものを作成しました。このサンプルでは、ファイルが1つなので、同時に複数の人がアクセスをして書込むと、少しでも後の方が残るはずです。書込み自体はロックをかけるので問題はないと思うのですが、記述が反映されないように見えることがあるかもしれませんね。
⇒こんな感じ
13-2 日記帳
サーバー側にファイルを作り日記帳を書くプログラムです。ひと月を一つのフォルダとして、日ごとに1ファイルを作るという形式で日記を残していきます。 ファイルの読み出しは、ファイル名がdaiary1からdairy31となっているので、while を使い31から順に数を減らして1日までを読み出します。順序としては、31のファイルの存在を確認→読み込み形式でファイルを開く→データを一行づつ順に読み込む→表示させる→ファイルを閉じる→1を引いて一日前を開く、これを繰返し1日まで表示させます。
$count = 31; while($count > 0) { if(file_exists("ファイル名")){ $filepointer=fopen("ファイル名", "r"); while(!feof($filepointer)){ $fileline = fgets($filepointer); echo "内容"; } fclose($filepointer); } $count--; }
日記には年・月・日・曜日・天気・気温・内容と7項目があるのですが、書き込みの時点でこれをそのまま接続してしまうと、読み出しの時に分割することができません。そこでこれらをandと言う文字をはさんで接続します。このandはもちろん何でもかまいませんが、内容の中に偶然andができてしまうと厄介なので、内容には絶対出てこない文字或いは記号を使います。こうしてandで各データを接続することで後に、split関数でこれらを分割し、配列に格納することができます。
内容記述の場合、改行することが予想されますが、データとしては¥nとして記録されます。これではデータを読み込んで表示する際にHTML上では改行になりません。そこで¥nを<br>に変換する必要があります。それがstr_replaceという関数です。 さらにいくつかの関数が登場します。
mkdir ("フォルダ名",パーミッション) フォルダを作ります。 unlink(ファイル名) ファイルを削除する strlen(文字数を数える) 入力文字数を制限するために文字を数えます。 str_replace(文字A,文字B,変数) nを に変換するために使用します。 split(キー,変数) 読み込んだ1行をキーによって分割し配列に入れます。 feof() ファイルの中の文字の終わりをチェックします。
日記なのでパスワード設定をしたいですね。本来ならもっと本格的なパスワードの設定があるのですが、ここではIFを使った簡易パスワードシステムです。クッキーを使いパスワードを記憶させています。そうしないと再読込みのたびにパスワードを要求されます。
$pass_w = $_POST['password_w']; //まずformからのパスを受けますが、 if($pass_w==null){ //もしなければ、 $pass_w=$_COOKIE['password_k']; //クッキーからもらいます } setcookie("password_k", $pass_w, time()+60*60); //クッキーに保存します。
これを作ったのは2005年2月だったと思うのですが、この時は「年」のことを考慮に入れていなかったのです。まぁ、1年たずにサイト更新を止めちゃう可能性もあったし…。年が変わってみると以前のスクリプトではうまく動かなくなるんですね。そこで一部変更を加えました。 「年」の選択は<select>は使用せず、<text>を使っています。ここに任意の西暦を入れることで過去の記述を見ることができます。デフォルトは今の「年」です。
⇒こんな感じ
13-3 写真付き日記帳
日記帳のプログラムと、ファイルアップロードの仕組みを組み合わせると、写真付き日記帳の完成です。これって掲示板に近くなってる?! 写真のファイルをアップする仕組みとそれを読み出す方法は問題ないのですが、読み出す時に文章と写真をセットにする方法が一工夫必要です。ってまぁそんなにたいした事ではありません。ファイルに文章を書きこむ時に写真のファイル名もいっしょに書き込んで、開いた時にはその名前を読み込んで写真を表示すればよいのです。 ファイル削除の時は、先ずはファイルを読み出し、写真ファイル名を読みこんで写真を削除、その後に文書のファイルを削除しています。
if(file_exists("文書ファイル")){ //ファイルの存在を確認 $filepointer=fopen("文書ファイル","読込モード"); //ファイルを開く $fileline = fgets($filepointer); //ファイルを一行読込 $pictshow = split("キー",$fileline); //キーで一行を分割 unlink("写真ファイル"); //写真ファイルを削除 fclose($filepointer); //ファイルを閉じる unlink("文書ファイル"); //文書ファイルを削除 }
13-4 2択クイズ
EXCELの知識問題を作成することになったので、これを簡素化して紹介します。ファイルの使い方が日記帳と違い、1ファイルにすべての問題と解答を書き込みます。ランダムな順に書きこまれた問題から、必要なデータを抜き出す点がこれまでと異なります。 問題は、全部で30問なのですが、10問づつ1レベルとして各10問から毎回ランダムに5問を取り出します。5問中4問以上の正解なら次のレベルに行けます。3問以下なら初めからやり直しです。 このスクリプトは2ファイルの構成です。出題画面とチェック画面です。チェック画面でレベルクリアなら出題画面にのファイルにもどりレベルを上げて次の5問を表示します。form を使ってデータを送りあい2つのファイルを交互に移動しながら進めていくわけです。 ファイルに書きこまれた問題は、1行ごとに配列に入れていき、要素の初めにある問題番号をもとに抽出されるのです。 また、問題作成画面は別のファイルです。問題番号・問題・解答・解説・改行の5つが一つのデータとしてファイルに書きこまれています。この書き込み・削除の画面も見ることができますし、実際に書き込みと削除ができます。すでにEXCELに関するテキトーな問題が記述されていますが、ぜひ書き換えてみてください。 予定通り動くのですが、煩雑なプログラムで、もっと良い方法があるかもしれません。
array_pop($var); 問題は1行で1セットなのですが、最後の改行が空白データを作ってしまうのです。array_pop は配列の最後のデータを削除してくれる関数です。
$quest = array_slice($var, 1, 10) 配列から一部分を取り出す関数です、$var に格納されたデータの内1番から10番までを、新たな配列に格納し、これをシャッフルして表示させます。
sort($quest,SORT_NUMERIC); 配列をソートするのですが、要素でソートする場合そのままだと、1 12 13 2 21 となってしまうので,SORT_NUMERIC を使っています。
srand((float)microtime() * 1000000); 「PHP 4.2.0 以降、 ランダム数生成器にシードを与える必要はありません。これは、この処理が自動的に行われるためです。」とあるので、これは必要ないはずなのですが、なぜかこれがないと2〜3種類の結果しか出ないんですね。不思議です。。
次のスクリプトは問題を5問選び出す部分です。これと同じような記述が何度か出てきます。
if(file_exists("./$updir")){ $filepointer=fopen("./$updir", "r"); //前回と同じファイルを読む記述です while(!feof($filepointer)){ $fileline = fgets($filepointer); //一度すべての行を順に読みこむ $quest[] = $fileline; //読みこんだ各行を配列に格納 } fclose($filepointer); }
array_pop($quest); //最後の改行が空白の配列になるので削除 sort($quest,SORT_NUMERIC); //要素でソートする(要素の初めは問題番号になっている)
$start = $level*10-10; //レベル番号から開始番号を調べる $quest = array_slice($quest, $start, 10); //開始番号から10問を取り出す
srand((float)microtime() * 1000000); //乱数を初期化 shuffle($quest); //取り出した10問をシャッフル //後は初めの5問を表示させるだけです。
|