Целочисленное поле MySQL возвращается как строка в PHP - PullRequest
104 голосов
/ 16 марта 2011

У меня есть поле таблицы в базе данных MySQL:

userid INT(11)

Итак, я звоню на мою страницу с таким запросом:

"SELECT userid FROM DB WHERE name='john'"

Затем для обработки результата я делаю:

$row=$result->fetch_assoc();

$id=$row['userid'];

Теперь, если я сделаю:

echo gettype($id);

Я получаю строку. Разве это не должно быть целым числом?

Ответы [ 13 ]

117 голосов
/ 16 марта 2011

Когда вы выбираете данные из базы данных MySQL, используя PHP, тип данных всегда будет преобразован в строку. Вы можете преобразовать его обратно в целое число, используя следующий код:

$id = (int) $row['userid'];

Или с помощью функции intval():

$id = intval($row['userid']);
68 голосов
/ 05 сентября 2014

Используйте mysqlnd (собственный драйвер) для php.

Если вы используете Ubuntu:

sudo apt-get install php5-mysqlnd
sudo service apache2 restart

Если вы находитесь на Centos:

sudo yum install php-mysqlnd
sudo service httpd restart

Собственный драйвер возвращает целочисленные типы соответственно.

Edit:

Как указал @Jeroen, этот метод будет работать только из коробки для PDO.
Как указал @LarsMoelleken, этот метод будет работать с mysqli, если вы также установите для параметра MYSQLI_OPT_INT_AND_FLOAT_NATIVE значение true.

Пример:

$mysqli = mysqli_init();
$mysqli->options(MYSQLI_OPT_INT_AND_FLOAT_NATIVE, TRUE);
17 голосов
/ 15 июля 2014

Мое решение состоит в том, чтобы передать результат запроса $rs и получить ассоциированный массив приведенных данных в качестве возврата:

function cast_query_results($rs) {
    $fields = mysqli_fetch_fields($rs);
    $data = array();
    $types = array();
    foreach($fields as $field) {
        switch($field->type) {
            case 3:
                $types[$field->name] = 'int';
                break;
            case 4:
                $types[$field->name] = 'float';
                break;
            default:
                $types[$field->name] = 'string';
                break;
        }
    }
    while($row=mysqli_fetch_assoc($rs)) array_push($data,$row);
    for($i=0;$i<count($data);$i++) {
        foreach($types as $name => $type) {
            settype($data[$i][$name], $type);
        }
    }
    return $data;
}

Пример использования:

$dbconn = mysqli_connect('localhost','user','passwd','tablename');
$rs = mysqli_query($dbconn, "SELECT * FROM Matches");
$matches = cast_query_results($rs);
// $matches is now a assoc array of rows properly casted to ints/floats/strings
15 голосов
/ 23 февраля 2017

Самое простое решение, которое я нашел:

Вы можете заставить json_encode использовать фактические числа для значений, которые выглядят как числа:

json_encode($data, JSON_NUMERIC_CHECK) 

(начиная с PHP 5.3.3).

Или вы можете просто привести свой идентификатор к int.

$row = $result->fetch_assoc();
$id = (int) $row['userid'];
13 голосов
/ 16 марта 2011

Нет.Независимо от типа данных, определенных в ваших таблицах, драйвер MySQL PHP всегда обслуживает значения строк в виде строк.

Вам необходимо преобразовать свой идентификатор в int.

$row = $result->fetch_assoc();
$id = (int) $row['userid'];
5 голосов
/ 17 февраля 2015

Мне нравится ответ Чада, особенно когда результаты запроса будут переданы в javascript в браузере.Javascript четко обрабатывает числовые подобные сущности как числа, но требует дополнительной работы для обработки числовых похожих сущностей как строк.то есть я должен использовать parseInt или parseFloat для них.

Основываясь на решении Чада, я использую это, и это часто именно то, что мне нужно, и создает структуры, которые могут быть закодированы в JSON для удобства работы в javascript.*

Добавление числовой строки в 0 создает числовой тип в PHP и правильно определяет тип, чтобы числа с плавающей запятой не были усечены до целых чисел.

2 голосов
/ 06 мая 2018

Это происходит, когда для соединения PDO::ATTR_EMULATE_PREPARES установлено значение true.

2 голосов
/ 15 июня 2013

Вы можете сделать это с ...

  1. mysql_fetch_field ()
  2. mysqli_result :: fetch_field_direct или
  3. PDOStatement :: getColumnMeta ()

... в зависимости от расширения, которое вы хотите использовать. Первое не рекомендуется, потому что расширение mysql устарело. Третий еще экспериментальный.

Комментарии в этих гиперссылках хорошо объясняют, как установить тип из простой старой строки в исходный тип в базе данных.

Некоторые структуры также абстрагируют это (CodeIgniter предоставляет $this->db->field_data()).

Вы также можете делать догадки - например, циклически проходить по полученным строкам и использовать is_numeric () для каждой. Что-то вроде:

foreach($result as &$row){
 foreach($row as &$value){
  if(is_numeric($value)){
   $value = (int) $value;
  }       
 }       
}

Это превратит все, что выглядит как число в одно ... определенно не идеально.

2 голосов
/ 03 января 2012

В моем проекте я обычно использую внешнюю функцию, которая «фильтрует» данные, полученные с помощью mysql_fetch_assoc.

Вы можете переименовать поля в своей таблице, чтобы было интуитивно понятно, какой тип данных хранится.

Например, вы можете добавить специальный суффикс к каждому числовому полю: если userid является INT(11), вы можете переименовать его userid_i или, если это UNSIGNED INT(11), вы можете переименовать userid_u. На этом этапе вы можете написать простую функцию PHP, которая получает в качестве входных данных ассоциативный массив (полученный с помощью mysql_fetch_assoc) и применяет приведение к «значению», сохраненному с этими специальными «ключами».

1 голос
/ 14 февраля 2018

В моем случае mysqlnd.so расширение было установлено.НО у меня не было pdo_mysqlnd.so.Итак, проблема была решена заменой pdo_mysql.so на pdo_mysqlnd.so.

...