PHP intval() weird results

前端 未结 5 1132
无人及你
无人及你 2020-12-20 06:26

I\'m encountering something weird and I don\'t know why it is happening!

I have a URL like:

http://mysite.com/users/USER_ID

this user id

相关标签:
5条回答
  • 2020-12-20 07:03

    PHP is a little odd when it comes to types.

    Basically, what you are doing is parsing the string into a number (so 'abcdef' returns 0 because it isn't a number at all), then comparing the original string to the number.

    Now, I can see why you would assume that it should be false, but PHP tries to be clever. Basically, == will coerce types, and almost always coerces to numbers if one of it's values is a number. So it is using the same conversion that you did on the string, then comparing.

    It is a better idea to use === which also checks types.

    0 讨论(0)
  • 2020-12-20 07:03

    From http://php.net/manual/en/language.operators.comparison.php

    Example       Name        Result
    
    $a == $b      Equal       TRUE if $a is equal to $b after type juggling.
    
    $a === $b     Identical   TRUE if $a is equal to $b,
                              and they are of the same type. 
    

    Your string is casted to integer because of type juggling on == operator and intval() of a string returns 0

    This explains why $id == $id_inted in your code evaluates to true.

    If you make your test with === instead of == no type juggling will be performed.

    0 讨论(0)
  • 2020-12-20 07:12

    PHP is really "wired" with so called type-juggling. It is the most error-prone part of most PHP-scripts. As such, you should always stay on the safe side and use the most robust check. For example intval("twelve") will return 0, which is a valid integer. But also considered "false": print if (intval("one")) ? "yup" : "nope" will print "nope".

    In this case, using intval, in combination with a check if the integer is larger then zero, should do the trick:

    <?php
    $id = intval($_GET['id']);
    
    if($id > 0){
      // The column which I should look into is id
      $column = 'id';
    }else{
      // The column which I should look into is page_name
      $column = 'page_name';
    }
    
    $query = mysql_qyery(SELECT * FROM members WHERE $column = '$id');
    ?>
    

    Or, shorter:

    $id = intval($_GET['id']);
    
    $column = ($id > 0) ? "id" : "page_name";
    $query = mysql_qyery(SELECT * FROM members WHERE $column = '$id');
    

    Aso note that $_GET["id"] might not be set, which would throw a notice in your code.

    And last, but certainly not least: the SQL-injection: ?id=LittleBobby';Drop table users.

    edit As commentor points out, there was a logical flaw in my code, stemming form the fact I tested it in phpsh only. I refactored it from using is_int() to intval and > 0. In a web-environment, $_GET["id"] is always a string; no matter what. Hence is_int() will always return FALSE.

    0 讨论(0)
  • 2020-12-20 07:12

    To check if numeric value is requested, use is_numeric.

    0 讨论(0)
  • 2020-12-20 07:15

    The integer value of var on success, or 0 on failure. Empty arrays return 0, non-empty arrays return 1. (From php.net intval().)

    intval('abcdefg') will trigger an error and the function return with 0.

    0 讨论(0)
提交回复
热议问题