次のコードは、深さ構造体をチェックし、Session スコープを正しくロックします。
<cffunction name="Exists" access="public" output="false" returntype="boolean">
<cfargument name="Key" required="true" type="string">
<cfset local.mainKeyList = ListChangeDelims(ListDeleteAt(Arguments.Key, ListLen(Arguments.Key, "."), "."), ",", ".")>
<cfset local.StructChain = "Session">
<cfloop list="#local.mainKeyList#" index="local.CurrentKey">
<cfset local.StructChain &= '["#local.CurrentKey#"]'>
</cfloop>
<cflock scope="session" type="readonly" timeout="3">
<cftry>
<cfset local.Exists = StructKeyExists(Evaluate(local.StructChain), ListLast(Arguments.Key, "."))>
<cfcatch>
<cfset local.Exists = false>
</cfcatch>
</cftry>
</cflock>
<cfreturn local.Exists>
</cffunction>
<cflock scope="session" type="exclusive" timeout="3">
<cfset Session.data.log.deep = "I'm here!">
</cflock>
<cfoutput>#Exists("data.log.deep")#</cfoutput>
願わくば、この関数のコードの量が、なぜヘルパー関数が有用なのかをあなたの理由を熟考している人々に正当化することを願っています. これは現在ではありませんが、強化される可能性があり、配列内の構造体も処理します。これはまた、空の Arguments.Key を処理したり、cflock タイムアウトで正常に失敗したりしませんが、開始する必要があります。
さらに、cflock は必要ないとコメントしたい場合は、まずColdFusion cflock ドキュメントをお読みください。
簡略化されていますが、非常にまれな状況で不正確な結果が得られる場合があります
コード内でインライン化を行うIsDefined
と、誤検知の可能性が生じますが、IsDefined
内部に udf または cfc メソッドを配置すると、このリスクが大幅に軽減され、考慮する必要がなくなる可能性があります。そのチャンスを喜んで利用する場合はIsDefined
、Peter Boughton が提案するように関数を単純化できます。
<cffunction name="Exists" access="public" output="false" returntype="boolean">
<cfargument name="Key" required="true" type="string">
<cflock scope="session" type="readonly" timeout="3">
<cfset local.Exists = IsDefined("Session." & Arguments.Key)>
</cflock>
<cfreturn local.Exists>
</cffunction>