views:

58

answers:

5

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?

A: 

You can use IIF. It's cool.

<cfset id = IIf(IsDefined("URL.id") AND Int(URL.id), Int(URL.id), DE("0"))>
ppshein
artlung
I've not tested it, but IIF is widely regarded as an efficiency sink.
Ben Doom
What my advice is correct, please dun forget to tick my post as right answer. :)
ppshein
You 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()
Stephen Moretti
I don't think IIF make efficiency sink. Please let me specific information to proof about that problem.
ppshein
IMO, IIF is one of the most unreadable features of CFML -- this is enough to avoid using it.
Sergii
I 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.
Ken Redler
A: 

You might also look into cfparam.

<cftry>
  <cfparam name="url.id" default="0" type="integer">
<cfcatch>
  <!--- log? etc --->
  <cfset url.id = 0>
</cfcatch>
</cftry>
Ken Redler
Bad solution: put the invalid value in the `url.id` and you'll fire the exception, handling one looks like overhead here.
Sergii
Sergii, 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
A: 

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>
Anthony
While 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.
Adam Tuttle
+5  A: 

Recent versions of ColdFusion also have a ternary conditional operator:

<cfset id = (structKeyExists(URL, "id") and isNumeric(URL.id)) ? int(URL.id) : 0>
Rick O
Notes: `?:` wont work before CF8, also `isNumeric(url.id)` can be replaced with more strict `isValid("integer", url.id)`.
Sergii
for a cf8 version of this ---- variables.id = 0;if (structKeyExists(url,"id)
Stephen Moretti
+1  A: 

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).

See http://cfquickdocs.com/cf8/#Val

Al Everett