【问题标题】:Zerofill is lost when using mysqli->prepare()使用 mysqli->prepare() 时 Zerofill 丢失
【发布时间】:2011-10-13 02:20:48
【问题描述】:

使用: 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 类型。

我需要在后面的步骤中显示带有尾随零的数字,而不必这样做。 zerofill 的字段非常多,从数据到屏幕的过程实际上是自动化的,因此在此代码之后尝试修复此问题,将需要市长更改。

【问题讨论】:

    标签: php mysql mysqli prepared-statement zerofill


    【解决方案1】:

    暂时,我通过添加以下几行来解决它:

    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;
    }  
    

    我仍然希望有人能告诉我一个更好的方法来解决它。

    【讨论】:

      【解决方案2】:

      另一种解决方案是将字段指定为十进制(6,0)。由于某种原因,它按预期工作(无需更改代码)。

      【讨论】:

        【解决方案3】:

        zerofill 会丢失,因为 mysqli 知道该列是整数类型,因此 php 变量的类型也变为 int,因此前导零会丢失。

        这似乎只在您使用带有 mysqli 的准备好的语句时发生(PDO 似乎没有这种行为)。

        为了防止 mysqli 变量的类型为整数,您必须将 MySQL 中的类型更改为以字符串形式返回的类型。

        有两种方式:

        1. CAST(intCol AS CHAR) 将包含前导零的整数转换为字符串。
        2. 在字符串上下文中使用填零整数,例如CONCAT(intCol, "").

        注意:如果您在 number 类型的 HTML5 输入字段中使用此值,这也会去除前导零(至少在某些浏览器中)。要解决这个问题,请查看this answer

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-07-12
          • 2018-08-11
          • 1970-01-01
          • 1970-01-01
          • 2013-09-12
          • 2023-03-26
          • 2011-07-18
          • 1970-01-01
          相关资源
          最近更新 更多