动态循环 URL 个参数

Dynamically looping through URL parameters

我正在尝试编写一些代码来循环遍历 URL 参数,这些参数以单词 'layer' 开头,后跟 1、2、3 等。例如:

http://example.cfm?numLayers=2&layer1=somevalue,123&layer2=someothervalue,456

URL中的层数每次都会不同。

这是我的代码:

<cfif isDefined("url.numLayers") AND url.numLayers gt 0>
    <cfset session.structLayers = structNew() />
    <cfloop index="index" from="1" to="#url.numCustom#">
        <cfset layerElement = evaluate(url.layer#index#) /><!--- This is where I'm having trouble --->
        <cfset arrLayerElement = listToArray(layerElement)>
        <structInsert(session.structLayers, arrLayerElement[1], arrLayerElement[2])]>
    </cfloop>
</cfif>

我在上面标记的行上收到 'Invalid CFML construct error'。我这样做不对。

您可以尝试以下操作。首先,使用 structKeyExists() 而不是 isDefined()。您会看到更好的性能:

<cfset numLayers = 0 />
<cfif structKeyExists(url, "numLayers")>
    <cfset numLayers = val(url.numLayers) />
</cfif>

此外,您不再需要使用 evaluate()

<cfset session.structLayers = {} /> <!--- instead of "structNew()" --->
<cfloop from="1" to="#numLayers#" index="ii">
    <cfif structKeyExists(url, "layer#ii#")> <!--- instead of evaluate --->
        <cfset arrLayerElement = listToArray(url["layer#ii#"]) />
        <cfset structInsert(session.structLayers, arrLayerElement[1], arrLayerElement[2]) />
    </cfif>
</cfloop>

你也可以这样做:

<cfloop collection="#url#" item="mylayer">
    <cfif REFindNoCase("^layer\d+$", mylayer) AND listLen(url.mylayer) EQ 2>
        <cfset structInsert(session.structLayers, listFirst(url.mylayer), listLast(url.mylayer) />
    </cfif>
 </cfloop>

我在编写这段代码时意识到并不真正需要对 listToArray() 的调用。如果您要在循环外再次使用该数组,那么我完全赞成,但由于您只使用了一次,然后就再也没有引用过它,因此可能不值得这么麻烦。

您可以使用数组访问器语法(方括号)来处理结构中的动态键:

<cfif structKeyExists(url,"numLayers") AND url.numLayers gt 0>
    <cfset session.structLayers = {} />
    <cfloop index="index" from="1" to="#url.numCustom#">
        <!--- use this instead of evaluate to get dynamic keys out of a struct --->
        <cfset var layerElement = url["layer#index#"] />
        <!--- same way to set a dynamic key into a struct --->
        <cfset session.structLayers[listFirst(layerElement)] = listLast(layerElement) />
    </cfloop>
</cfif>

您可以试试这个简单的代码。只需将 session_struct 替换为您自己的结构即可。您可以附加此 URL 进行测试:

?numLayers=5&layer1=Layer1Key,Layer1Value&layer2=Layer2Key,Layer2Value

<cfif StructKeyExists(url, "numLayers") and url.numLayers gt 0>
    <cfloop list="#StructKeyList(url)#" index="key">
        <cfif ReFindNoCase("^layer", key)>
            <cfset StructInsert(session_struct, ListGetAt(url[key], 1), ListGetAt(url[key], 2))>
        </cfif>
    </cfloop>
</cfif>

<cfdump var="#session_struct#">