14

前任者のコードを調べて、「リクエスト」スコープの使用法を頻繁に確認しました。このスコープの適切な使用法は何ですか?

4

4 に答える 4

21

コードの任意の部分で使用できるスコープがいくつかあります。セッション、クライアント、Cookie、アプリケーション、およびリクエストです。特定の方法で使用することはお勧めできません(つまり、カスタムタグまたはCFC内でリクエストまたはアプリケーションスコープを使用します。これは結合であり、カプセル化の原則に違反し、悪い習慣と見なされます)。また、特別な目的があるものもあります。Cookieはクライアントに保持されます。物理Cookieとしてのマシン、およびSessionスコープの変数はユーザー固有であり、Webサイトでのユーザーのセッションで期限切れになります。

変数が変更される可能性が非常に低く(すべての目的と目的で一定)、アプリケーションの起動時に初期化して再度書き込むことができない場合は、すべてのユーザーとすべてのセッションの間で変数が保持されるため、通常はアプリケーションスコープに変数を配置する必要があります。適切に実装されると、1回書き込まれ、N回読み取られます。

Application.cfmでのApplication変数の適切な実装は、次のようになります。

<cfif not structKeyExists(application, "dsn")>
    <cflock scope="application" type="exclusive" timeout="30">
        <cfif not structKeyExists(application, "dsn")>
            <cfset application.dsn = "MyDSN" />
            <cfset foo = "bar" />
            <cfset x = 5 />
        </cfif>
    </cflock>
</cfif>

アプリケーションスコープ内の変数の存在はロックの前後でチェックされるため、2人のユーザーがアプリケーションの起動時に競合状態を作成した場合、そのうちの1人だけがアプリケーション変数を設定することになります。

このアプローチの利点は、要求ごとにこれらの格納された変数を常に更新せず、ユーザーの時間とサーバーの処理サイクルを浪費しないことです。トレードオフは、それが少し冗長で複雑であるということです。

これは、Application.cfcの追加により大幅に簡素化されました。これで、アプリケーションの起動時に作成される変数を指定でき、存在のロックとチェック、およびそのすべての楽しいことについて心配する必要はありません。

<cfcomponent>
    <cfset this.name = "myApplicationName" />

    <cffunction name="onApplicationStart" returnType="boolean" output="false">
        <cfset application.dsn = "MyDSN" />
        <cfset foo = "bar" />
        <cfset x = 5 />
        <cfreturn true />
    </cffunction>
</cfcomponent>

利用可能なさまざまな特殊機能のすべてと、その使用方法の詳細を含むApplication.cfcの詳細については、RaymondCamdenのブログにあるこの投稿をお勧めします。

要約すると、リクエストスコープはコード内のどこでも利用できますが、必ずしもどこでも使用できるとは限りません。前任者がカプセル化を解除するためにそれを使用していた可能性があり、それはリファクタリングするのが面倒な場合があります。そのままにしておくのが最善かもしれませんが、どのスコープがその仕事に最適なツールであるかを理解することで、将来のコードが確実に改善されます。

于 2008-08-25T19:54:19.210 に答える
16

これは非常に主観的な質問であり、最新の ColdFusion アプリケーションで request スコープを使用することは決して「適切」ではないと主張する人さえいます。

その免責事項が邪魔にならないので、リクエストスコープとは何か、そしてそれがどこで役立つかを定義しましょう。

リクエスト スコープは、単一の ColdFusion ページ リクエストにおける絶対的なグローバル スコープです。これは、アプリケーション、サーバー、クライアント、およびセッション スコープのような共有スコープではないため、スレッドセーフにするためにロックは必要ありません (CF8 の CFTHREAD タグを使用して単一の要求からワーカー スレッドを生成しない限り)。グローバル スコープとして、変数を親から呼び出し元に渡すことなく、要求のスタック内の任意のレベルで変数を永続化するための非常に便利な方法です。これは、古い CF アプリでネストされたカスタム タグまたは再帰的なカスタム タグを介して変数を永続化するための非常に一般的な方法でした。

多くのアプリケーションはこのスコープを使用してアプリケーション レベルの変数 (構成設定など) を格納しますが、リクエスト スコープとアプリケーション スコープの大きな (そして時には微妙な) 違いは、同じリクエスト スコープの変数の値を個々のページ要求によって異なります。

あなたの前任者は、カプセル化されたコード単位またはネストされたコード単位間のジャンプを生き残るために必要な変数を、明示的に渡すことなく便利に設定する手段としてこのスコープを使用したと思います。

于 2008-08-26T07:04:13.203 に答える
0

私は私たちのサイトを動かすために使用される私の会社のフレームワークを書いてきました。

リクエスト変数を使用して、他のCFCで利用できる特定のデータを設定します。これにより、データを継続的に渡す必要なしに、アプリケーション全体でデータを利用できるようになります。静的関数コンポーネントである限り、リクエストとアプリケーションを使用すれば問題はないと正直に信じています。これについての考え方が間違っているかどうかはわかりませんが、フレームワークをリリースすると表示されます。

于 2011-09-26T22:33:08.110 に答える
0

さて、あなたのコードにコメントしたかっただけです。私が狂っているように見えたら、私を許してください。しかし、最初に structKeyExists を既に確認しました。それが true になることがわかっているので、別のチェックを実行しても意味がありません。だから私のバージョンはこれだろう...しかし、それは私だけです。


<cfif not structKeyExists(application, "dsn")>
    <cflock scope="application" type="exclusive" timeout="30">
            <cfset application.dsn = "MyDSN" />
            <cfset foo = "bar" />
            <cfset x = 5 />
    </cflock>
</cfif>

大丈夫。

于 2010-08-11T22:16:18.230 に答える