使用 mysqli->prepare() 时 Zerofill 丢失
使用: 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 类型。
我需要显示带有尾随零的数字,而不必在后续步骤中执行此操作。有很多字段都带有零填充,并且从数据到屏幕的过程实际上是自动化的,因此尝试在此代码之后修复此问题将需要进行重大更改。
Using:
MySQL 5.1 + PHP 5.3.5
MySQL:
id in "table" is defined as: mediumint(6) zerofill not null
I get the expected result when using:
$mysqli->query("SELECT id FROM table WHERE id = 1");
while($row = $ret->fetch_array(MYSQLI_ASSOC)) $arr[] = $row;
>>> $arr[0]["id"] = 000001
But not when I use prepared statement:
$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
When trying the prepared statement directly in the MySQL console, it shows as expected (it is not MySQL).
According to PHP mysqli_stmt::bind_result documentation I found this:
Depending on column types bound variables can silently change to the
corresponding PHP type.
I need to show the number with the trailing zeros WITHOUT having to do it in a later step. There are so many fields with zerofill and the process is practically automated from the data to the screen, so trying to fix this after this code, will require mayor changes.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
Zerofill 丢失了,因为 mysqli 知道该列的类型为整数,因此 php 变量的类型也变为 int,因此前导零丢失。
这似乎只在您将准备好的语句与 mysqli 一起使用时才会发生(PDO 似乎没有这种行为)。
为了防止 mysqli 将变量的类型更改为整数,您必须将 MySQL 中的类型更改为以字符串形式返回的类型。
有两种方法:
CAST(intCol AS CHAR)
将包含前导零的整数转换为字符串。CONCAT(intCol, "")
。注意:如果您在
number
类型的 HTML5 输入字段中使用此值,这也会去除前导零(至少在某些浏览器中)。要解决此问题,请查看此答案。The zerofill gets lost, because mysqli knows that the column is of type integer and so the type of the php variable becomes also int and so the leading zeros get lost.
This seems only to happen when you use prepared statements with mysqli (PDO seems not to have this behavior).
To prevent mysqli the type of the variable to integer you have to change the type in MySQL to something that is returned as a string.
There are two ways:
CAST(intCol AS CHAR)
casts the integer including the leading zeros to a string.CONCAT(intCol, "")
.Notice: If you use this value in an HTML5 input field of type
number
, this will also strip off leading zeros (at least in some browsers). To solve this problem have a look at this answer.暂时,我解决了这个问题,添加了这些行:
我仍然希望有人能告诉我一个更好的方法来解决它。
Temporally, I solved it adding these lines:
Still I hope someone can show me a better way to solve it.
另一个解决方案是将字段指定为decimal(6,0)。由于某种原因,它按预期工作(不需要更改代码)。
Another solution was to specify the field as decimal(6,0). For some reason it works as expected (no changes to the code required).