PHPファイルの操作
PHP はファイルの操作を簡単に行える。http://www.php.net/manual/ja/function.fopen.phpを参考にしてほしい。
ファイルの操作を含むほんのちょっと実用的なスクリプト
- ここでは、ほんのちょっと実用的なスクリプトになるようにしたい。作るのはWEBメモ帳とでもいうのか、メモをとるスクリプト。ただそれだけなので大きな期待はしないように(笑)。
- 始める前に、memo.txtという空のテキストファイルを作り、phpスクリプトと同じディレクトリに置いて、パーミッションを666に設定しておく。memo.txtはここでのメモ帳となる。
- 最初に、メモ入力用のHTMLファイルを作る。ファイル名はmemo.htmlが適当か。
<html> <HEAD> <TITLE>メモの入力</TITLE> </HEAD> <body> <form action="memo.php" method="post"> メモ:<input type="TEXT" name="data" size=50 maxlength=50 > <BR> <input type="submit" name="exec" value="入力データをおくる"> <BR> <input type="reset" name="exec" value="やりなおし"> </body> </html>
- 次は、POSTデータを受け取るPHPスクリプトを作る。memo.phpとしておこう。
<? $memodata = $HTTP_POST_VARS["data"]; $fno = fopen("memo.txt", 'a'); fwrite($fno, "$memodata"); fclose($fno); ?>
- とりあえずこれだけ。memo.htmlからメモを書き込むと、どんどんmemo.txtに追加されることがわかる。無理矢理memo.txtをブラウザで開ければ、(サーバーの設定によるが)これでも立派なWebアプリケーションである。(無理があるなあ。。)
- これだけで実用的とはちょっといい難いので、少し改造しよう。
ファイルオープン時のエラー処理
<? $memodata = date("Y/m/d H:i:s"); $memodata.= $HTTP_POST_VARS["data"]; $memodata.="?n"; if (!($fno = fopen("memo.txt", 'a'))) { die; } fwrite($fno, "$memodata"); fclose($fno); ?>
メモを書いた時間がわかるようにデータに時間を加えた。また、
if (!($fno = fopen("memo.txt", 'a'))) { die; }
は、ファイルオープン時のエラー処理。
- たったこれだけだが、ちょっとスクリプトを変えるだけで、いろんなことに応用できる。(うそ)
- 注意(言い訳ともいう):上記のスクリプトは非常に不完全である。たとえば複数のリクエストが一度にきた場合、ファイルオープンのの排他的な処理をしていないため、ファイルが破壊され、「あうと!」となる可能性が高い。また、不正な入力もいっさい素通りする。決してインターネット上に裸でぶら下がっているサーバーで試そうなって思ってはいけない。コンピュータ室のLAN内での使用がお奨めである。
セキュリティを高める(XSS対策)
- さきほど書いたように、インタラクティブなWebページや、PHPを用いたCGIは、不正な入力により思わぬ動作をする危険がある。中でもクロスサイトスクリプティング(XSS)は、HTML入力欄にすこし仕掛けをほどこした文字列を送り込むことで、簡単にそのスクリプト作者の意図しない動作をさせることができる。たとえば、次のようなスクリプトを作って試してみると。
<送信部><form action="test6.php" method="post"> なにか入力して<input type="text" name="moji"> <input type="submit"> </form>
<受信部><? $mae = $HTTP_POST_VARS["moji"]; echo $mae; ?>
一見、ただの文字列を表示させるスクリプトだが、入力欄に、
<hr>
とHTMLのタグを打ち込んでみると。。見事区切り線が引けたはず。このようなスクリプトでは、悪意のあるタグを打ち込まれ、思いもしないサイトに誘導されたり、意図しないスクリプトが実行されたりが、簡単にできてしまう。
- そこで、問題の起こりやすい"<"、">"、"&"などを無効化(サニタイジング)する必要がある。これは、PHPのhtmlspecialchars()関数を使ってみる。以下のスクリプトをtest6.phpとして実行。
<送信部><form action="test6.php" method="post"> なにか入力して<input type="text" name="moji"> <input type="submit"> </form>
<受信部><? $mae = $HTTP_POST_VARS["moji"]; // echo "無効化前の文字列を出力:"; echo $mae; // //htmlspecialchars関数を使った無効化(サニタイジング) $ato = htmlspecialchars("$mae", ENT_QUOTES); // echo "<br>"; echo "無効化後の文字列を出力:"; echo $ato; ?>
おなじようにタグを送り込んでもタグとして認識せずに、出力されるはず。もちろん、これだけですべてのセキュリティ問題が解決されるわけではない。誤解のないように。