ネットワークプログラミング
演習
第12回 Webサーバ上で動作するプログラム2
今日のお題
PHPのプログラム例
おみくじ
アクセスカウンタ
ファイルの扱い
lock
ファイルの所有者・許可と権限
2018.12.19PHP の文法
(の一部)
型はあるが、明示的な宣言はしなくてよい 変数には型がない 変数の宣言はしなくてよい 変数名には $ をつける 仮引数も同じ 関数は function で宣言する オブジェクト指向に対応している: クラスは class で宣言する メソッドも function で宣言する main はなく、トップレベルに書かれた命令列が実行の起点 WEB上にマニュアルが公開されている http://php.net/manual/ja/ 2018.12.19if, for, while の制御の 構文はC言語と似ている
例1:おみくじ
http://sun.ac.jp/prof/yamagu/2018NP/omikuji.php ソースコード: <HTML> <HEAD><TITLE>Fortune</TITLE></HEAD> <BODY> <?PHP $i = rand(1,4); if ($i == 1) { echo '大吉<BR/>' ; } else if ($i == 2) { echo '中吉<BR/>' ; } else if ($i == 3) { echo '吉<BR/>' ; } else { echo '凶<BR/>' ; } ?> </BODY> </HTML> 2018.12.19 1から4までの整数をランダム に生成して、変数$iに代入。 $iの値によって表示する内容 を変える。 このサンプルは、そのうち また使います例2:アクセスカウンタ
http://sun.ac.jp/prof/yamagu/2018NP/tst.php 基本的な考え方: 1. アクセス回数を記録したファイルを用意する 2. ファイルからアクセス回数を読む 3. アクセス回数を1増やす 4. ファイルに(新しい)アクセス回数を書き込む 注意点が二つ… 2018.12.19アクセスカウンタを作る際の注意点
排他制御
複数のアクセスがほぼ同時にあったら、ファイルの 整合性は保たれるか? ➡ ファイルにロックをかける(OSの)機能を使う
ファイルの所有者・許可と権限
PHPのプログラムを実行するのは、Webサーバ: Webサーバに読み書きできるようにファイルを作る必要 がある 2018.12.19ファイルの排他ロック
あるプロセスがファイルにロックをかけると、
ロックが解除されるまで、他のプロセスは
そのファイルへのアクセスを待つ。
…アクセス回数を読む前にロックをかけ、
新しいアクセス回数を書き込んだらロックを解除
2018.12.19ファイルの所有者と権限
UNIX のファイルシステムは、ユーザ全員で共有する
とはいえ、自分のファイルを、他のユーザに自由
に読まれたり書き換えられたりされては困る
各ファイルには、所有者が決まっている
各ユーザはいくつかのグループに所属している
各ファイルには、グループも設定されている
ファイルの所有者は、ファイルについて、
所有者/グループ/それ以外 に対して、それぞれ
読む/書く/実行する の許可を設定できる
2018.12.19 ディレクトリの場合は、ディレクトリの下 にアクセスする許可ファイルの所有者と許可を確認する
ubuntu の場合
シェルで ls -l を実行すると、カレントディレクトリの ファイルについて、所有者や許可モードの情報とともに 一覧が表示されるWinSCP の場合
ファイルの一覧に、パーミッション(許可モード)や所有者 が表示されているはず 2018.12.19許可モードの読み方
ls -l だと、 -rwxr-xr-x WinSCP だと rwxr-xr-x 2018.12.19 permission 最初の1文字はディレクトリか 否かを示す それ以外(other)への許可 同じグループ(group) のユーザへの許可 所有者(user)への許可 r は読む権限がある ことを示す w は書く(書き換え る・削除する)権限 があることを示す x は実行する(ディ レクトリの場合は下 にアクセスする)権 限があることを示す2018.12.19
アクセスカウンタと権限の話
プログラムがファイルを読み書きするときは、
そのプログラムを実行したユーザと同じ権限を持つ
PHPのプログラムを実行しているのは誰?
…Webサーバ
では Webサーバを実行しているのは誰?
実は、Webサーバ用に仮想のユーザを作って、
その仮想ユーザが実行している
大昔は、管理者の権限で動いていた
…セキュリティリスクがある
➡Webサーバ用仮想ユーザが、アクセスカウンタ用
のファイルを読み書きできないといけない。
アクセス回数記録用のファイルを作る
1. アクセスカウンタのプログラムを、ファイルが無ければ 作るという動作にしておく アクセスカウントをするページを作っておく 2. ファイルの置き場所となるディレクトリを作る 3. 置き場ディレクトリの other の権限に w を追加する ディレクトリに w 権限があると、ファイルを作れる 4. アクセスする → ファイルができる できたファイルの所有者は、Webサーバ用仮想ユーザ 5. 置き場ディレクトリの other の権限から w を削除する この手順をやらないと、誰でもファイルを置けるように なってしまう。 2018.12.19アクセスカウンタの設計
ページごとに別のカウンタを用意したい
…回数を記録するファイルだけ変えればよい
(PHPのプログラムは同じものを使う)
アクセスカウンタのプログラムをPHPの関数で書く
関数の引数は、回数を記録するファイルの名前
この関数が定義されたPHPファイルを読み込んで、
関数を呼び出すと、回数が返る
2018.12.19アクセスカウンタのソース
<?PHP function counter($file) { $fh = fopen($file,"c+"); if ($fh === FALSE) return 0; flock($fh,LOCK_EX); $sc = fgets($fh); if ($sc === false) { $c = 0; } else { $c = intval(trim($sc)); } $c = $c+1; ftruncate($fh,0); fwrite($fh, $c . "\n"); flock($fh,LOCK_UN); fclose($fh); return $c; } 2018.12.19 counter という関数を定義 c+ で fopen すると、読み書き できて、無ければ作る fopen に失敗したとき ファイルにロックをかける ファイルから1行読み込む ファイルから読めない(無い)とき、 0回とする 読めたら(改行を削除して) 整数値にする 回数を1増やす ファイルサイズを0にする。 c+で開くと、末尾に追記されるので。 新しいアクセス回数を書く ロックを解除 ファイルを閉じる 新しいアクセス回数を返す ?> で閉じなくてもよいアクセスカウント
するページのソース
<HTML> <HEAD><TITLE>welcome</TITLE></HEAD> <BODY> <H1>ようこそ</H1> <HR/> <?PHP require_once "counter.php"; echo 'あなたは ' . counter("./count/tst.cnt") . '人目の来訪者です。'; ?> </BODY> </HTML> 2018.12.19 counter.php を1度だけ (必要なら)読み込む カレントディレクトリの下の countというディレクトリの下の tst.cnt というファイルに アクセス回数を記録する 関数 counter の呼出しファイルの許可モードの変更
ubuntu の場合
シェルから chmod コマンドを使う chmod 変更 ファイル名またはディレクトリ名 変更は、u(所有者),g(グループ),o(それ以外)に、+か- と r(読み),w(書き),x(実行)で表す 例)count に対して、それ以外のユーザの書き込み権限を削除する:chmod o-w count
(全ユーザへの権限を3桁の八進数で指定する方法もある)