• (cs) in reply to W. Snapper
    W. Snapper:
    I just did this on a recent project, to find the status of account applications. Their database had both "Approved" and "approved," "declined" and "Declined," etc.

    Why would I not simply omit the first letter? And for those who are somehow claiming clarity, is there anyone who didn't instantly understand the code?

    status = "Reclined". Now what?
  • (cs) in reply to G
    G:
    because -1 is perfectly legal argument, for example, start or length of a substring (php.net/substr) therefore to prevent people from shooting their leg and not realizing it by directly using its return value as a parameter to another function...
    That is why God created the IF.
  • (cs) in reply to Val
    Val:
    Stop kidding! ('f...ggot' also suits well).

    Val, stop being such a pussy. It's not Putin's Rissia. Nobody will come after you and accuse in "inflaming of religious or national conflict". Freedom of speech, you know. You can say plainly "queer" and "faggot", you, ebutchiy pidoraz.

  • califa (unregistered) in reply to G
    G:
    because -1 is perfectly legal argument, for example, start or length of a substring (php.net/substr) therefore to prevent people from shooting their leg and not realizing it by directly using its return value as a parameter to another function, ie substr($s, 0, strpos($s, '%')) will return 'a' for 'a%b', but 'ab' for 'abc' having strpos return false will issue a warning, under normal circumstances

    do not criticize something you haven't throughoutly researched

    Except it doesn't issue a warning (with error_reporting(E_ALL) )...

    On the other hand, many (most of?) php functions don't check for the type of the arg, making 0,'',FALSE,NULL interchangeable.

    And, to me, this:

    substr($s, 0, strpos($s, '%'))

    is plain wrong, since it assumes that there's a '%' character in the string in the first place, which is a wild assumption, in my opinion.

  • An Old Hacker (unregistered) in reply to G
    G:
    because -1 is perfectly legal argument, for example, start or length of a substring (php.net/substr) therefore to prevent people from shooting their leg and not realizing it by directly using its return value as a parameter to another function, ie substr($s, 0, strpos($s, '%')) will return 'a' for 'a%b', but 'ab' for 'abc' having strpos return false will issue a warning, under normal circumstances

    do not criticize something you haven't throughoutly researched

    Actually, this is only the negative reason (which alone would be enough). The positive reason is that it allows

    z = strpos(x,y) if(z) {}

    If your library returns -1, you end up with if(z == -1). This is bad because it looks like an integer compare. As others have mentioned, maintainability is the first rule of software design, and every time someone's brain has to recalibrate, maintainability is lost.

    There are some advantages for a -1 return. But I would prefer false.

  • An Old Hacker (unregistered) in reply to Andy Goth
    Andy Goth:
    Nick Johnson:
    Actually, there's a pseudo-plausible reason to do this: strpos(blah, "pider") matches both "spider" and "Spider".
    Yeah, sometimes I do the same trick (leave off the first character) if I don't know what case it will be in. For example, CHAT scripts. "ogin:", "assword:" Hehehe, assword. :^)

    STOP IT! YOU'RE MAKING BY BRAIN HURT!

    The reason we use "ogin:" and "assword" in CHAT scripts is because the first character would often be DROPPED! I've seen this in my log scripts.

    And that is the ONLY reason to drop the first character--if in fact the resulting substring is a known valid response. (Then you still have to deal with 0 != false.)

  • (cs) in reply to WhiskeyJack
    WhiskeyJack:
    Andy Goth:
    For example, CHAT scripts. "ogin:", "assword:" Hehehe, assword. :^)

    You mean buttword.

    Well done, sir!
  • James (unregistered) in reply to G
    G:
    because -1 is perfectly legal argument, for example, start or length of a substring (php.net/substr) therefore to prevent people from shooting their leg and not realizing it by directly using its return value as a parameter to another function, ie substr($s, 0, strpos($s, '%')) will return 'a' for 'a%b', but 'ab' for 'abc' having strpos return false will issue a warning, under normal circumstances

    do not criticize something you haven't throughoutly researched

    Here's the thing: your example is a WTF -- you really, really should be checking for and explicitly handling the case where there's no "%" in the string instead of letting it "issue a warning" -- what does that even mean?

    And giving a negative length to substr should also generate an error, so whether it returns "-1" or "false", substr should bomb out.

    I'm not a language designer by trade, so I can't give you a 10-paragraph justification why my "shoulds" are right, but I use languages all the time and have an intrinsic sense of good and bad design. And writing functions with multiple return types when there's a perfectly good invalid set to assign errors to (e.g. negative "lengths") is in fact a WTF.

  • ChrisB (unregistered) in reply to Dave
    Dave:
    Staggers me the amount of PHP developers who never heard of stristr(), including all commenters here, it seems.
    Of course, if you Read The Fine Manual for strstr, you'll find the following message:
    Note: If you only want to determine if a particular needle occurs within haystack , use the faster and less memory intensive function strpos() instead.
    One assumes that the same applies to the case-insensitive versions of these functions.
  • thc (unregistered)

    strpos is a great example of why PHP is one of the worst languages ever created and why everyone who has the slightest understanding of good programming stays as far away from this cancer as possible.

  • (cs) in reply to James
    James:
    And giving a negative length to substr should also generate an error, so whether it returns "-1" or "false", substr *should* bomb out.

    If length is given and is negative, then that many characters will be omitted from the end of string (after the start position has been calculated when a start is negative). If start denotes a position beyond this truncation, an empty string will be returned.

  • Anon (unregistered)

    TRWTF is that it can't tell the difference between Google and Foogle, Boogle, Doogle, Ioogle, Soogle, etc.

  • (cs)

    Here's a much simpler spider detection routine, which I use all the time:

    if (strpos($_SERVER['HTTP_USER_AGENT'], '+http') === false)

    Every well-behaved spider puts a URL, prefixed with +, into the user-agent, to give information about said spider. Any spider which isn't well-behaved is likely to spoof itself as something else entirely. Ergo, it's only worth worrying about ones which put the +http indicator into the UA.

  • sobani (unregistered) in reply to WhiskeyJack
    WhiskeyJack:
    Andy Goth:
    For example, CHAT scripts. "ogin:", "assword:" Hehehe, assword. :^)

    You mean buttword.

    hmm... I wonder if there ever has been a story about bugs that were caused by spell checking the source code...

  • Steve (unregistered)

    Admittedly, having rarely used PHP for anything, I find the real WTF here to be that the operator === even exists.

    = : assignment == : is equal test === : is really f****ng equal test

    I can guarantee that most developers originating from other languages who are forced into the realm of PHP will similarly trip over this oddity. Reading about this whole affair caused me to have the same pained grimace as when I work in Perl.

  • (cs) in reply to powerlord
    powerlord:
    failues
    That's a great substitute for "failure values"... :)

    np: Caribou - Niobe (Andorra)

  • (cs) in reply to An Old Hacker
    An Old Hacker:
    The reason we use "ogin:" and "assword" in CHAT scripts is because the first character would often be DROPPED! I've seen this in my log scripts.
    Oh, I hadn't thought of that. That's good to know, thanks. It's been a while since I've actually had to use CHAT scripts.
    And that is the ONLY reason to drop the first character--if in fact the resulting substring is a known valid response. (Then you still have to deal with 0 != false.)
    Of course I was being facetious. Skipping the first character is a poor substitute for ignoring its case.
  • (cs) in reply to MET
    MET:
    Nikolai:
    Actually, this indicates that the developer knows what he is doing and tries to write the most efficient code possible (the kind of thing a lot of modern software engineers lack). Definitely not WTF.
    In my 13 years of experience a focus on efficiency first is always the mark of a n000b. After a while most realise that correctness and maintainability are almost always more important, and only a very few places need to coded as if every cycle counts. I agree a good developer should know how to code very efficiently, I just think they should know not to do so most of the time.

    I wouldn't say efficiency first is always wrong, but I don't consider the WTF to be "efficient". It's shorter, but a longer solution would be compiled to look much the same and the runtime difference would be negligible. The problem here is it doesn't quite do what he thinks it does, so he's put out a terse, hard to read code snippet that uses a non-standard method to come up with a probably correct-ish answer.

    To me THAT is unacceptable. Short and sweet is fine, but an obsession with brevity over accuracy is a problem, and this type of bug is a nasty bitch to fix because it's not going to fail every time.

  • (cs) in reply to Steve
    Steve:
    Admittedly, having rarely used PHP for anything, I find the real WTF here to be that the operator === even exists.

    = : assignment == : is equal test === : is really f****ng equal test

    I can guarantee that most developers originating from other languages who are forced into the realm of PHP will similarly trip over this oddity. Reading about this whole affair caused me to have the same pained grimace as when I work in Perl.

    They could, you know, look it up. Anyone who's seen a weakly-typed language won't be falling off their chair or anything when beholding an "equality plus type checking" operator.

  • califa (unregistered) in reply to thc
    thc:
    strpos is a great example of why PHP is one of the worst languages ever created and why everyone who has the slightest understanding of good programming stays as far away from this cancer as possible.

    I've been using php regularly for quick and dirty stuff for about 3 years and, for me, it works great for that (I'm not saying you can't build more complex stuff, I'm just describing how I use it).

    What bugs me about it is that most php fanatics can't acknowledge that some things are a bit f****d up with it. When I find such a case, I usually go to the manual, read the user's comments, generally find a way around it and move on. But why would anyone say that an odd, counterintuitive design (or sometimes a plain bug) is a good feature?

    The strings API is a good example of this. Almost all functions are marked as "binary safe", as if it were a carefully thought out feature, added there for your convenience. And in fact, binary safe just means that the API is braindead about strings encodings, and just treats them as arrays of bytes, which admitedly, is not the behaviour you'd expect for string manipulation in a high level language.

    Say you're using utf-8 and you have this:

    strpos('añb','b');

    It will return 3, not 2. WTF? If you understand what's going on under the hoods, you can see that in binary, using utf-8, 'añb' is 0x61,0xc3,0xb1,0x62. 4 bytes, not 3 characters. (But isn't the goal of a high language to abstract away from you what's under the hoods and let you deal with more "abstract" concepts?)

    So if you do:

    strpos('añb',0xb1);

    You'd get 2, instead of FALSE. Isn't this a WTF?

    Later, they added some hooks (hacks?) to alleviate the problem, like mb function overloading (to hook up the mb_string API), but you can't really rely on that, because you don't necessarily control it.

    So, back to my point, I can deal with most of these WTF's and find some way around them, but don't tell me they're nice, well thought features. Most of them are either bad design, inherited crap from legacy code you cannot change without breaking a lot of stuff or plain bugs.

  • m0ffx (unregistered) in reply to Steve
    Steve:
    = : assignment == : is equal test === : is really f****ng equal test
    ==== : is genuinely, truly, ultimately, indisputably, beyond all reasonable doubt equal test
  • Mr. (unregistered) in reply to heise
    heise:
    He he, that's funny.

    Still, I'm not sure what surprised me more: a) The "ingenuity" of developer. b) That the function can return "0" AND "FALSE" and that's not the same. c) That "strpos" is not appropriate function for searching substrings inside string.

    It doesn't. It returns FALSE, but if you use "==" it is the same as comparing with 0 (borrowed from C)

    If you really want to use a boolean test, you use "===" and "!=="

  • Vowels (unregistered) in reply to Jonathan
    Jonathan:
    Val:
    And one more thing: 'pider' is kind of 'q...er' in Russian :(

    Quaker? Or can I buy a vowel?

    Yep. You can have the u' which comes right after theq'. Does that help?

  • W. Snapper (unregistered) in reply to dpm

    it couldn't be. All the states were known. If you're writing code that tests the validity of every single read from the database every place you use it, then you're doing it wrong.

  • (cs) in reply to AT
    AT:
    brodie:
    In your mind, a "good developer" should know that they shouldn't write efficient code most of the time?

    I'm sure glad you don't work with me. We obviously have extremely different views on what makes a "good" developer. Writing inefficient code "most of the time" is not the hallmark of a "good developer."

    Really? So in other words, you don't evaluate the trade-offs between clarity and efficiency (where they diverge) on a case-by-case basis and choose the solution that best your overall design goals? You just always choose efficiency without regard to the problem, technology, or environment at hand?

    I'm glad I don't work with you!

    Oh ZING. Man, you sure got me there!

    Unfortunately for you, strawmen arguments don't get you very far in the real world. I never said anything about what I do. I just said that automatically writing inefficient code from the get-go (as MET claimed) is not the sign of a good developer. A good developer evaluates the needs and trade-offs of each project as it comes, and doesn't deal in absolutes and "most of the times."

    But go ahead and keep putting words into other people's mouths so that you don't have to tax your obviously overstressed brain on coming up with a logical argument based on what was actually said. It seems to work for you.

  • Wonko (unregistered) in reply to fmobus

    [quote user=fmobus]Stop being lazy and just do what TFM tells you to: if (strpos($needle,$haystack) === true) {}[/quote] I have no idea which manual you might refer to here but it is definitly not the php manual. You got the argument order wrong (it's $haystack, $needle) and strpos() will never return true. It will return the position of $needle in $haystack or false if it is not there.

    So I suggest you stop being lazy and read the fine manual before giving the arrogant smartass next time.

  • Jay (unregistered) in reply to biziclop
    biziclop:
    Gustav:
    I agree with all of you who say that PHP is a poor language. I mean, that's why Facebook, Wikipedia, Yahoo!, Digg, Sourceforge and Flickr are built on it, right?

    If you feel yourself inferior because you are a PHP developer that's not our fault. :)

    Hey, go easy on the poor guy. You don't know what it's like when you try to get into a night club and the bouncer says, "Hey, aren't you the guy who programs in a WEAKLY-TYPED language? We don't like your kind here."

  • Jay (unregistered) in reply to dpm
    dpm:
    W. Snapper:
    I just did this on a recent project, to find the status of account applications. Their database had both "Approved" and "approved," "declined" and "Declined," etc.

    Why would I not simply omit the first letter? And for those who are somehow claiming clarity, is there anyone who didn't instantly understand the code?

    status = "Reclined". Now what?

    So if a new browser hits the market that's named "Foogle" or "Yebcrawler", this code will break. I'd take a bet on the odds of that happening any time soon.

  • Anon. (unregistered) in reply to m0ffx
    m0ffx:
    Steve:
    = : assignment == : is equal test === : is really f****ng equal test
    ==== : is genuinely, truly, ultimately, indisputably, beyond all reasonable doubt equal test
    is syntax error.
  • (cs) in reply to Jay
    Jay:
    dpm:
    status = "Reclined". Now what?
    So if a new browser hits the market that's named "Foogle" or "Yebcrawler", this code will break. I'd take a bet on the odds of that happening any time soon.
    Oh, excellent. I deeply admire programmers who "bet" instead of just writing maintainable code.
  • tungsten (unregistered) in reply to ParkinT

    Sorry, but copyrights are nothing to do with trademarks and trademarks do not provide any entitlement to extract, "usage fees."

    Trademark law exists solely to prevent confusion in the marketplace and does not confer any ability to control the usage of the trademark, unless such usage would cause confusion.

    If you're interested in the subject, perhaps the most entertainingly pedantic series of cases would be the several Apple vs. Apple disputes in the U.K.

    For U.S.A. case law, Google is a good start: the number of failed suits against Google's adwords is quite startling.

    They all failed on the same point: having a trademark does not confer control of the term unless confusion would occur.

  • (cs) in reply to W. Snapper
    W. Snapper:
    I just did this on a recent project, to find the status of account applications. Their database had both "Approved" and "approved," "declined" and "Declined," etc.

    Why would I not simply omit the first letter? And for those who are somehow claiming clarity, is there anyone who didn't instantly understand the code?

    (1) aaar! (2) ay!

    Doesn't seem to work too well on Pirate Dialog Boxes ...

  • (cs) in reply to m0ffx
    m0ffx:
    Steve:
    = : assignment == : is equal test === : is really f****ng equal test
    ==== : is genuinely, truly, ultimately, indisputably, beyond all reasonable doubt equal test
    I myself prefer the simple and elegant "===~" regexp operator. I haven't found a use for it yet, but I'm a big fan of treating all corner cases in code by creating a new operator. It'll come in handy some day.
  • K (unregistered) in reply to m0ffx
    m0ffx:
    Steve:
    = : assignment == : is equal test === : is really f****ng equal test
    ==== : is genuinely, truly, ultimately, indisputably, beyond all reasonable doubt equal test

    Actually as far as I know, and I'm not a PHP programmer, PHP should actually have the third comparison operator because:

    == : is an equality test with type coercion === : is an equality test with type checking ==== : or some other operator would, be the actual identity check, that checks that the two variables are references to the same object

    Of course the correct solution would be (using the same operator syntax which IMHO is ugly):

    == : is an equality check without type coercion, all cross-type comparison results are false === : is an identity check, which checks that the two variables has the same memory address (or some other unique identity)

    But what can you except from programmers that see a type comparison table as the solution?

  • (cs) in reply to Dave

    In perl, you pass in one scalar haystack, and one scalar needle, and you get back one integer, which is -1 if the needle is not found.

    Now, if you were looking at the perl module someone coded to enhance this functionality, you'd almost certainly be almost correct.

    (The structure returned would probably be a hash of the haystacks within which needles were found, whose values were hashes of the needles found, whose values would be the locations in where they were found. And, like all of these modules, I'd never use them, because it's more legible to just simply use index each time one needs it, rather than gathering the huge mass of haystacks and needles and then parsing all the results after.)

  • Shuttenbah (unregistered)

    You know, "pider" in Russian is unprintable synonym of "gay".

  • Buddy (unregistered)

    If I had to maintain the code, say there's a problem with matching jahoo, I'd probably do this to ensure minimum change in code:

    $spider_footprint = array('googlebot', 'crawler', 'spider', 'gulliver', 'harvest', 'yahoo! Slurp');

    // Prepend with a dummy character to force strpos // to return > 0 for a match $normalizedAgent = '`' + strtolower($agent)

    foreach($spider_footprint as $spider_name) { if (strpos($normalizedAgent, $spider_name)) { $is_spider = 1; break; } }

    I like the '+http' method the best, though.

  • (cs) in reply to MET
    MET:
    Nikolai:
    Actually, this indicates that the developer knows what he is doing and tries to write the most efficient code possible (the kind of thing a lot of modern software engineers lack). Definitely not WTF.
    In my 13 years of experience a focus on efficiency first is always the mark of a n000b. After a while most realise that correctness and maintainability are almost always more important, and only a very few places need to coded as if every cycle counts. I agree a good developer should know how to code very efficiently, I just think they should know not to do so most of the time.

    While I agree that overly focusing on efficiency is the mark of a n00b, I certainly hope that you have some sense beyond that of your words.

    A good programmer, by my definition, will write legible code which is reasonably efficient most of the time. When it matters, a good programmer will spend a bit more time writing legible code which is rather efficient. When it's critical, a good programmer may spend a lot more time to write crufty code which is hyper efficient.

    The above coding sample did not strive for legibility, did not include comments pointing out the reasoning for what was done, did not result in a significant performance savings, and was not positioned in a critical inner loop, so wasn't even eligible for 'hyper efficient coding'.

    I've seen quite a few programmers who may be good by your standards, as they paid first attention to code legibility, but they failed along one or more of the below points:

    1. Use of very inefficient code. For example, using a shell escape to perform string manipulation, math, or simple logic tests.

    2. Coding something in a non-performance critical section so poorly that it became a performance critical section.

    For example, coderA wrote in perl a character by character (using substr) analysis of an SQL query to ensure no malicious or otherwise inappropriate code was included. (My alternate code, for what it's worth, eliminated the bulk of the check, by collecting the possible set of desired queries, naming each of them, and having the form pass a string naming the query format, plus any data elements needed. The data elements were all SQL-escaped, allowing only '*' as a permissible meta-character.)

    1. Failing to optimize a performance-critical inner loop - or, possibly worse, performing step-wise optimization where an obvious algorithmic optimization exists.

    For example, in a perl program, three levels into a loop, coderB put a simple min-max sort to order the elements of a hash table. Optimizations attempted before I arrived included using lexical variables, turning off strict and warnings, and various similar fumblings. My first opto was to use sort (which, IMHO, also improved legibility); my second opto was to move it out of the three nesting loops. (The second opto was only second because it was more invasive, and it might have eliminated the need to fix his sort routine.)

    (Just in case it isn't clear from the above, I'm a fan of the '+http' test - it's reasonably efficient, it's quick to code, and it has good coverage over the problem space.)

    Note: I provided examples above regarding how I optimized some fairly broken code. This is not claiming I'm amazing for having figured this out - I'm sure there's better fixes. I'm just pointing out an answer which didn't require much work, and had a big enough impact.

  • (cs)

    Please, stop bitching about "===" or "$var". It's really simple and useful. It's the design of the language. Learn it or find another job, but please stop doing this! It's just a fucking tool! It exists in php, and been there for ages. MacGyver could use anything he had around to do everything he wanted, and it worked. You can't use php. You're not MacGyver. Every time I see a post about "===" or "ooh false is not zero", I feel superior, because I'm closer to MacGyver than some whiner. /rage

  • (cs) in reply to Shuttenbah
    Shuttenbah:
    You know, "pider" in Russian is unprintable synonym of "gay".
    Didn't you just print it?
  • (cs) in reply to real_aardvark
    real_aardvark:
    (1) aaar! (2) ay!

    Doesn't seem to work too well on Pirate Dialog Boxes ...

    hiver e imbers! elay hat alk, ate, r 'll ave e alkin' he lank, e wab!

  • Fred (unregistered) in reply to brodie

    apparently ad hominum does go very far in the real world though.

  • Noam Samuel (unregistered)

    Wouldn't that make $is_spider 1 if it's, say, Firefox, since -1 is considered positive?

  • Mr. (unregistered)

    I would just like to specify something about PHP

    The function does not return to return values. It returns a true boolean value. The only difference is how you compare it.

    When you use "==" you are doing it like C, since 0 == FALSE

    When you use "===" you have a true boolean test.

  • Val (unregistered) in reply to alegr
    alegr:
    Val:
    Stop kidding! ('f...ggot' also suits well).

    Val, stop being such a pussy. It's not Putin's Rissia. Nobody will come after you and accuse in "inflaming of religious or national conflict". Freedom of speech, you know. You can say plainly "queer" and "faggot", you, ebutchiy pidoraz.

    Sorry for offtopic but I don't give a fuck about fucking "Putin's Rissia". And about such clownery like "vaginaamericans", proposals to repaint White House in black becouse its white (sorry) and other "freedom".

  • Fedaykin (unregistered) in reply to brodie
    brodie:
    MET:
    I agree a good developer should know how to code very efficiently, I just think they should know not to do so most of the time.
    In your mind, a "good developer" should know that they shouldn't write efficient code most of the time?

    I'm sure glad you don't work with me. We obviously have extremely different views on what makes a "good" developer. Writing inefficient code "most of the time" is not the hallmark of a "good developer."

    I think the point (and a good one at that) is that a good developer writes code with the following (in order) priorities:

    1.) Is it correct 2.) Is it maintainable 3.) Is it efficient

    Of course, this priority list changes depending on the particular application (e.g. if you are writing a real time app efficient becomes second), but for most software, efficiency is less important than correctness and maintainability.

    This does not mean someone shouldn't write with efficiency in mind, but rather that when there is scarcity of development resources (e.g. time to get something done) and there is a choice between writing something efficiently and writing something correctly, the latter should take precedence.

  • emma (unregistered) in reply to m0ffx

    =====: this is starting to get misguided

  • Mike (unregistered)

    could be that he (wrongly or rightly) was worried about titlecase vs lowercase ... it looks like one of my lazy regular expressions. pider matches both spider and Spider

  • (cs) in reply to Val
    Val:
    alegr:
    Val:
    Stop kidding! ('f...ggot' also suits well).

    Val, stop being such a pussy. It's not Putin's Rissia. Nobody will come after you and accuse in "inflaming of religious or national conflict". Freedom of speech, you know. You can say plainly "queer" and "faggot", you, ebutchiy pidoraz.

    Sorry for offtopic but I don't give a fuck about fucking "Putin's Rissia". And about such clownery like "vaginaamericans", proposals to repaint White House in black becouse its white (sorry) and other "freedom".

    The "freedom" is: you can't get prosecuted for what you say, unless that a threat to inflict bodily injury. You can get fired, though, if you say derogatory/discriminatory remarks in your workplace. But this won't cause any criminal prosecution or civil liability for you. If you don't give a flying fuck about this, you don't know how is to live without that.

  • minty (unregistered) in reply to powerlord
    powerlord:
    Nick Johnson:
    Actually, there's a pseudo-plausible reason to do this: strpos(blah, "pider") matches both "spider" and "Spider".
    So does stripos(blah, "Spider") except that stripos also matches "sPider", "SPIDER", etc... I imagine it just uses strtolower or strtoupper on both strings first.

    I doubt strpos changes case just for comparison - if it did, that's another clbuttic WTF. Not only inefficient, but there are better ways to perform case insensitive substring comparisons. Calling ToLower() or ToUpper() then comparing will bite you depending on which locale you are in. (Turkish i's are one example IIRC)

Leave a comment on “pider Detection”

Log In or post as a guest

Replying to comment #:

« Return to Article