ColdFusion へようこそ

ColdFusion信者歴22年です。社畜SEをしております。

cfinclude と cfmodule

こんにちは、管理人のハルです。

すいません、忙しくて前回の投稿からだいぶ間が空いてしまいました。
CFCが実装されてから、あまり触れなくなったcfmoduleと、似て非なるcfinclude。
今回はこの2つについてお話をしたいと思います。

cfmodule は 入出力を定義して、引数と戻り値を使った処理が可能なユーザ定義関数です。
対して cfinclude は cfincludeで指定したファイルの中身をそのままHTMLとして出力するための機能です。
ではcfmoduleから具体的に見ていきましょう。

<!--- mod.cfm --->
<!--- 初期値 --->
<cfparam name="Attributes.prmDateTime" default="#Now()#">
<cfset Caller.rtnDateTime = DateTimeFormat(Attributes.prmDateTime, "yyyy/mm/dd hh:MM:ss")>

まずは cfmodule で呼び出されるUDF側を作成します。
単純に引数で渡された日付に対してフォーマットを整えて呼出元に返してあげるだけの処理です。

<!--- test.cfm --->
<cfmodule template="mod.cfm" prmDateTime="#Now()#">
<cfoutput>#Variables.rtnDateTime#</cfoutput>

f:id:welcomcf:20210408142342p:plain

呼出側は cfmodule で呼び出すUDFが鬼呪されたファイル及び引数を指定します。
戻り値があれば、戻り値は接頭辞Variablesの変数として格納されるので、cfoutputで中身を見てみます。
今日の日付が、mod.cfm で指定したフォーマットで出力されていますね。
cfmodule はこのように呼出元に処理結果を返してくれる動きです。

代わって cfinclude を見てみましょう。

<!--- inc.cfm --->
<h1>これはインクルードされる文章です。</h1>

CFの処理を書いてもいいのですが、まずはHTMLで試してみます。

<!--- test.cfm --->
<cfinclude template="inc.cfm">

呼出側ではファイルのパスを指定するだけです。
cfincludeを記述した位置に、指定したファイルの内容が出力されます。
呼出先にCFの関数や変数を書けば、CF側で処理されて出力されます。

f:id:welcomcf:20210408142405p:plain

似て非なるcfmoduleとcfincludeですが、CFCが実装されてからはあまり利用しなくなった印象です。
私の勤務先では、cfmodule は単一処理の共通化に過去よく利用しておりました。

上記でご紹介した記述以外にも様々な記述方法があると思います。
ぜひ皆さんもColdFusionでプログラムを楽しんでみてください。

それではまた次の機会に。

CFScriptで書いてみよう!(CFFTP)

こんにちは、管理人のハルです。
忙しくて間が空いてしまいました…。もっとたくさん書きたいことはあるのですがなかなか時間が取れないですね。

さて、ColdFusionにもFTPサービスへの接続機能は用意されています。
業務システムでFTPサービスを使ったファイルのやり取りは結構頻度的にあり得ますね。
簡易的なFTPサーバへの接続、ファイルのダウンロードを試してみましょう。

まずは公開されているFTPサーバに接続するコードを記述してみます。
定番ですが、理化学研究所さまの公開FTPサーバを利用させて頂きます。

<cfscript>
  ftpSvc = new ftp();
  ftpSvc.setConnection("ftpCon");
  ftpSvc.setUsername("anonymous");
  ftpSvc.setPassword("haru@welcomecf.net");
  ftpSvc.setServer("ftp.riken.jp");
  ftpSvc.setStopOnError(true);
  // ftpインスタンスオープン
  ftpSvc.open();
  // listDirアクションでFTPルートディレクトリの内容を取得
  qryDirList = ftpSvc.listDir(name="qryDirList", directory= "/Linux/", stopOnError="false").getResult();
  ftpSvc.close();
  writedump(qryDirList);
</cfscript>

f:id:welcomcf:20210315181802p:plain

これで、理化学研究所さまのFTPサーバのトップディレクトリが参照できますね。
では getFile関数でFTPサーバから任意のファイルを取得してみたいので、負荷が掛からないように、小さいテキストを取得してみます。
とりあえず centOSディレクトリを見てみましょう。
上の listDir 関数の directory属性を以下のように書き換えて実行してみます。

  qryDirList = ftpSvc.listDir(name="qryDirList", directory= "/Linux/centos", stopOnError="false").getResult();

f:id:welcomcf:20210315181818p:plain

試験的にサイズの小さなテキストファイルを指定のパスにダウンロードするようにしました。
getFile関数の属性「localfile」には対象のファイルの保存パス+ファイル名を指定します。

<cfscript>
  ftpSvc = new ftp();
  ftpSvc.setConnection("ftpCon");
  ftpSvc.setUsername("anonymous");
  ftpSvc.setPassword("haru@welcomecf.net");
  ftpSvc.setServer("ftp.riken.jp");
  ftpSvc.setStopOnError(true);
  // ftpインスタンスオープン
  ftpSvc.open();
  // getFileで特定のファイルを取得
  ftpSvc.getFile(
                connection="ftpCon"
                ,remotefile="/Linux/centos/timestamp.txt"
                ,localfile="C:\timestamp.txt"
                ,failIfExists = false
                );
  ftpSvc.close();
</cfscript>

どうでしょうか、目的のファイルがダウンロードできましたか?
localfile属性で指定したパスにファイルがダウンロードできたか確かめてみてください。

よく使うCFFTPのaction属性としては「putfile」「getfile」「changedir」などがあります。
基本的にCFFTPのタグ(CFML)の属性と同じ書き方なので、CFScriptだからと言って悩むことはないでしょう。
業務システムだとリテラルではなく変数を使って記述することになるでしょうが、例の一つとして見て頂ければと思います。

上記でご紹介した記述以外にも様々な記述方法があると思います。
ぜひ皆さんもColdFusionでプログラムを楽しんでみてください。

それではまた次の機会に。

CFコンポーネント [CFC] の活用

こんにちは、管理人のハルです。

ColdFusionでは拡張子CFCのファイルでユーザ定義関数を作り、それをコンポーネントとして活用できます。
処理のカプセル化と言われることもあります。
よく使う処理はコンポーネント化して処理を省力化かつ効率化しましょう、ということですね。

では具体的にどうするかコードを見ていきましょう。
まずは以下のようなコードを書いてみることにします。
単純に現在日時と、現在日時に該当する曜日(に該当するCF上の処理値)を表示します。

<cfscript>
  // a.cfm
  today = DateTimeFormat(Now(), "yyyy/MM/dd HH:nn:ss");
  dayOfWeek = DayOfWeek(today);
  writedump('今日の日付:'&today);
  writeoutput('<br>');
  writedump('今日の曜日:'&dayOfWeek);
</cfscript>

今日の日付を返す関数 [Now] に対して、日付のフォーマットを指定する関数 [DateTimeFormat] で形式を整えています。
また日付から曜日に該当する数値を返す関数 [DayOfWeek] の値を表示します。
結果は以下のような表示になることでしょう。
f:id:welcomcf:20210305172709p:plain

ではこれだと曜日が数字でわかりづらいので、日本の曜日形式に修正して cfc でコンポーネント化してみましょう。
DayOfWeekAsStringという関数も存在しますが、Sunday,Monday,Tuesday...と英語で返ってくるので、今回は自分で関数を作ります。
以下の処理を別途、b.cfc というファイルで作成してみます。

<!--- b.cfc --->
<cfcomponent output="no" >
<cffunction name="returnDate" output="no" returnType="string" access="public">
  <cfscript>
    // 曜日に該当する数字をセット
    retValue = DateTimeFormat(Now(), "yyyy/MM/dd HH:nn:ss");
    return retValue;
  </cfscript>
</cffunction>
<cffunction name="returnDayOfWeek" output="no" returnType="string" access="public">
  <cfscript>
    // 曜日に該当する数字をセット
    DayNumber = DayOfWeek(Now());
    // DayOfWeekの結果に該当する文字列を変数にセット
    switch(DayNumber){
      case 0:
        retValue = "土曜日";
        break;
      case 1:
        retValue = "日曜日";
        break;
      case 2:
        retValue = "月曜日";
        break;
      case 3:
        retValue = "火曜日";
        break;
      case 4:
        retValue = "水曜日";
        break;
      case 5:
        retValue = "木曜日";
        break;
      case 6:
        retValue = "金曜日";
        break;
    };
    return retValue;
  </cfscript>
</cffunction>
</cfcomponent>

このCFコンポーネントを利用する際に注意するのが、ColdFusion管理画面のマッピングです。
予めこのCFCファイルを設置するパスを決めておくことで、パスを省略できます。
例では「D:¥inetpub¥WCF」というCFコンポーネント用のディレクトリを決め、ColdFusion管理画面で登録しています。
f:id:welcomcf:20210305172404p:plain

マッピングの登録を行った場合、CFC呼出は以下のように記述します。

<cfscript>
 // a.cfm
  // オブジェクト生成
  cmpDateTime = createObject("component", "WCF.b");
  // b.cfmのユーザ定義関数をコール
  Local.retDate = invoke(cmpDateTime, "returnDate");
  Local.retDayName = invoke(cmpDateTime, "returnDayOfWeek");
  // 戻り値を表示
  writedump('今日の日付:'&Local.retDate);
  writeoutput('<br>');
  writedump('今日の曜日:'&Local.retDayName);
</cfscript>

結果、以下のような表示が行われれば成功です。
f:id:welcomcf:20210305172458p:plain

結果、CFCコンポーネント処理化する前と同じような処理が実現できました。
例えばこの処理を必ず現在日時をベースにするのではなく、引数で与えた日時を基に結果を返すようにもできます。
シチュエーションごとに利用方法は多彩になりますね。ここにプログラムの面白味があると感じます。

上記でご紹介した記述以外にも様々な記述方法があると思います。
ぜひ皆さんもColdFusionでプログラムを楽しんでみてください。

それではまた次の機会に。