如何在PHP中生成学生证学号?怎么避免使用goto函数?
问题描述:
我想生成一个唯一的学生证学号。我想要的格式是年份的最后两位数字,再加上5位数字。例如:2000001、2000002、2000003 等。
以下是我的php代码:$pre = substr(strval(date("Y")),2);
$num = 1;
include "dbh.inc.php";
$sql_cmd = "SELECT id FROM students WHERE id=?;";
$stmt = $conn->stmt_init();
if ($stmt) {
$prepare = $stmt->prepare($sql_cmd);
if ($prepare) {
bind:
$studentid = $pre . str_repeat('0', (4 - strlen($num)) ) . strval($num);
$bind = $stmt->bind_param('s', $studentid);
if ($bind) {
$result = $stmt->execute();
if ($result) {
$num++;
goto bind;
}
else {
// insert student here using $studentid
}
}
}
}
我觉是上面代码需要改进:
1.使用goto,我不想用这个函数.
2.每次代码开始,绑定,执行等在每个循环中查询数据库带来很大的性能开销,显然很慢。
是否有更好的方法呢?
回答:
1.可以在MySQL端生成新的学生证ID。include "dbh.inc.php";
$sql =
"SELECT CONCAT("
. "DATE_FORMAT(CURDATE(), '%y'), "
. "LPAD(COALESCE(MAX(RIGHT(id, 5)) + 1, 1), 5, '0')"
. ") AS new_id "
. "FROM students";
$result = $conn->query($sql);
if ($result) {
if ($row = $result->fetch_assoc()) {
// insert student here using $row['new_id']
}
}
2.使用触发器,在插入数据时创建触发器。DELIMITER //
CREATE TRIGGER students_tr_bi BEFORE INSERT ON students
FOR EACH ROW
BEGIN
SET NEW.id = (
SELECT CONCAT(
DATE_FORMAT(CURDATE(), '%y'),
LPAD(COALESCE(MAX(RIGHT(id, 5)) + 1, 1), 5, '0')
) FROM students
);
END//
DELIMITER ;
-- Usage:
INSERT INTO students (name) VALUES ('John');