質問

前任者のコードを調べていると、「request」スコープの使用法が頻繁に見られます。このスコープの適切な使用法は何ですか?

役に立ちましたか?

解決

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

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

Application.cfm 内のアプリケーション変数の適切な実装は次のようになります。

<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 の詳細については、次のリンクを参照してください。 Raymond Camden のブログでこの投稿をお勧めします.

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

他のヒント

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

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

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

多くのアプリケーションはこのスコープを使用してアプリケーション レベルの変数 (構成設定など) を保存しますが、リクエスト スコープとアプリケーション スコープの大きな (そして場合によっては微妙な) 違いは、同じリクエスト スコープの変数の値が異なる可能性があることです。個々のページリクエストごとに異なります。

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

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


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

大丈夫。

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

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

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top