「 PHP」のページ記事
カウンターのソースファイル(修正版)
[sourcecode language=”php”]
<?php
// カウントデータとIPアドレスデータのファイルのパス
// count.phpと異なるフォルダに設置するときは変更
$config[‘file’][‘count’] = ‘cnt.php’;
$config[‘file’][‘check’] = ‘ip.php’;
// カウンタの桁数
$config[‘figure’][‘total’] = 6;
$config[‘figure’][‘today’] = 4;
$config[‘figure’][‘yesterday’] = 4;
[/sourcecode]
[php]
<?php
// カウントデータとIPアドレスデータのファイルのパス
// count.phpと異なるフォルダに設置するときは変更
$config[‘file’][‘count’] = ‘cnt.php’;
$config[‘file’][‘check’] = ‘ip.php’;
// カウンタの桁数
$config[‘figure’][‘total’] = 6;
$config[‘figure’][‘today’] = 4;
$config[‘figure’][‘yesterday’] = 4;
// 重複カウント回避時間
// IPアドレスによる同一クライアントの重複カウント回避時間
//
// 設定時間内は同一IPアドレスの重複カウントをしない。
// 単位は分 / (例) 60 を設定すると1時間カウントしない
// 0 を設定すると常にカウントする。
// (IPアドレスの記録もしない。)
$config[‘limit’][‘time’] = 60;
// IPアドレスを記録する上限数
// アクセス時、この記録を参照し、
// 同一IPアドレスで、「重複カウント不許可の時間」内の記録があればカウントしないことになります。
//
// 重複カウント回避時間設定が0の場合IPアドレスの記録・チェックともに行いません。
// 上限を超えた場合、古いリストから順に削除されるので、
// 1時間重複カウントを防止すると仮定した場合、1時間のユニークアクセスと同等以上の上限数を設定すべきです。
// また、上限数を大きくすればするほどチェックに時間がかかり動作は遅延します。
// アクセス状況と動作スピードを検証しつつ適宜設定してください。
$config[‘limit’][‘ip’] = 100;
// カウントデータ取得
if($fp = @fopen($config[‘file’][‘count’],"r+")) {
flock ($fp,LOCK_EX);
$data = fgets($fp);
// データ分割
$datas = divideData($data);
// カウントアップ
if(ipCheck($config)) {
$datas = countUp($datas);
rewind($fp);
ftruncate($fp,fwrite($fp,makeData($datas)));
}
fclose($fp);
// 出力
putCounter($config,$datas);
}
exit;
function putCounter($config,$datas) {
$datas[‘total’] = sprintf("%0".$config[‘figure’][‘total’]."d", $datas[‘total’]);
$datas[‘today’] = sprintf("%0".$config[‘figure’][‘today’]."d", $datas[‘today’]);
$datas[‘yesterday’] = sprintf("%0".$config[‘figure’][‘yesterday’]."d", $datas[‘yesterday’]);
$result=array(
‘total’=> $datas[‘total’],
‘today’=> $datas[‘today’],
‘yesterday’=> $datas[‘yesterday’]
);
$jsonedData = json_encode($result);
$callback="counter";
header("Content-type:text/html;charset=UTF-8");
print $callback . ‘(‘ . $jsonedData . ‘);’;
exit();
}
/** 書込みデータ作成 */
function makeData($datas) {
return join(‘,’,array($datas[‘date’],$datas[‘total’],$datas[‘today’],$datas[‘yesterday’]));
}
/** カウントアップ */
function countUp($datas) {
$date[‘today’] = date("Ymd");
$date[‘yesterday’] = date("Ymd",(time() – 60*60*24));
// データ内の日付検証
if($datas[‘date’] == $date[‘today’]) {
// 今日
$datas[‘today’]++;
}
elseif($datas[‘date’] == $date[‘yesterday’]) {
// 昨日
$datas[‘yesterday’] = $datas[‘today’];
$datas[‘today’] = 1;
}
else {
// 初回等、上記以外
$datas[‘yesterday’] = 0;
$datas[‘today’] = 1;
}
$datas[‘total’]++;
// 日付
$datas[‘date’] = $date[‘today’];
return $datas;
}
/** IPアドレスによる重複カウント防止 */
function ipCheck($config) {
$addr = $_SERVER[‘REMOTE_ADDR’];
// 判定値
$re = 0;
// 今回データ
$current = join(‘,’,array(time(),$addr));
// データバッファ
$buffer = array();
// 時間設定が0の場合、何もしないで1を返す
if($config[‘limit’][‘time’] == 0) {
return 1;
}
// IPデータ取得
$hit = 0;
if($fp = @fopen($config[‘file’][‘check’],"r+")) {
while($line = fgets($fp)){
$line = rtrim($line);
list($old[‘time’],$old[‘ip’]) = explode(‘,’,$line);
if($old[‘ip’] == $addr) {
if($old[‘time’] < time() – ($config[‘limit’][‘time’] * 10)) {
// 同一IPで設定時間外の場合、判定値を1とする
$re = 1;
}
$hit = 1;
}
else {
$buffer[] = $line."n";
}
}
// 同一IPがない場合、判定値を1とする
if($hit == 0) {
$re = 1;
}
// 今回のデータを格納
$buffer[] = $current."n";
sort($buffer);
// 記録上限数に調整
while(count($buffer) > $config[‘limit’][‘ip’]) {
array_shift($buffer);
}
// データ書込み
rewind($fp);
ftruncate($fp,fwrite($fp,join(”,$buffer)));
}
fclose($fp);
return $re;
}
/** データ分割 */
function divideData($data) {
$data = rtrim($data);
if($data) {
list($datas[‘date’],$datas[‘total’],$datas[‘today’],$datas[‘yesterday’]) = explode(‘,’,$data);
}
return $datas;
}
?>
[/php]
日付計算(1)「インクルードファイルの利用」
= 1989:
$gengo_s=”H”;
$gengo=”平成”;
$yy_wa=$yyyy-1988;
break;
case $yyyy >= 1926:
$gengo_s=”S”;
$gengo=”昭和”;
$yy_wa=$yyyy-1925;
break;
case $yyyy >= 1912:
$gengo_s=”T”;
$gengo=”大正”;
$yy_wa=$yyyy-1911;
break;
case $yyyy >= 1868:
$gengo_s=”M”;
$gengo=”明治”;
$yy_wa=$yyyy-1867;
break;
default:
return FALSE;
}
// 和暦を返す
switch($option){
case “s”: // 短い形式
return $gengo_s . $yy_wa. ” “;
break;
case “m”: // 通常の形式
if($yy_wa==1){
$yy_wa=”元”;
}
return $gengo . $yy_wa . ” 年”;
break;
case “l”: // 長い形式
if($yy_wa==1){
$yy_wa=”元”;
}
return $gengo . $yy_wa . ” 年(” . $eto . “)”;
break;
case “g”: // 元号のみ
return $gengo;
break;
case “e”: // 干支のみ
return $eto;
break;
default:
return FALSE;
}
}
// 和暦⇒西暦変換関数 toSeireki($yy_wa,$option)
function toSeireki($yy_wa,$option){
// 西暦を返す
switch($option){
case “H”:
return $yy_wa+1988;
break;
case “S”:
if($yy_wa=65){
return FALSE;
}else{
return $yy_wa+1925;
}
break;
case “T”:
if($yy_wa=16){
return FALSE;
}else{
return $yy_wa+1911;
}
break;
case “M”:
if($yy_wa=46){
return FALSE;
}else{
return $yy_wa+1867;
}
break;
default:
return FALSE;
}
}
?>
日付計算
結果:
<?php
// 今日の日付を配列にセットする
$datetime=getdate();
$yyyy=$datetime["year"];
$mm=$datetime["mon"];
$dd=$datetime["mday"];
if(isset($_POST['sub1'])){
// strlen()関数でデータのチェックをする
if(!strlen($_POST["day"])){
echo "
データが入力されていません”;
}else{
$day=@$_POST[“day”];
$val=@$_POST[“r1”];
if($val==0){
$date=date(“Y/m/d”,mktime(0,0,0,$mm,$dd+$day,$yyyy));
echo “
今日[“.date(“Y/m/d”,time()).”(”.isWeek(“now”).”)]から “.$day.”日後は、”.$date.”(”.isWeek($date).”)です。”;
}else{
$date=date(“Y/m/d”,mktime(0,0,0,$mm,$dd-$day,$yyyy));
echo “
今日[“.date(“Y/m/d”,time()).”(”.isWeek(“now”).”)]から “.$day.”日後は、”.$date.”(”.isWeek($date).”)です。”;
}
}
}
?>
暗号化と復号化(2)「base64エンコード関数を複数回用いて暗号化する」
base64エンコードを利用して暗号化する(2)
結果:
データが入力されていません”;
}else{
$str=@$_POST[“moji”];
$cnt=@$_POST[“num”];
echo “
元の文字列:”.$str;
// データのエンコード
for($i=1;$i<=$cnt;$i++){
$str=base64_encode($str);
echo "
暗号化(base64_encode)→第”.$i.”回目:”.$str;
}
// データのデコード
for($i=1;$i<=$cnt;$i++){
$str=base64_decode($str);
echo "
復元化(base64_decode)→第”.$i.”回目:”.$str;
}
}
}
?>
暗号化と復号化(1)「base64エンコードの利用」
base64エンコードを利用して暗号化する
結果:
<?php
if($_SERVER["REQUEST_METHOD"]=="POST"){
// strlen()関数でデータのチェックをする
if(!strlen($_POST["moji"]) or !strlen($_POST["moji"])){
echo "
データが入力されていません”;
}else{
$moji=@$_POST[“moji”];
$ango_moji=base64_encode($moji);
echo “
元の文字列:”.$moji;
echo “
暗号化(base64_encode):”.$ango_moji;
echo “
復元化(base64_decode):”.base64_decode($ango_moji);
}
}
?>
基本フォームをつくる(2)「複数のボタンをもつフォーム」
文字列の暗号化
結果:
<?php
if($_SERVER["REQUEST_METHOD"]=="POST"){
// strlen()関数でデータのチェックをする
if(!strlen($_POST["moji"])){
echo "
データが入力されていません”;
}else{
$moji=@$_POST[“moji”];
echo “
元の文字列:”.$moji.”
“;
switch($_POST[“sub1”]){
case “crypt”:
echo “暗号化文字列:”.crypt($moji);
break;
case “md5”:
echo “暗号化文字列:”.md5($moji);
break;
default:
echo “暗号化文字列:”.sha1($moji);
}
}
}
?>
基本フォームをつくる(1)
円の面積を求める
結果:
if(isset($_POST[“cmdCalc”])){
$r=@$_POST[“hankei”];
$s=$r*$r*3.14;
echo “半径が “.$r.” のとき、円の面積は “.$s.” です。”;
}
PHP Learning(学習テキスト)の目次
導入段階
導入段階では、PHPのプログラミングをはじめて学習する上で、参考となる例題を集めています。
[導入例題1]
例題1では、「半径を入力して、円の面積を求める」フォームを作成する作業を通じて、基本的なフォームの作り方、データの受け渡し方法やその処理の仕方について学習します。
[導入例題2]
例題2では、「文字列を暗号化する」作業を通じて、ボタンを複数もつ、少し複雑なフォームを作成し、データの受け渡しとその処理方法について学習します。
- 基本フォームをつくる(2):複数のボタンをもつフォーム
- 暗号化と復号化(1):base64エンコードの利用
- 暗号化と復号化(2):base64エンコード関数を複数回用いて暗号化する
[導入例題3]
例題3では、「西暦⇔和暦」変換関数を作る作業を通じて、関数の作り方と使用方法について学習します。
[導入例題4]
例題4では、例題3で作成した「西暦⇔和暦」変換関数をインクルードファイルとしてライブラリー化する方法について学習します。例題で扱う内容は日付に関する計算問題です。
- 日付計算(1):インクルードファイルの利用
- 日付計算(2)
- 日数計算の追加
- 西暦・和暦・干支対応表の追加
理解段階
理解段階では、PHPのプログラミングで必要となる基礎事項をサンプル例題によって学習します。
[数値]
[日付]
日付について学習します。
[ファイル]
ファイルの操作について学習します。
[ディレクトリ]
ディレクトリの操作について学習します。
[GD]
画像ファイルについて学習します。
応用段階
応用段階では、PHPによるWebアプリケショーンのプログラミングに挑戦します。
[万年カレンダー]
手始めに、万年カレンダーを作成します。週休日の色変更も追加してみます。