Convert PHP foreach loop to ColdFusion

advertisements

I have the PHP Code which is using a foreach loop to loop over and create a query. I am trying to convert that into ColdFusion, but am getting lost. Can someone show the way how that can be done?

if ($deps) {
    $num = count($deps);
    $i = 0;
    $addon = " AND (";
    foreach ($deps as $dep) {
        $addon .= " DEPARTMENT_ID='{$dep['dep']}'".($num != ++$i ? ' OR': '');
    }
    $addon .= ")";
} else {
    // Has been assigned no departments, so they can't see any tickets
    $addon = " AND (DEPARTMENT_ID='-1')";
}


Here is the PHP translated directly to CFML, that is: with as few changes as required to make it compile and run:

<cfscript>
    if (isDefined('$deps')) {
        $num = ArrayLen($deps);
        $i = 0;
        $addon = " AND (";
        for ($dep in $deps) {
            $addon &= " DEPARTMENT_ID='#$dep['dep']#'"&($num NEQ ++$i ? ' OR': '');
        }
        $addon &= ")";
    } else {
        // Has been assigned no departments, so they can't see any tickets
        $addon = " AND (DEPARTMENT_ID='-1')";
    }
</cfscript>

Here is an screenshot of a diff showing what has changed:

The changes are:

  • Need isDefined to check for non-null value.
  • ArrayLen instead of count to get size of an array.
  • foreach ( Y as X ) translates to for ( X in Y )
  • Use & and &= for concatenation, instead of . and .=
  • PHP uses {braces} when a bracket notation var is inside a string - for a single variable it could have just been $varname directly and would be evaluated. In CFML you use #hashes# to put variable's values in a string.

Note that CF lets you use != in script, but NEQ must be used in tag-based code (cfif/cfset).

Also note that, whilst PHP requires variables to start with a $ sign, CFML does not care either way, so they don't strictly need to be removed (even if they are ugly noise).


Here is the same concept done in a simpler way:

<cfscript>
    if ( NOT isDefined('deps') )
        deps[1] = {dep=-1};

    addon = [];
    for ( dep in deps )
        ArrayAppend(addon," DEPARTMENT_ID='#dep.dep#'");

    addon = " AND (#ArrayToList(addon,' OR')#)";
</cfscript>

And here's an example of how similar code could work with cfqueryparam instead:

<cfscript>
    if ( isDefined('deps') )
    {
        depIds = [];

        for ( dep in deps )
            ArrayAppend(depIds,dep.dep);
    }
    else
    {
        depIds = [-1];
    }
</cfscript>
<cfquery>
    ...
    <cfif ArrayLen(depIds) >
        AND DEPARTMENT_ID IN (<cfqueryparam list value=#ArrayToList(depIds)# cfsqltype="cf_sql_integer" />)
    </cfif>
</cfquery>

(Proper code would of course use better variable names and appropriate scoping.)