PHP intval () странные результаты

Я встречаюсь с чем-то странным, и я не знаю, почему это происходит!

У меня есть URL-адрес:

http://mysite.com/users/ USER_ID

этот идентификатор пользователя может быть INT и может быть STRING , это что-то вроде адресов страниц Facebook, если вы вызываете страницу с идентификатором страницы, который она загружает, вы также можете назвать ее с именем страницы, например «my_page_name»,

Итак, представьте себе, что пользователь, которому он равен 1 и его адрес – my_name На моей php-странице мне нужен запрос db, но перед этим мне нужно знать, какой столбец искать, id или page_name

Поэтому я пришел с таким решением:

 <?php $id = $_GET['id']; $id_inted = intval($_GET['id']); if($id == $id_inted){ // 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'); ?> 

Поэтому я тестировал его, но результаты были странными, даже если я называю этот URL:

http://mysite.com/users/ page_name

Это происходит: $column = 'id';

Я открыл новую тестовую страницу:

 <?php $real_string = 'abcdefg'; $string_inted = intval($real_string); echo "Real String is: " . $real_string . "<br />"; echo "The same string as int is: " . $string_inted . "<br />"; if($real_string == $string_inted) echo "Weird!"; else echo "Fine..."; ?> 

и результаты:

 Real String is: abcdefg The same string as int is: 0 Weird! 

Почему это происходит?

Заранее спасибо.

Related of "PHP intval () странные результаты"

PHP действительно «подключен» с так называемым манипулятором типа. Это наиболее подверженная ошибкам часть большинства PHP-скриптов. Таким образом, вы всегда должны оставаться на безопасной стороне и использовать самую надежную проверку. Например, intval("twelve") вернет 0, что является действительным целым числом. Но также считается «ложным»: print if (intval("one")) ? "yup" : "nope" print if (intval("one")) ? "yup" : "nope" напечатает «nope».

В этом случае использование intval в сочетании с проверкой, если целое число больше нуля, должно сделать трюк:

 <?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'); ?> 

Или, короче:

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

Aso обратите внимание, что $ _GET ["id"] не может быть установлен, что вызовет уведомление в вашем коде.

И последнее, но, конечно, не в последнюю очередь: SQL-инъекция ?id=LittleBobby';Drop table users

Как замечает комментатор, в моем коде есть логический недостаток, связанный с тем, что я тестировал его только в phpsh . Я реорганизовал его с использованием is_int() для intval и > 0 . В веб-среде $ _GET ["id"] всегда является строкой; не важно что. Следовательно is_int() всегда возвращает FALSE .

Чтобы проверить, запрашивается ли числовое значение, используйте is_numeric .

PHP немного странный, когда дело касается типов.

В основном, то, что вы делаете, это разбор строки на число (поэтому 'abcdef' возвращает 0, потому что это не номер вообще), а затем сравнивает исходную строку с номером.

Теперь я могу понять, почему вы предполагаете, что это должно быть ложным, но PHP пытается быть умным. В принципе, == будет принуждать типы и почти всегда прибегает к номерам, если одно из его значений – это число. Таким образом, он использует то же преобразование, что и в строке, а затем сравнение.

Лучше использовать === который также проверяет типы.

С 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. 

Ваша строка заливается в целое число из-за манипуляции типа в операторе == и intval() строки возвращает 0

Это объясняет, почему $id == $id_inted в вашем коде оценивается как true.

Если вы сделаете свой тест с === вместо == не будет выполняться жонглирование.

Целое значение var для успеха, или 0 при ошибке. Пустые массивы возвращают 0, возвращаются непустые массивы 1. (Из php.net intval () .)

intval ('abcdefg') вызовет ошибку, а функция вернется с 0.