Yesterday, while writing data transfer scripts to move data from an MS Access database into a MySQL database, I came across a problem that I had not faced before. In the Access database, all of the phone extensions where broken out into their own fields. In the new database, there were no phone ext fields so as part of the data translation, the phone number and phone extensions needed to be concatenated. This seemed like a simple enough translation and I wrote code like this to take care of it:
<!--- Set phone and ext. In reality, these values would be coming out of a data base or input form (over which we do not have control). ---> <cfset strPhone = "(123) 456-7890" /> <cfset strExt = "128" /> <!--- Create full phone number complete with base number and line extension. ---> <cfset strFullPhone = ( strPhone & IIF( Len( strExt ), DE( " x#strExt#" ), DE( "" ) ) ) /> <!--- Output new number. ---> #strFullPhone#
This simply takes the number and extension and if there is a an extension, it appends it to the phone number but prepends " x" to it (the extension). Running the above code, we get the following output:
(123) 456-7890 x128
This worked fine, until I hit a phone extension with a "#" in it:
If the extension contained this hash, ColdFusion would throw the following error:
Invalid CFML construct found on line 1 at column 8. ColdFusion was looking at the following text:<p>\"</p><p> The CFML compiler was processing: <ul><li>An expression that began on line 1, column 4.<br>The expression might be missing an ending #, for example, #expr instead of #expr#.<li> An expression beginning with \", on line 1, column 1. This message is usually caused by a problem in the expressions structure.</ul>
The problem here is that ColdFusion's IIF() doesn't just evaluate the passed in expressions right away - it uses a double (delayed) evaluation. Therefore, when it goes to evaluate the passed in argument for the second time, it appears as if it contains a ColdFusion expression that is malformed (missing the closing hash symbol).
I tried to mess around with the way in which the IIF() statement was executed, but no combination or existence of DE() and quotes would get this error to go away (other than when I produced a different error altogether). The only thing that I could do was to double the hash signs in the phone extension so that they would be escaped in the second evaluation:
<!--- Set phone and ext. In reality, these values would be coming out of a data base or input form (over which we do not have control). ---> <cfset strPhone = "(123) 456-7890" /> <cfset strExt = "##128" /> <!--- Create full phone number complete with base number and line extension. ---> <cfset strFullPhone = ( strPhone & IIF( Len( strExt ), DE( Replace( " x#strExt#", "##", "####", "all" ) ), DE( "" ) ) ) /> <!--- Output new number. ---> #strFullPhone#
This is not pretty, but it is all I could come up with without actually doing a CFIF / CFELSE statement. If anyone has a better fix, please let me know. Looking at the work-around, it would have been much more simple to just use a CFIF / CFELSE statement, but this was actually part of a CFQueryParam tag value attribute (so, you can't use other tags in there).
Want to use code from this post? Check out the license.