X 116



  • Hello All,

     I was browsing through some PHP code my predessor wrote and found this gem

               if( strpos( strtolower( $_SERVER["HTTP_USER_AGENT"] ), "mozilla" ) ||
                  strpos( strtolower( $_SERVER["HTTP_USER_AGENT"] ), "firefox" ) ||
                  strpos( strtolower( $_SERVER["HTTP_USER_AGENT"] ), "safari" )
              ) {
                //echo '<td align="right" style="position: relative; left: -50px;">'; // FF this does not work
                echo '<td align="center">'; // FF
                  for( $i=0; $i<116; $i++ ) echo "&nbsp;";
              }
              else {
                echo '<td align="right" style="position: relative; left: -38px;">'; // IE
              }

    My IDE reports almost 44,000 warnings and 4,500 errors with the entire web site. I am sure to have bigger and brighter gems than this one.

     



  • I like that he lowercases the UA each time he checks.  Classy. 



  • A second, subtle, wtf..  All of the IE user agent strings I've seen start with "Mozilla x/0".

     



  • @ElizabethGreene said:

    A second, subtle, wtf..  All of the IE user agent strings I've seen start with "Mozilla x/0".

    strpos() returns the zero-indexed position of the search string.  Now, zero-based indexing is stupid (as noted in previous threads) but since zero evaluates as false in PHP, strpos('mozilla...', 'mozilla') will evaluate as false and IE will not enter into the first block.

     

    PHP's strpos() is particularly annoying, though, because it returns false if the string is not found (instead of -1), which means you have to do strpos('foo', 'bar') === false to check that the string doesn't actually exist.  I usually end up wrapping strpos() so it returns -1 for "not found".



  • @morbiuswilters said:

    Now, zero-based indexing is stupid (as noted in previous threads)
     

    Flamewar, GO!



  • @MiffTheFox said:

    @morbiuswilters said:
    Now, zero-based indexing is stupid (as noted in previous threads)
    Flamewar, GO!
    Not Quite.  This has been played out pretty well.



  •  I feel it is necessary to reference another piece of code related to strpos. Enjoy...

    function any2dec( $num, $base=35, $index=false ) {
      if( !$base ) {
        $base = strlen( $index );
      }
      else if( !$index ) {
        $index = substr( "0123456789ABCDEFGHIJKLMNPQRSTUVWXYZ", 0, $base );
      }

      $out = 0;
      $len = strlen( $num ) - 1;

      for( $t = 0; $t <= $len; $t++ ) {
        $out = $out + strpos( $index, substr( $num, $t, 1 ) ) * pow( $base, $len - $t );
      }

      return $out;
    }



  • @belgariontheking said:

    @MiffTheFox said:

    @morbiuswilters said:
    Now, zero-based indexing is stupid (as noted in previous threads)
    Flamewar, GO!
    Not Quite.  This has been played out pretty well.

    Has not!


  • @MiffTheFox said:

    @morbiuswilters said:

    Now, zero-based indexing is stupid (as noted in previous threads)
     

    Flamewar, GO!

    I propose a compromise: 0.5 based indexing.

    Seriously, different tasks call for different conventions (e.g. dates and strings should porbably be one-based)

    @Donald Knuth said:

    Who are you? How did you get in my house?

     



  • Indexed arrays and Associative arrays seem to solve all my problems. 

       



  • @samanddeanus said:

    @MiffTheFox said:

    @morbiuswilters said:

    Now, zero-based indexing is stupid (as noted in previous threads)
     

    Flamewar, GO!

    I propose a compromise: 0.5 based indexing.

    Seriously, different tasks call for different conventions (e.g. dates and strings should porbably be one-based)

    ISTR that consnsus was that whether 0 or 1 based indexing is best from a theoretical point of view, in practice the vast majority of programmers have learnt C at some point and are used to 0-based indexing, and so the minor annoyance which is caused by having to remember that this @!*%# language uses 1-based indexing could be the difference between a nice language but which is a little obscure and getting a critical mass of users to make the language viable for commercial use, meaning that all new languages are almost certainly going to choose 0-based indexing. Furthermore, would "not found" be 0 or -1, and what about searching from the end of a list backwards.



  • @Physics Phil said:

    ....... Furthermore, would "not found" be 0 or -1, and what about searching from the end of a list backwards.

    If all numbers are treated as true then "not found" should be the boolean false value, like it is in PHP. But since PHP doesn't treat all numbers as true that is why boolean false value is not found, is sometimes the problem (but is sometimes good it is like that), as noted.

    In BASIC, strings start at 1, but arrays can start at whatever you want it to start at.

    In Forth you can make anything to start at whatever you want it to start at. Also, if you make a function to search in string, in case it is zero-based, you could make it return two values on the stack if it is successful, boolean true on top and position directly underneath, or just the false value (zero) without anything underneath if it is not found. That way you can make something like (do search in string) IF (do something with found position) THEN you make it according to which way is better for whatever program you are trying to write. If strings are one-based and not-found is zero then you can write something like (do search in string) ?DUP IF (do something with found position) THEN



  • @zzo38 said:

    If all numbers are treated as true then "not found" should be the boolean false value, like it is in PHP. But since PHP doesn't treat all numbers as true that is why boolean false value is not found, is sometimes the problem (but is sometimes good it is like that), as noted.
     

    I personally think this "use index function to test presence of string location" is just stupid.  The optimal solution is a seperate function that simply checks for the presence of a string, then the index function would just throw an error when using an incorrect value.

    For example (In C#):

    public static bool Contains(this string haystack, string needle){

    return haystack.IndexOf(needle) > -1;

    }

    public static int IndexOfChecked(this string haystack, string needle){

    int index = haystack.IndexOf(needle);

    if (index >= 0) return index;

    else throw new SubstringNotFoundException();

    }



  • @MiffTheFox said:

    For example (In C#):

    public static bool Contains(this string haystack, string needle){

    return haystack.IndexOf(needle) > -1;

    }

    public static int IndexOfChecked(this string haystack, string needle){

    int index = haystack.IndexOf(needle);

    if (index >= 0) return index;

    else throw new SubstringNotFoundException();

    }

    You, sir, win +1 Evil Internets. 



  • @MiffTheFox said:

    @zzo38 said:

    If all numbers are treated as true then "not found" should be the boolean false value, like it is in PHP. But since PHP doesn't treat all numbers as true that is why boolean false value is not found, is sometimes the problem (but is sometimes good it is like that), as noted.
     

    I personally think this "use index function to test presence of string location" is just stupid.  The optimal solution is a seperate function that simply checks for the presence of a string, then the index function would just throw an error when using an incorrect value.

    For example (In C#):

    public static bool Contains(this string haystack, string needle){
    return haystack.IndexOf(needle) > -1;
    }

    public static int IndexOfChecked(this string haystack, string needle){
    int index = haystack.IndexOf(needle);
    if (index >= 0) return index;
    else throw new SubstringNotFoundException();
    }

    In many cases it is necessary to look for a substring, then do something on the substring if it was found, and some default action otherwise.  For example, Google's search: if a search term contains a colon, check the left side of the colon to see if it's an operator word.  If it is, add a special search condition.  If there's no colon, add the term to the words to search for.  I use similar logic in many of my programs.  Using separate contains / index_of_checked functions would cause two linear searches through the string.

    Here's an alternate proposal (in C++):

    using std::string; 

    bool find(const string &haystack, const string &needle, string::size_type &index)
    {
    index = haystack.find(needle);
    return (index!=string::npos);
    }

    The downside is that you'll have to declare an extra variable to store the result in, even if you just wanted to do a "contains" check.



  • the Contains already exists and does the same :p

    you could go with a:

    public static bool TryIndexOf(this string str, string value, out int index)
    {
    index = str.IndexOf(value);
    return index >= 0;
    }
    


  • @XIU said:

    the Contains already exists and does the same :p

    you could go with a:

    public static bool TryIndexOf(this string str, string value, out int index)
    {
    index = str.IndexOf(value);
    return index >= 0;
    }
    

     

    Correction:

    Contains(char) already exists.  Contains(string) would overload it.

    But yes, a out variable does seem to be the optimal solution.



  • Reflector only shows:

    public bool Contains(string value)
    {
        return (this.IndexOf(value, StringComparison.Ordinal) >= 0);
    }
    

    on the string class, the only way you would get Contains(char) is with Linq since the string is an IEnumerable<char>



  • @XIU said:

    Reflector only shows:

    public bool Contains(string value)
    {
        return (this.IndexOf(value, StringComparison.Ordinal) >= 0);
    }
    

    on the string class, the only way you would get Contains(char) is with Linq since the string is an IEnumerable<char>

     

    Hmm, MSDN says differently...



  • @MiffTheFox said:

    @XIU said:

    the Contains already exists and does the same :p

    you could go with a:

    public static bool TryIndexOf(this string str, string value, out int index)
    {
    index = str.IndexOf(value);
    return index >= 0;
    }
    

     

    Correction:

    Contains(char) already exists.  Contains(string) would overload it.

    But yes, a out variable does seem to be the optimal solution.

    Uhh... why are you guys talking like you are serious?



  • @MiffTheFox said:

    @XIU said:

    Reflector only shows:

    public bool Contains(string value)
    {
        return (this.IndexOf(value, StringComparison.Ordinal) >= 0);
    }
    

    on the string class, the only way you would get Contains(char) is with Linq since the string is an IEnumerable<char>

     

    Hmm, MSDN says differently...

    Yes it does. You are showing the extensions methods, which like I said are coming from the fact that string is an IEnumerable<char>



  • @XIU said:

    @MiffTheFox said:

    @XIU said:

    Reflector only shows:

    public bool Contains(string value)
    {
        return (this.IndexOf(value, StringComparison.Ordinal) >= 0);
    }
    

    on the string class, the only way you would get Contains(char) is with Linq since the string is an IEnumerable<char>

     

    Hmm, MSDN says differently...

    Yes it does. You are showing the extensions methods, which like I said are coming from the fact that string is an IEnumerable<char>

     

    Woah, you're right.  I just couldn't tell what MSDN was actually showing me.

    I guess the real WTF is MSDN. </obligitory>


Log in to reply