ネットワークプログラミング 演習 第 12 回 Web サーバ上で動作するプログラム 2
今日のお題 PHPのプログラム例 おみくじ アクセスカウンタ ファイルの扱い lock ファイルの所有者 許可と権限
PHP の文法 ( の一部 ) if, for, while の制御の構文は C 言語と似ている 型はあるが 明示的な宣言はしなくてよい 変数には型がない 変数の宣言はしなくてよい 変数名には $ をつける 仮引数も同じ 関数は function で宣言する オブジェクト指向に対応している : クラスは class で宣言する メソッドも function で宣言する main はなく トップレベルに書かれた命令列が実行の起点 WEB 上にマニュアルが公開されている http://php.net/manual/ja/
例 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> 1 から 4 までの整数をランダムに生成して 変数 $i に代入 $i の値によって表示する内容を変える このサンプルは そのうちまた使います </HTML>
例 2: アクセスカウンタ http://sun.ac.jp/prof/yamagu/2018np/tst.php 基本的な考え方 : 1. アクセス回数を記録したファイルを用意する 2. ファイルからアクセス回数を読む 3. アクセス回数を1 増やす 4. ファイルに ( 新しい ) アクセス回数を書き込む 注意点が二つ
アクセスカウンタを作る際の注意点 排他制御 複数のアクセスがほぼ同時にあったら ファイルの整合性は保たれるか? ファイルにロックをかける (OS の ) 機能を使う ファイルの所有者 許可と権限 PHP のプログラムを実行するのは Web サーバ : Web サーバに読み書きできるようにファイルを作る必要がある
ファイルの排他ロック あるプロセスがファイルにロックをかけると ロックが解除されるまで 他のプロセスはそのファイルへのアクセスを待つ アクセス回数を読む前にロックをかけ 新しいアクセス回数を書き込んだらロックを解除
ファイルの所有者と権限 UNIX のファイルシステムは ユーザ全員で共有する とはいえ 自分のファイルを 他のユーザに自由に読まれたり書き換えられたりされては困る 各ファイルには 所有者が決まっている 各ユーザはいくつかのグループに所属している 各ファイルには グループも設定されている ファイルの所有者は ファイルについて 所有者 / グループ / それ以外に対して それぞれ読む / 書く / 実行するの許可を設定できる ディレクトリの場合は ディレクトリの下にアクセスする許可
ファイルの所有者と許可を確認する ubuntu の場合 シェルで ls -l を実行すると カレントディレクトリのファイルについて 所有者や許可モードの情報とともに一覧が表示される WinSCP の場合 ファイルの一覧に パーミッション ( 許可モード ) や所有者が表示されているはず
permission 許可モードの読み方 ls -l だと -rwxr-xr-x WinSCP だと rwxr-xr-x それ以外 (other) への許可 最初の 1 文字はディレクトリか否かを示す r は読む権限があることを示す w は書く ( 書き換える 削除する ) 権限があることを示す 所有者 (user) への許可 同じグループ (group) のユーザへの許可 x は実行する ( ディレクトリの場合は下にアクセスする ) 権限があることを示す
アクセスカウンタと権限の話 プログラムがファイルを読み書きするときは そのプログラムを実行したユーザと同じ権限を持つ PHP のプログラムを実行しているのは誰? Web サーバ では Web サーバを実行しているのは誰? 実は Web サーバ用に仮想のユーザを作って その仮想ユーザが実行している 大昔は 管理者の権限で動いていた セキュリティリスクがある Webサーバ用仮想ユーザが アクセスカウンタ用のファイルを読み書きできないといけない
アクセス回数記録用のファイルを作る 1. アクセスカウンタのプログラムを ファイルが無ければ作るという動作にしておく アクセスカウントをするページを作っておく 2. ファイルの置き場所となるディレクトリを作る 3. 置き場ディレクトリの other の権限に w を追加する ディレクトリに w 権限があると ファイルを作れる 4. アクセスする ファイルができる できたファイルの所有者は Web サーバ用仮想ユーザ 5. 置き場ディレクトリの other の権限から w を削除する この手順をやらないと 誰でもファイルを置けるようになってしまう
アクセスカウンタの設計 ページごとに別のカウンタを用意したい 回数を記録するファイルだけ変えればよい (PHP のプログラムは同じものを使う ) アクセスカウンタのプログラムを PHP の関数で書く 関数の引数は 回数を記録するファイルの名前 この関数が定義された PHP ファイルを読み込んで 関数を呼び出すと 回数が返る
アクセスカウンタのソース <?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; counter という関数を定義 c+ で fopen すると 読み書きできて 無ければ作る fopen に失敗したとき ファイルにロックをかける ファイルから 1 行読み込む ファイルから読めない ( 無い ) とき 0 回とする 読めたら ( 改行を削除して ) 整数値にする 回数を 1 増やす ロックを解除 ファイルを閉じる 新しいアクセス回数を返す?> で閉じなくてもよい ファイルサイズを 0 にする c+ で開くと 末尾に追記されるので 新しいアクセス回数を書く
アクセスカウントするページのソース <HTML> <HEAD><TITLE>welcome</TITLE></HEAD> <BODY> <H1> ようこそ </H1> <HR/> <?PHP?> </BODY> </HTML> require_once "counter.php"; echo ' あなたは '. counter("./count/tst.cnt"). ' 人目の来訪者です '; 関数 counter の呼出し counter.php を 1 度だけ ( 必要なら ) 読み込む カレントディレクトリの下の count というディレクトリの下の tst.cnt というファイルにアクセス回数を記録する
ファイルの許可モードの変更 ubuntu の場合 シェルから chmod コマンドを使う chmod 変更ファイル名またはディレクトリ名 変更は u( 所有者 ),g( グループ ),o( それ以外 ) に + か - と r( 読み ),w( 書き ),x( 実行 ) で表す 例 )count に対して それ以外のユーザの書き込み権限を削除する : chmod o-w count ( 全ユーザへの権限を 3 桁の八進数で指定する方法もある ) WinSCP の場合 Web サーバで作業します ssh campus.sun.ac.jp で Web サーバにログインしてください ファイルやディレクトリを選んで プロパティをクリック パーミッションのチェックボックスで設定
出席確認 アンケート ネットワークを使った既存のサービスの中から 技術的な観点 ( 特にネットワーク関連と思われる点 ) で興味がある ( すごい 不思議などと思う ) ものを一つ挙げて どういう点に興味があるかを簡潔に述べなさい 提出方法 :sec02@sun.ac.jp 宛てにメール 提出期限 : この時間中 (14:10 まで )
次回予告 来週 再来週は冬休み 次回は 1 月 9 日 PHP の続き サーバやクライアントの情報を受け取る