0

I want to generate a unique student ID. The format that I want is the last two digits of the current year plus 5 digits after that. For example: 2000001, 2000002, 2000003.. etc.. This is the extract of my code right now.

$pre = substr(strval(date("Y")),2);
$num = 1;
include "dbh.inc.php"; // this file merely creates the $conn variable that connects to mysql database.
$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
            }
        }
    }
}

But I need to improve this because:

  1. It uses a goto (I want to avoid it)
  2. It seems overkill to prepare, bind, execute, etc everytime and query the database every loop.
  3. It is obviously slow.

Please let me know if there is a better way of doing this.

astigmatik
  • 134
  • 1
  • 8
  • 5 numbers will only give you a max of 99,999 rows per year. Are you sure you want to limit yourself to this? – waterloomatt Dec 06 '20 at 03:35
  • 1
    You can use a normal _auto-increment_ field and simply add a prefix (20, 21, 22, etc.) by using a trigger. https://stackoverflow.com/a/17894239/296555 – waterloomatt Dec 06 '20 at 03:36
  • the number of students per year is not that many. and the first two digits will always change to the current year. so that is not an issue. if i use AI, how do I pad it with the zeros? – astigmatik Dec 06 '20 at 03:58
  • 1
    Use LPAD to pad with 0. – waterloomatt Dec 06 '20 at 04:04
  • @waterloomatt the link that you gave gives me another option. cheers. – astigmatik Dec 06 '20 at 07:58
  • You can have a sequence table to store last used integer per year and populate it for the next century. You then just need to increment the appropriate value every time you fetch one. The tricky bit is to ensure consistency on concurrent accesses. – Álvaro González Dec 07 '20 at 14:03
  • I’m voting to close this question because this type of question is better for Code Review Stack Exchange rather than Stack Overflow. – user16217248 Aug 01 '23 at 05:51

2 Answers2

1

You can generate new id on the MySQL side:

include "dbh.inc.php"; // this file merely creates the $conn variable that connects to mysql database.

$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']
    }
}

Or another option is to create an trigger on insert:

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');
id'7238
  • 2,428
  • 1
  • 3
  • 11
  • Good idea. You should probably add some more details for OP about how to create the initial ID. Is it auto-increment? – waterloomatt Dec 06 '20 at 03:32
  • In this case, the identifier is not auto-increment. It can be generated through a trigger with a similar query. – id'7238 Dec 06 '20 at 04:00
  • Just a question, but does this run the risk of collisions? If 2 or more users hit this script at the same time will it return the same `MAX(id)` number and therefore generate the same _next_ id for all of them? – waterloomatt Dec 06 '20 at 04:05
  • @waterloomatt, trigger on insert deals this it. And id is still the primary key. – id'7238 Dec 06 '20 at 04:15
  • @user14717238 tq. i need to study your answers first. i'm not very good with mysql.. i assume that for the trigger, i just enclose them in quotes (starting at CREATE TRIGGER and ending at END) and assign to a variable? – astigmatik Dec 06 '20 at 07:58
  • @astigmatik, either you can use the first part in your php script instead of your own code, or create once a trigger object from the second part without `INSERT` statement on the MySQL server side. This is not executed in the php script. – id'7238 Dec 06 '20 at 08:35
-1

Generate Student certificate in php mysql this code is useful to generate student certificate according to student id (data) in database

Points to remember before executing the code: 1.download fpdf library and include fpdf.php file 2.include your favourite font ttf file 3.Here we use php GD library : imagecreatefrom jpeg function

Most Important Point: Here we convert image into pdf then then place student data in certificate accordingly

<?php
require_once 'connection.php';
require 'assets/fpdf.php';
error_reporting(E_ALL);
ini_set('display_errors', 1);

  $id = $_GET['id'];  
  $franQuery   = "SELECT * FROM `certificate` where id=$id";
  // $franQuery   = "SELECT * FROM `certificate` where id=255";
  $franRecords = mysqli_query($con, $franQuery);
  $sr = 1;

  if($franRecords->num_rows>0){

    while ($row = mysqli_fetch_assoc($franRecords)) { 
      $font = __DIR__ . '/assets/Poppins-Bold.ttf';

      $image = imagecreatefromjpeg('assets/certificate.jpg');
      $color = imagecolorallocate($image,1,1,1);
      $name = $row['student_name'];
      $sondaugheroff = $row['sondaugheroff'];
      $school =  $row['school'];
      $marks_per = $row['marks_per'];
      $level = $row['level'];
      $cert_date = date('d/m/Y', strtotime($row['cert_date']));
      $place = $row['place'];
      $address = $row['address'];
      
      imagettftext($image,13,0,415,308,$color,$font,$name);
      imagettftext($image,13,0,175,340,$color,$font,$sondaugheroff);
      imagettftext($image,13,0,650,340,$color,$font,$school);
      imagettftext($image,13,0,480,375,$color,$font,$marks_per);
      imagettftext($image,13,0,160,410,$color,$font,$level);
      imagettftext($image,13,0,390,465,$color,$font,$cert_date);
      imagettftext($image,13,0,1030,465,$color,$font,$place);
      imagettftext($image,13,0,1145,465,$color,$font,$address);

      // header('Content-Type: image/jpg'); 
      $save =   imagejpeg($image,"assets/".$name.".jpg");
  
      $pdf = new FPDF('L','in',[11.7,8.27]);
      $pdf ->AddPage();
      
      $pdf->Image("assets/".$name.".jpg",0,0,11.7,8.27);
   
      $pdf->Output("assets/".$name.".pdf","I");
      imagedestroy($image);
    }
  }else{
    echo '<script>alert("Sorry... Your Certificate Not found")</script>';
  }

?>
  • How does this answer the question at hand - "*How to generate a student ID*"? Furthermore the code you've posted is open to [SQL injection](https://stackoverflow.com/questions/601300/what-is-sql-injection) – DarkBee Aug 01 '23 at 06:26
  • This answer related information outside the main issue. – Tural Rzaxanov Aug 04 '23 at 07:12
  • @TuralRzaxanov What do you mean? – DarkBee Aug 04 '23 at 08:03
  • This does not provide an answer to the question. Once you have sufficient [reputation](https://stackoverflow.com/help/whats-reputation) you will be able to [comment on any post](https://stackoverflow.com/help/privileges/comment); instead, [provide answers that don't require clarification from the asker](https://meta.stackexchange.com/questions/214173/why-do-i-need-50-reputation-to-comment-what-can-i-do-instead). - [From Review](/review/late-answers/34775597) – Hamza Rashid Aug 05 '23 at 22:34