I just got this email this morning and had to share it:
I am converting from ASP to coldfusion but having troubles with code dealing with querystrings.I have the code:
<cfif parameterexists(URL.edit) AND URL.edit NEQ "">
<cfquery name="accountrecord" datasource="datasource">
SELECT *
FROM Admin
WHERE adID = #URL.edit#
</cfquery>Now I think coldfusion still tries to see if URL.Edit is defined for the sql statement although the if statement says only execute code if URL.edit value is present.
How do I fix this problem?
First off - welcome to the Light Side! I have some bad news for you. Now that you are leaving ASP you are going to need to find something else to do with your time once you start finishing your projects in a good tenth of the time it took you in ASP. (As you can see, I'm more than just a little bit biased towards ColdFusion. ;)
So - I had a hard time understanding the exact nature of your question. It sounds like you are saying the query is executing even when the url variable does not exist. While I have problems with your code (which I'll explain in a second), the logic at least seems right. Are you sure you aren't having some other problem?
That being said - let me pick apart your code a bit and point out some problems. First - forget about parameterExists(). You may have missed this in the docs, or seen it in use in other people's code, but it is deprecated. That just means you shouldn't use it. Instead, you want to use isDefined()*. Note that isDefined works a bit differently. Instead of:
parameterExists(name)
You use:
isDefined("name")
Notice the quotes? I'd rewrite your cfif like so:
<cfif isDefined("url.edit") and url.edit neq "">
Now another problem. I see you are using the value as a number in your query. You need to check and ensure that the value is a number. ColdFusion provides a function for that, isNumeric(). However, even that isn't enough. Don't forget the 3.14159 is also a number, but your database will be desiring a whole number. You can either check for that or simply round the number. That way if the number is changed by some unscrupulous user, it will still be ok for the query. ColdFusion provides a few functions that can get rid of anything after the decimal: round, fix, int, and ceiling. Any of these are fine.
Still with me? Notice how you use the variable inside your query? There is one more step you can do and that is to use cfqueryparam. This tag does a few things: One, it makes the query run a bit faster. Speed is always good. The best thing it does, however, is add one more layer of validation. It will double check to make sure your value really is the correct type. I'd check the docs for more information on the tag. Here is one more rewrite of your code.
Before I post the code though - please remember that there are many ways to skin the cat in ColdFusion. Consider this a suggestion. You don't have to write the code exactly as I have it.
<cfif isDefined("url.edit") and isNumeric(url.edit)>
<cfquery name="accountrecord" datasource="datasource">
SELECT *
FROM Admin
WHERE adID = <cfqueryparam cfsqltype="cf_sql_integer" value="#int(url.edit)#">
</cfquery>
- So just a quick note. As I said - there are multiple ways of doing things in ColdFusion. While isDefined certainly works well enough to check for the existence of a variable, some people use structKeyExists instead. Now - I don't want to confuse you, so feel free to stop reading now. The basic idea is that all variable scopes in ColdFusion are structures. I'm not sure what the equivalent is in ASP, but I'm sure it has something similar. (Basically an array indexed by strings, not numbers.) Because all the scopes can be treated as a struct, you can change an isDefined("url.edit") to structKeyExists(url, "edit"). You will see some of my readers suggesting that instead of isDefined(). Myself - I'm slowly moving to that form as well, so now my code will sometimes use both methods.
Archived Comments
Good Entry Ray! Nice to see ASPer's moving to CF!
I don't know much about ASP but my company uses a Help Desk based on ASP and when I looked at the code to try to fix a problem... forget it. I'm in the process of rebuilding the whole application in Coldfusion 7 with charts, printable reports and even a couple of flash forms a la ASFusion.
oh man, I got on a rant and forgot my question... what is the advantage to structKeyExists over IsDefined?
Help desk app? Have you seen Lighthouse Pro? :)
You opened the door Ray.
We use lhp for our helpdesk and our maintenance department uses it for their workorders. Not perfect and certainly not what it was intended for but it sure beat me having to make one.
That said, we needed a couple of extra fields added to make it work for us along with a few other kludges.
Nice to have in LHP:
The name and email address of the person submitting the 'bug'. (not creationism but two fields with text in them)
The ability to send status change emails to the user that submitted the bug, remember that person more than likely will not be in user table.
Reports, bean counter type stuff, how many tickets closed, how many submitted, how many by location, blah blah
my ADD just kicked in so I'm out.
thanks what you do.
Michael beat me to it. Would StructKeyExists be better than isDefined? I use that for Form and Url variable checks or is the reasoning behind using isDefined() taht those structures are not created if ColdFusion does not find any such corresopnding values in the request?
I've heard various reasons, one is speed (although I'm not too concerned with that), the other is that it just looks better, and is more appropriate. I'm sure my readers will chime in. As I said, I'm slowly changing myself and find myself liking it as well.
your lighthouse pro is a good software development/lifecycle helpdesk but my company's main focus is installation & repair of Networks, servers, workstations, projects for installing hardware, asset management. I think it would be easier to steal some of your ideas and add the features to my application than to modify yours to fit my needs. I could go through the whole history but...
It's all good Michael, I was just teasing.
I will say this, using isdefined() is faster than using StructKeyExists().
If you don't believe me, that's fine. Run a test where you run a loop 10,000 times for each one and see who comes out in front a majority of the time.
<cfset variables.start = gettickcount()>
<cfloop index="i" from="1" to="10000">
<cfset isdefined("url.testingthisout")>
</cfloop>
<cfset variables._isdefined = gettickcount() - variables.start>
<cfset variables.start = gettickcount()>
<cfloop index="i" from="1" to="10000">
<cfset StructKeyExists(url, "testingthisout")>
</cfloop>
<cfset variables._StructKeyExists = gettickcount() - variables.start>
<cfoutput><p>isdefined: #variables._isdefined# ms<br>StructKeyExists: #variables._StructKeyExists# ms<br></p></cfoutput>
Now grant it I will say one other thing. If you noticed the difference in performace between the two are minimal at best. That said, use which ever one you feel comfortable with. If you are having performace issues with your CF app, I would bet to say that using StructKeyExists isn't the reason and more likly it is a poorly designed database.
Here are my results from your exact code after running 2X. My test was writen inside an existing application, with a decent size application.cfm file preceding it.
isdefined: 109 ms
StructKeyExists: 63 ms
further F5's gave me stuff closer to 30ms, with a few MS difference in favor of structKeyExists.
I started writing the explanation, but recalled a blog or post by Mike Nimer on the subject. I couoldn't find his, but I found one by Sean Corfield
http://corfield.org/blog/in...
Let me just say that - in general - I'm not too keen on speed tests. I don't mean folks should ignore speed - but difference in 20-30 ms are typically not going to matter. That being said, Sean made a good point about how CF looks up when using isDefined. I'd say that is good enough reason.
OMG, I just spend all this time responding to the Sean Corfield blog when it said that the entry was too old to add any more comments!
The last comment said that isDefined was a security risk, so in my mind that would justify looking for an alternative.
But I don't think that it is.
I don't think there's a security risk with isDefined.
The only thing surprising about the following code is the very last line outputs your url variable if you call
www.MySite.com/mypage?SESSI...
But IF YOU HAD A SESION VARIABLE, it would output it correctly.
[cfdump var="#url#"]
[cfdump var="#Session#"]
[cfif isDefined("Session.Username")]
I'm getting hacked! Ack!
[/cfif]
[cfif StructKeyExists(url,"Session.UserName")]
Someone's trying to hack me!
[/cfif]
[cfoutput]#Session.UserName#[/cfoutput]
But just to reiterrate,
[cfif isDefined("Session.Username")]
is NOT a security risk if someone posts
www.MySite.com/mypage?SESSI...
Any problems in doing the following:
<cfparam default="0" name="url.edit" type="numeric">
<cfif url.edit neq 0>
...
</cfif>
I don't understand why people are so adverse to using structKeyExist(). I much prefer it over isDefined.
Because it doesn't read well.
"If it's defined, then..." vs.
"If the struct key exists, then that means it's been defined..."
well Sean puts it to rest for me (Sean's picture on his blog looks like it should be stamped on a coin). Come on Ray, let's make the switch!
Between Tony and Russell this sort of brings up another point... getting conflicting results from the exact same piece of code seems strange. Maybe someday we'll come up with some standard environment for this sort of thing or maybe some genius will come up with "How to turbo-charge your Coldfusion server and applications", "Coldfusion for Speed-Freaks" or some-such title.
Michael -I am making the switch - just slowly. :)
[cfif ISDEFINED("URL.EDIT") AND IsNumeric(URL.EDIT)]..
is wrong, if url.edit is undefined, an error will occur trying to evaluate the second part of the IF.
it should be
[cfif ISDEFINED("URL.EDIT")]
[cfif isNumeric(url.edit)]
...
[/cfif]
[/cfif]
T
That is not true.
Tim - CF will not evaluate the second condition of an AND pair if the first one is False (because if either is False the final result is False).
Similarly with ORs - if the first condition is True, it doesn't evaluate the second condition (because if either is True the final result is True).
You're right.
i just tested this on my new cf7 box, but it failes on my older cf6 box.
must be something new, i have tried this in the past and it has came back to haunt me. sorry for the premature post
regards
t
The conditional logic works as Peter explained on my CF6 box at work so it is not something new to CF7.
Coldfusion fails
Bob fails to provide any context and well wonder what he really means...