PHP и MySQL: при использовании mysqli-> prepare () теряется значение zerofill - PullRequest
0 голосов
/ 26 июля 2011

Использование: MySQL 5.1 + PHP 5.3.5

MySQL:

id in "table" is defined as: mediumint(6) zerofill not null

Я получаю ожидаемый результат при использовании:

$mysqli->query("SELECT id FROM table WHERE id = 1");
while($row = $ret->fetch_array(MYSQLI_ASSOC)) $arr[] = $row;
>>> $arr[0]["id"] = 000001

Но не когда яиспользуйте подготовленный оператор:

$ret = $mysqli->prepare("SELECT id FROM table WHERE id = ?");
call_user_func_array(array($ret,"bind_param"),array("i",1));
$ret->execute();
$ret->store_result();
$meta = $ret->result_metadata();
$fields = $meta->fetch_fields();
$cols = array(); $data = array();
foreach($fields as $field) $cols[] = &$data[$field->name];
call_user_func_array(array($ret, 'bind_result'), $cols);
while($ret->fetch()) {
    $row = array();
    foreach($data as $key => $val) $row[$key] = $val;
    $arr[] = $row;
}
>>> $arr[0]["id"] = 1

При попытке подготовить оператор непосредственно в консоли MySQL, он показывает, как ожидалось (это не MySQL).

Согласно PHP mysqli_stmt ::bind_result документация Я нашел это:

В зависимости от типов столбцов связанные переменные могут молча перейти на соответствующий тип PHP.

Мне нужно показать число сконечные нули без необходимости делать это на более позднем этапе.С нулевым заполнением есть так много полей, и процесс практически автоматизирован от данных до экрана, поэтому попытка исправить это после этого кода потребует изменений мэра.

Любой намек на решение этой проблемы приветствуется.

Ответы [ 3 ]

1 голос
/ 04 ноября 2014

Zerofill теряется, потому что mysqli знает, что столбец имеет тип integer, и поэтому тип переменной php становится также int, и поэтому ведущие нули теряются.

Это, кажется, происходит только тогда, когда выиспользуйте подготовленные операторы с mysqli (кажется, что PDO не имеет такого поведения).

Чтобы предотвратить mysqli, тип переменной на целое, вы должны изменить тип в MySQL на что-то, что возвращается в виде строки.

Существует два способа:

  1. CAST(intCol AS CHAR) переводит целое число, включая первые нули, в строку.
  2. Использование целого числа с нулем в строковом контексте, например CONCAT(intCol, "").

Примечание: если вы используете это значение в поле ввода HTML5 типа number, это также удалит начальные нули (по крайней мере, в некоторых браузерах).Чтобы решить эту проблему, взгляните на этот ответ .

0 голосов
/ 26 июля 2011

Другим решением было указать поле как десятичное (6,0). По какой-то причине он работает как положено (никаких изменений в коде не требуется).

0 голосов
/ 26 июля 2011

Временно я решил это, добавив следующие строки:

define("ZEROFILL_FLAG",64);
$zeros = array();
foreach($fields as $field) {
    $zeros[$field->name] = $field->flags & ZEROFILL_FLAG ? $field->length : 0;
    $cols[] = &$data[$field->name];
}   
call_user_func_array(array($ret, 'bind_result'), $cols);
while($ret->fetch()) {
    $row = array();
    foreach($data as $key => $val) {
        $row[$key] = $zeros[$key] > 0 ? sprintf('%0'.$zeros[$key].'s', $val) : $val;
    }   
    $arr[] = $row;
}  

Тем не менее, я надеюсь, что кто-то может показать мне лучший способ решить эту проблему.

...