-2

So right now I'm making a simplistic login system. The client enters the form data and the php handles it by checking a text file that goes like so:

name
pass
name
pass
...so on

The php I'm using to process this is:

$name = $_REQUEST['name'];
$pass = $_REQUEST['pass'];
$validName = false;
$validPass = false;
$pos = 0;

$file_handle = fopen("database.txt", "r");

while (!feof($file_handle)) {

    $line = ltrim( fgets($file_handle), "\n" );

    if ($pos % 2 == 0 ) // Checks for names first on even rows
    {
        if( strcmp( $name, $line))// Normal checking returns correctly
            $validName = true;
    }
    else if( $validName === true ) // if odd, and a matching name check pass
    {
        if( !strcmp( $pass, $line) )// What's going on here? Why is it opposite?
        {
            $validPass = true;
        }
        break;
    }
    $pos++;
}

What's happening is that the first check if( strcmp( $name, $line)) checking if there is a name in the data base that matches the input from the client.

This correctly returns true when the clients name matches a name in the data base. I check the password the EXACT same way, but some how it returns false when it's suppose to be true, and returns true when it's suppose to be false.

What's going on here?

On a side note, I'm only using strcmp because I couldn't get $name === $line to work.

Andrew
  • 3,393
  • 4
  • 25
  • 43
  • `strcmp` returns `0` if the strings are equal. So `if (strcmp($name, $line))` will execute the next statement if `$name` and `$line` are not equal. It does not return true or false. See the [online doc for strcmp](http://www.w3schools.com/php/func_string_strcmp.asp) – lurker May 02 '14 at 01:56
  • @lurker Thanks, I just read that in the manual. But for some reason, in order for me to get the values to return correctly I now have to set them up like this : `if( !strcmp( $name, $line) == 0 )`. That makes no sense. – Andrew May 02 '14 at 02:08
  • For equality, you should do `if(strcmp($name, $line) == 0)`, or `if ( !strcmp($name, $line) )`. But not a combination of both. If you don't like how the second one looks, use the first one. :) – lurker May 02 '14 at 02:25
  • @lurker That is what I originally thought .. I did the `(strcomp(a,b) == 0)` but that didn't get the correct results .. – Andrew May 02 '14 at 03:34
  • @lurker solved it completely. There's was more fault on my side and that's why the comparisons weren't completely correct. – Andrew May 02 '14 at 04:07

3 Answers3

3

strcmp() returns an integer, not a boolean. In fact, it returns 0 if the strings match, which would evaluate to false in an if-statement. That is why it appears to have "reverse" behavior compared to a typical boolean function.

See the documentation.

Daniel
  • 1,920
  • 4
  • 17
  • 35
  • thank you. I sort of saw that, but didn't fully realize it. Why does the first check work then is the real question now. – Andrew May 02 '14 at 02:00
  • Read the [documentation](http://php.net/manual/en/function.strcmp.php) and compare the result with an integer, instead of trying to treat it as a boolean. e.g. `strcmp(...) < 0` – Alex.Ritna May 02 '14 at 02:11
  • @Lemony-Andrew I couldn't say without seeing the values of each variable. Try `var_dump()`ing both of them and I'm sure you'll spot the difference. It may be extra whitespace that you can't see so ensure their lengths are the same. Also note that `strcmp()` is case-sensitive. – Daniel May 02 '14 at 02:14
  • @Daniel Further to your answer, for completion sake it's worth mentioning it's case sensitive (along with that a case insensitive function exists), and the return values are integers and should be compared with integers (`strcmp(...) < 0` or `strcmp(...) === 0`). – Alex.Ritna May 02 '14 at 02:24
  • @Daniel That's what I first used to compare the values but the value returned by `$_REQUEST` didn't have anything written about it with the var_dump() function. Also, I got something working now but still iffy about the subject. – Andrew May 02 '14 at 03:37
0

According to your code, it is not exact same way, but rather opposite:

    if( strcmp( $name, $line))
    if( !strcmp( $pass, $line))
user58697
  • 7,808
  • 1
  • 14
  • 28
0

Looks like there was a bigger problem then I thought.

There was 2 problems.

1, As Daniel explained perfectly

2, There was an extra character at the end of each line which threw off all comparisons. So to fix this I deleted the end of the line and now everything's working.

while ( !feof($file_handle) ) 
{

    $line = ltrim( fgets($file_handle) );
    $line = substr($line, 0, -1);/// This gets rid of the extra character

    if ( ($pos % 2) == 0 )
        $validName = ( $name === $line );// compares with ===, which is faster then strcmp
    else if( $validName )
    {
        $validPass = ( $pass === $line );
        break;
    }

    $pos++;
}fclose($file_handle);
Andrew
  • 3,393
  • 4
  • 25
  • 43