今回は、カウンターを表示します。
ホームページにある、
「あなたは○○番目の訪問者です」
というものです。
といっても、最近あまり見ないですね。
また、
「ノーマル」「黒ボックス」「デジタル」
をそれぞれ指定すると、
画像表示が変わります。
こちらをクリックしてください。
<cfinclude template="define.cfm">
<cfinclude template="header.cfm">
<cfinclude template="counter.cfm">
<!---解説
counter.cfmファイルを利用しています。
今回の処理の中心となるファイルです。
--->
<cfinclude template="disp1.cfm">
<cfinclude template="disp2.cfm">
<cfinclude template="footer.cfm">
<cfset title="カウンター">
<cfset keta=6>
<!---解説
カウンター表示の桁数を設定しています。
--->
<cfset img_type=arrayNew(1)>
<!---解説
arrayNew()で配列を作成します。
3次元までの配列が可能です。
今回は1次元です。
--->
<cfset img_type[1]="ノーマル">
<cfset img_type[2]="黒ボックス">
<cfset img_type[3]="デジタル">
<cfif isDefined("url.type")>
<cfcookie name="type" value="#url.type#">
<!---解説
cfcookieタグでクッキー変数typeを設定します。
--->
</cfif>
<cfparam name="cookie.type" default="1">
<!---解説
cfparamタグはnameで指定した変数が存在しない時、
defaultで指定した値を設定します。
初めてプログラムを実行した時は
cookie.type変数が存在していないので、
1がセットされます。
--->
<cfset ftype="#cookie.type#">
<cfoutput>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
<title>#title#</title>
</head>
<body>
■#title#<br><br>
現在の表示画像:<b>#img_type[ftype]#</b><br>
<br>
以下を選択すると画像が変わります。<br>
<cfloop index="i" from="1" to="#arrayLen(img_type)#">
・<a href="index.cfm?type=#i#">#img_type[i]#</a><br>
</cfloop>
<!---解説
arrayLen関数で、配列の個数を求めます。
今回は3つです。
--->
<hr>
</cfoutput>
<cflock name="counter" timeout="100">
<!---解説
cflockタグで排他制御します。
ネットワークでの処理では排他制御は重要です。
マニュアルでcflockについて見てみると、
「ColdFusion Serverは、1度に複数のページリクエストを処理できる
マルチスレッドWebアプリケーションサーバです。」
とあります。また注意として、
「ファイル操作連想配列をcflockで囲むとファイルが開き、
他のアプリケーションやColdFusionタグを使用して
書き込みが実行されるため、
ファイルの更新に失敗することはありません。」
とありました。
ようするに、今回のプログラムでcflockタグを使用しなかったら、
1度に複数のページリクエストがあるかもしれないので、
カウンタ用のファイルは壊れるかもしれません。
cflockタグの使用によって同時処理はないので、
ファイルが壊れることはありません。
nameはlock名称です。これを元に処理を待ちます。
アプリケーションに対してユニークにしてください。
timeoutは、ロックを得るときまでの最大時間を秒単位に指定します。
今回はロック内の処理をするまで最大100秒待ちます。
--->
<cfset fname="#ExpandPath('counter.txt')#">
<!---解説
ExpandPath関数で、指定した相対パスを絶対パスで返します。
この関数を使うことにより、以下の利点が考えられます。
1.絶対パスの穏便
わざわざ物理的な指定、例えば「c:\hoge\」などを
プログラム内で書く必要がありません。
このことは、プログラムを見てマシンのディレクトリ構成が
わからないというセキュリティ上の利点もあります。
2.アプリケーションの柔軟な対応
例えば、今回のプログラムを別のディレクトリに移動しても、
プログラム内容を変更することなく動作させることができます。
--->
<cffile action="read" file="#fname#" variable="cnt">
<!---解説
cffileタグのreadアクションにより、ファイル内容を読み込みます。
ファイル名は絶対パス名で指定します。
今回の場合は、読み込んだファイル内容をcnt変数にセットします。
--->
<cfset cnt=cnt+1>
<!---解説
cnt変数を1、カウントアップしています。
--->
<cffile action="write" file="#fname#" output="#cnt#" addnewline="No">
<!---解説
cffileタグのwriteアクションにより、ファイルを書き出します。
ファイル名は絶対パス名で指定します。
outputに書き出す内容をセットします。
addnewline="No"で改行をセットしません。
--->
</cflock>
<cfset cnt=RepeatString("0",keta-len(cnt)) & cnt>
<!---解説
指定した桁数の、数字の文字列に編集します。
今回のRepeatStringの設定により、
指定桁からカウンターの桁数を差し引いた分の桁の
0の文字列が作られます。
&により文字列同士の結合を行います。
--->
<cfoutput>
■画像表示<br>
<cfloop index="i" from="1" to="#len(cnt)#">
<!---解説
cntの桁数分、繰り返します。
--->
<cfset gfile="img/#ftype#/" & mid(cnt,i,1) & ".gif">
<!---解説
画像ファイル名を指定します。
例えば「ノーマル」を指定、数字が0の場合、
img/1/0.gif
という文字列が作られます。
あらかじめimgディレクトリ内に1,2,3ディレクトリを作り、
その中に0から9までのgifファイルを用意しておきます。
--->
<img src="#gfile#">
</cfloop>
</cfoutput>