PHP 実用的なサンプル

PHP 実用的なサンプル
0312006003
浅川 和久
2016/7/9
PHP 実用的なサンプル
1
和暦変換プログラム
初期状態
実行中
2016/7/9
PHP 実用的なサンプル
2
和暦変換プログラム
• デバッグルーチン
• 年月日の入力
• 厳密な入力チェック
– 文字種や数値の範囲チェック、閏年判定、性格な妥当性チェック
• 正確な和暦変換
– 和暦の境界チェック、元号の変わり目の判定
• 実行履歴の表示
– 過去に表示された判定結果を逐次表示
2016/7/9
PHP 実用的なサンプル
3
デバッグルーチン
<?
// printd.inc
// デバッグ文の表示
function printd($msg)
{
printf("<!-- %s -->\n", $msg);
}
?>
• HTMLコメント書式 <!-- と --> で囲む
• デバッグ表示 「表示」ー「ページのソース」
2016/7/9
PHP 実用的なサンプル
4
日付のチェック(1)
<?
// date_is_valid.inc
// 入力値のチェック
// 返り値:True 妥当な値
function date_is_valid($yyyy ,$mm, $dd){
printd("\$yyyy=$yyyy, \$mm=$mm, \$dd=$dd");
if(! ereg("^[0-9][0-9]+$", $yyyy)) return False;
if(! ereg("^[0-9][0-9]*$", $mm)) return False;
if(! ereg("^[0-9][0-9]*$", $dd)) return False;
printd("date_is_valid(): check1");
if($mm < 1 || 12 < $mm) return False;
printd("date_is_valid(): check2");
if($dd < 1 || 31 < $dd) return False;
printd("date_is_valid(): check3");
2016/7/9
PHP 実用的なサンプル
5
正規表現
if(! ereg("^[0-9][0-9]+$", $yyyy)) return False;
• [0-9][0-9]+$
– 「0から9」の文字で始まり(^)、その直後に「0から9」までのいずれかの文字が
1個以上の繰り返し(+)
if(! ereg("^[0-9][0-9]*$", $mm)) return False;
• [0-9][0-9]*$
– 「0から9」の文字で始まり(^)、その直後に「0から9」までのいずれかの文字が
0個以上の繰り返し(*)
2016/7/9
PHP 実用的なサンプル
6
日付のチェック(2)
if($dd==31){
if($mm==2 || $mm==4 || $mm==6 ||
$mm==9 || $mm==11){
printd("date_is_valid(): check4");
return False;
}
return True;
}
if($dd==30){
if($mm==2){
printd("date_is_valid(): check5");
return False;
}
return True;
}
2016/7/9
if($mm==2 && $dd==29){
if($yyyy % 4 == 0){
if($yyyy % 100 == 0){
if($yyyy % 400 == 0){
return True;
}
printd("date_is_valid(): check6");
return False;
}
return True;
}
printd("date_is_valid(): check7");
return False;
}
return True;
}
?>
PHP 実用的なサンプル
7
和暦への変換(1)
<?
// calc_wareki.inc
// 元号の計算
// 返り値:計算結果の文字列
function calc_wareki($yyyy, $mm, $dd)
{
printd("\$yyyy=$yyyy, \$mm=$mm, \$dd=$dd");
$border = array(
array(開始日 => 18680908, 終了日 => 19120730, 元号 => 明治),
array(開始日 => 19120730, 終了日 => 19261225, 元号 => 大正),
array(開始日 => 19261225, 終了日 => 19890107, 元号 => 昭和),
array(開始日 => 19890107, 終了日 => 20091231, 元号 => 平成)
);
$target = sprintf("%04d%02d%02d", $yyyy, $mm, $dd);
printd("\$target=$target");
2016/7/9
PHP 実用的なサンプル
8
和暦への変換(2)
if($target < $border[0][開始日]) return "計算対象外";
printd("calc_wareki(): check1");
for($i=0; $border[$i]; $i++){
printd("calc_wareki(): \$border[$i][元号]=" . $border[$i][元号]);
if($border[$i][開始日] <= $target && $target <= $border[$i][終了日]){
$temp = ($yyyy - substr($border[$i][開始日], 0, 4) + 1);
$wareki = $border[$i][元号].($temp == "1" ? "元" : $temp);
break;
}
}
if($i > 3) return "計算対象外";
printd("calc_wareki(): check2");
return sprintf("%s年%d月%d日", $wareki, $mm, $dd);
}
?>
2016/7/9
PHP 実用的なサンプル
9
セッションの考え方
• 「履歴の表示」・・・履歴のデータをどこかに保存しておかねばならない
– クライアント内のどこか
– サーバ内のどこか
• Webページへのアクセスは毎回完結した処理
• 情報を何らかな方法で持ちまわることで一連の処理を関連づけてやれば、
見かけ上連続した処理を実現できる
論理的に連続した処理のことをセッションと呼ぶ
これを実現することをセッション管理と呼ぶ
2016/7/9
PHP 実用的なサンプル
10
セッションの実現方法
• クライアントが持ちまわる形式が一般的
• サーバに情報を保存する場合でも、保存した情報を取り出すためのキー
になる情報自体はクライアント側に持たせなければならない
• Webのしくみだけではサーバ側がクライアントを一意に識別することが困
難
2016/7/9
PHP 実用的なサンプル
11
php.iniの編集
• session_register
– 現在のセッションに1つ以上の変数を登録する
• /etc/php/apache2/php.ini を編集
– register_globals off → register_globals on
2016/7/9
PHP 実用的なサンプル
12
メインルーチン(1)
<?
// wareki_sample.php
session_start(); // セッションを開始/復帰
if($button){
$hist = "";
session_destroy(); // セッションデータを破棄
}
session_register(hist); // セッションへ変数を登録
include("printd.inc");
include("date_is_valid.inc");
include("calc_wareki.inc");
2016/7/9
PHP 実用的なサンプル
13
メインルーチン(2)
//
// 入力画面の表示
//
function display_input_area($yyyy, $mm, $dd, $hist)
{
<? echo session_name() . “=“ . session_id(); ?>
?>
<form action="wareki_sample.php?<?=SID?>">
西暦
<input type=text name=yyyy size=5 value="<? echo $yyyy; ?>">年
<input type=text name=mm size=5 value="<? echo $mm; ?>">月
<input type=text name=dd size=5 value="<? echo $dd; ?>">日
<input type=submit value="送信">
<input type=submit name=button value="履歴のクリア">
</form>
<?
}
2016/7/9
PHP 実用的なサンプル
14
メインルーチン(3)
// メイン
printd("前回のセッション名=".session_name());
printd("前回のセッションID=".session_id());
printd("セッションモジュール名=".session_module_name());
printd("セッションデータ保存path名=".session_save_path());
printd("\$histがセッションに登録されているか=".(session_is_registered("hist") ? "True" : "False"));
printd("前回の\$hist=".$hist);
display_input_area($yyyy, $mm ,$dd, $hist); // 入力エリアの表示
if(empty($yyyy) && empty($mm) && empty($dd)) exit;
if(date_is_valid($yyyy, $mm, $dd)){ // 入力のチェック
$wareki = calc_wareki($yyyy, $mm, $dd); //元号の計算
$result = sprintf("西暦%d年%d月%d日は%sです。<br>\n",$yyyy, $mm, $dd, $wareki);
echo $result; // 結果の表示
}else{
print("<font color=red>日付の入力が誤っています。</font>\n");
}
if($hist){
print("<table border>\n<tr><td>\n$hist</table>\n"); // 履歴の表示
}
if($result){
$hist = date("Y/m/d H:i:s ") . $result . $hist; // 履歴の追加
}
printd("今回の\$hist=".$hist);
?>
2016/7/9
PHP 実用的なサンプル
15
PHP3 セッション管理
1.
2.
3.
HTTPクッキーを使う
URLの引数として指定する
hidden属性を使う
2016/7/9
PHP 実用的なサンプル
16
HTTPクッキー
• 変数の値をクライアント側にファイルとして保持する
• ブラウザによってはサポートされていない
• 設定で無効にできる
2016/7/9
PHP 実用的なサンプル
17
HTTPクッキー
<?
include("date_is_valid.inc");
include("calc_wareki.inc");
// デバッグ文の表示
function printd($msg){
//printf("<!-- %s -->\n", $msg);
syslog(LOG_INFO, sprintf("<!-- %s -->\n", $msg));}
//
// 入力画面の表示
//
function display_input_area($yyyy, $mm, $dd, $hist){
?>
<form action="wareki_sample-cookie.php">
西暦
<input type=text name=yyyy size=5 value=“<? echo $yyyy; ?>”>年
<input type=text name=mm size=5 value=“<? echo $mm; ?>”>月
<input type=text name=dd size=5 value=“<? echo $dd; ?>”>日
<input type=submit value="送信"><input type=submit name=button value="履歴のクリア"></form>
<?
2016/7/9
PHP 実用的なサンプル
18
HTTPクッキー
//
// メイン
//
if($buttin){
$hist ="";
}
printd("\$hist=$hist");if($yyyy && $mm && $dd){
if(date_is_valid($yyyy, $mm, $dd)){ // 入力のチェック
$wareki = calc_wareki($yyyy, $mm, $dd); // 元号の計算
$result = sprintf("西暦%d年%d月%d日は%sです。<br>\n",$yyyy, $mm, $dd, $wareki);
$errmsg = "";
}else{
$result = ""; $errmsg = "<font color=red>日付の入力が誤っています</font>\n";
}
}if($hist){
$history = "<table border>\n<tr><td>\n$hist</table>\n";
}if($result){
$hist = date(“Y/m/d H:i:s ”) . $result . $hist; // 履歴に追加
}setCookie(“hist”, $hist, time()+3600); // クッキーの設定
display_input_area($yyyy, $mm ,$dd, $hist); // 入力エリアの表示
echo $result; // 結果の表示
echo $errmsg; // エラー表示
echo $history; // 履歴の表示
?>
2016/7/9
PHP 実用的なサンプル
19
URLの引数
• クライアントの実装に依存しない
• URLを保存しておくと再利用できる
• URLが長くなって見づらい
• URLの長さ制限がある
2016/7/9
PHP 実用的なサンプル
20
URLの引数
<?
include("date_is_valid.inc");
include("calc_wareki.inc");
// デバッグ文の表示
function printd($msg){
//printf("<!-- %s -->\n", $msg);
syslog(LOG_INFO, sprintf("<!-- %s -->\n", $msg));
}
//
// 入力画面の表示
//
function display_input_area($yyyy, $mm, $dd, $hist){
?>
<form method="post" action="wareki_sample-url.php?hist=<?echo urlencode($hist)?>">
西暦
<input type=text name=yyyy size=5 value=“<? echo $yyyy; ?>”>年
<input type=text name=mm size=5 value=“<? echo $mm; ?>”>月
<input type=text name=dd size=5 value=“<? echo $dd; ?>”>日
<input type=submit value="送信"><input type=submit name=button value="履歴のクリア"></form>
<?
}
2016/7/9
PHP 実用的なサンプル
21
URLの引数
//
// メイン
//
if($buttin){
$hist ="";
}
printd("\$hist=$hist");
$hist = urldecode($hist);
if($yyyy && $mm && $dd){
if(date_is_valid($yyyy, $mm, $dd)){ // 入力のチェック
$wareki = calc_wareki($yyyy, $mm, $dd); // 元号の計算
$result = sprintf("西暦%d年%d月%d日は%sです。<br>\n",$yyyy, $mm, $dd, $wareki);
$errmsg = "";
}else{
$result = "";
$errmsg = "<font color=red>日付の入力が誤っています</font>\n";
}
}if($hist){
$history = "<table border>\n<tr><td>\n$hist</table>\n";
}if($result){
$hist = date(“Y/m/d H:i:s ”) . $result . $hist; // 履歴に追加
}display_input_area($yyyy, $mm ,$dd, $hist); // 入力エリアの表示
echo $result; // 結果の表示
echo $errmsg; // エラー表示
echo $history; // 履歴の表示
?>
2016/7/9
PHP 実用的なサンプル
22
hidden属性
• クライアントに依存しない
• URLは変わらない
• ブラウザを終了すると変数を復元できない
2016/7/9
PHP 実用的なサンプル
23
hidden属性
<?
include("date_is_valid.inc");
include(“calc_wareki.inc”);// デバッグ文の表示
function printd($msg){
//printf("<!-- %s -->\n", $msg);
syslog(LOG_INFO, sprintf("<!-- %s -->\n", $msg));
}
//
// 入力画面の表示
//
function display_input_area($yyyy, $mm, $dd, $hist){
?>
<form action="wareki_sample-hidden.php">
西暦
<input type=text name=yyyy size=5 value=“<? echo $yyyy; ?>”>年
<input type=text name=mm size=5 value=“<? echo $mm; ?>”>月
<input type=text name=dd size=5 value=“<? echo $dd; ?>”>日
<input type=submit value="送信"><input type=submit name=button value="履歴のクリア">
<input type=hidden name=hist value="<? echo $hist; ?>">
</form>
<?
}
2016/7/9
PHP 実用的なサンプル
24
hidden属性
//
// メイン
//
if($buttin){
$hist ="";
}
printd("\$hist=$hist");
$hist = urldecode($hist);
if($yyyy && $mm && $dd){
if(date_is_valid($yyyy, $mm, $dd)){ // 入力のチェック
$wareki = calc_wareki($yyyy, $mm, $dd); // 元号の計算
$result = sprintf("西暦%d年%d月%d日は%sです。<br>\n",$yyyy, $mm, $dd, $wareki);
$errmsg = "";
}else{
$result = "";
$errmsg = "<font color=red>日付の入力が誤っています</font>\n";
}
}if($hist){
$history = "<table border>\n<tr><td>\n$hist</table>\n";
}if($result){
$hist = date(“Y/m/d H:i:s ”) . $result . $hist; // 履歴に追加
}
display_input_area($yyyy, $mm ,$dd, $hist); // 入力エリアの表示
echo $result; // 結果の表示
echo $errmsg; // エラー表示
echo $history; // 履歴の表示
?>
2016/7/9
PHP 実用的なサンプル
25