PHP会自动删除标识字符串中我需要的零

时间:2014-02-27 11:28:15

标签: php mysql

在表格中,主要字段是名为ribiid的Char(12)字段,其格式为RB##########

它需要自动增加它,为此我准备了以下代码:

function getid() {
   global $connection;
   $idquery = "SELECT ribiid FROM systems ORDER BY ribiid DESC LIMIT 1";
   $idsave = mysqli_query($connection, $idquery);
   $idresult = mysqli_fetch_assoc($idsave);
   $idalpha = substr($idresult['ribiid'], 0, 2);
   $idnumeric = substr($idresult, 2);
   $newidnumeric = $idnumeric + 1;
   $newid = $idalpha . $newidnumeric;
   return $newid;
}

现在进行测试我在cmd中用id = RB0000000000手动输入了一行,我使用php通过我的网页提交的下一个条目应该是RB0000000001,但它正在RB1。

我该如何解决这个问题,这是我的第一个网络数据库。感谢

3 个答案:

答案 0 :(得分:2)

您的问题是,在向$idnumeric添加1时,PHP需要将其视为一个数字。数字中的前导零没有意义,所以它们被丢弃了。

要保留零,您可以使用sprintf格式化生成的(递增的)数字:

$newid = sprintf("%s%010d", $idalpha, $newidnumeric);

但是,使用这样的代码不是一个好主意

此代码存在一个问题:它受竞争条件的影响。考虑如果脚本的两个实例并行运行会发生什么:

                Instance A                    Instance B
T  |
i  |            Reads ribiid RB..001          Reads ribiid RB..001
m  |            Generates next id RB..002     Generates next id RB..002
e  v            Writes RB..002 to DB
                                              Writes RB..002 to DB => OOPS

如您所见,由于使用了重复的主键,这种情况将导致实例B无法插入记录。要解决这个问题,您需要消除竞争条件,您可以通过以下几种方式之一来完成竞争:

  • 对PK使用AUTO_INCREMENT列,而不是手动插入值。虽然这意味着您不能再将“RB”前缀作为密钥的一部分,但可以将其移动到不同的列,并使PK成为这两列的组合。
  • 正在进行插入时
  • LOCK TABLES ribiid(请注意,锁需要覆盖所有进程,而不仅仅是getid函数)。锁定表是您通常想要避免的,但如果插入不频繁,则它是一种可用的实用解决方案。

答案 1 :(得分:0)

您可以尝试这样的事情:

$newid = $idalpha . str_pad($newidnumeric, 10, '0', STR_PAD_LEFT);

这将添加零以达到十个字符。

答案 2 :(得分:0)

您可以使用以下函数再次填充数字字符串:

function pad_number($number, $pad=10){
  $pad_zero = $pad - strlen($number.'');
  $nstr = '';
  for($i =0; $i< $pad_zero; $i++){
    $nstr .="0";
  }
  $nstr .= $number;
  return $nstr;
}

您可以在代码中使用此功能:

$newid = $idalpha . pad_number($newidnumeric);