Cast as integer in ColdFusion; sanitizing variables
Solution 1
I would use cfparam. I'd also scope explicitly, but that's not necessary. I wouldn't use the IIF() function, because it makes use of evaluate(), which can be problematic, I'd also avoid DE() for the same reason. In this case, it won't be an issue, but I avoid them on general principle in any situation where it's not absolutely necessary. I've been using CF for a few years now, and it hasn't been necessary yet.
<cfparam name="url.id" default="0" />
<cfif isNumeric(url.id)>
<cfset local.id = int(url.id) />
<cfelse>
<cfset local.id = 0 />
</cfif>
Solution 2
Recent versions of ColdFusion also have a ternary conditional operator:
<cfset id = (structKeyExists(URL, "id") and isNumeric(URL.id)) ? int(URL.id) : 0>
Solution 3
Apologies for raising an old thread but came up with this same question and found a simple solution that might help others with this issue
NumberFormat(URL.id)
There are also various masks that you can specify in different scenarios
ColdFusion Reference
A formatted number value:
If no mask is specified, returns the value as an integer with a thousands separator. If the parameter value is "" (an empty string), returns 0.
http://help.adobe.com/livedocs/coldfusion/8/htmldocs/help.html?content=functions_m-r_08.html
Solution 4
To me, the simplest way to ensure your variable is an integer is to wrap the variable in val().
It attempts to parse the string and extract any integer found (at the beginning of the string). If none is found it returns 0.
- If TestValue = "234A56?7'", Val(TestValue) returns 234.
- If TestValue = "234'5678'9?'", Val(TestValue) returns 234.
- If TestValue = "BG234", Val(TestValue) returns the value 0, (not an error).
- If TestValue = "0", Val(TestValue) returns the value 0, (not an error).
artlung
Programmer for hire | Indieweb | Toy robot collector | Bodysurfer | Respiratory | Bad drawing | Peace, love, resistance @artlung | [email protected] | artlung.com
Updated on June 24, 2022Comments
-
artlung almost 2 years
I'm rusty at ColdFusion, I've been used to PHP for so long. What I want to do is something like this:
<?php $id = (isset($_GET['id'])) ? (int)$_GET['id'] : 0; ?>
Basically, check for a url parameter called
id
and if it exists make sure it's an integer so I can safely use it in database queries. If it ends up zero, that's fine too.I have:
<cfscript> if (IsDefined("URL.id") AND IsNumeric(URL.id)) { id = int(URL.id); } else { id = 0; } </cfscript>
This is working, but is awfully messy. Is there a better way to do this?
-
artlung over 13 yearsYes! It's been a long time. I didn't recognize
DE
: adobe.com/livedocs/coldfusion/7/htmldocs/wwhelp/wwhimpl/common/… Thanks! Seems to be working nicely! -
Ben Doom over 13 yearsI've not tested it, but IIF is widely regarded as an efficiency sink.
-
PPShein over 13 yearsWhat my advice is correct, please dun forget to tick my post as right answer. :)
-
Stephen Moretti over 13 yearsYou can't use IIF in this instance. IIF evaluates all parts everytime. This means if you use this and URL.Id doesn't exist it will throw an error trying to process Int(URL.Id) in the second part of IIF()
-
PPShein over 13 yearsI don't think IIF make efficiency sink. Please let me specific information to proof about that problem.
-
Adam Tuttle over 13 yearsWhile your solution is not wrong, I think Rick O's is more elegant and closer to the original question; so I'm down-voting you to bump his up, at least for now.
-
Sergey Galashyn over 13 yearsBad solution: put the invalid value in the
url.id
and you'll fire the exception, handling one looks like overhead here. -
Sergey Galashyn over 13 yearsNotes:
?:
wont work before CF8, alsoisNumeric(url.id)
can be replaced with more strictisValid("integer", url.id)
. -
Sergey Galashyn over 13 yearsIMO, IIF is one of the most unreadable features of CFML -- this is enough to avoid using it.
-
Stephen Moretti over 13 yearsfor a cf8 version of this ---- variables.id = 0; if (structKeyExists(url,"id) && isValid("integer",url.id)) variables.id = url.id;
-
Ken Redler over 13 yearsSergii, I understand where you're coming from, but as to whether it's "bad," I think it depends. If having an empty or malformed
url.id
does in fact constitute an exception in his app, I think it's fair to handle it as such (i.e. within a try/catch block, where it can be logged, handled, etc). "Swallowing" the exceptional behavior by specifically programming for it conditionally works, of course, although it blurs the line between an exception and an expected operating state of the app. -
Ken Redler over 13 yearsI don't think this warrants a downvote -- it is after all a language feature (albeit ugly), in the precise spirit of the first php snippet, and older versions of CF don't have the ternary operator.
-
Leigh about 9 yearsEvery situation is different, but a couple things worth noting.
NumberFormat
is really designed for presentation. Technically, it returns a string, not an integer. Also, it throws an exception when passed a non-numeric value. So it does not satisfy all of the requirements of the original question, ie sanitize the value (and verify the variable exists).