skip to Main Content

I have two below tables

1)CandidateDetails

EmployeeId  FirstName       LastName    Mobile          Email     BatchId
1           fn1             ln1         123456789       Email1      75
2           fn2             ln2         123456790       Email2      75
3           fn3             ln3         123456791       Email3      75
4           fn4             ln4         123456792       Email4      75
                

2)DuplicateCandidate

EmployeeId  FirstName       LastName    Mobile          Email     BatchId

My requirement is if EmployeeId is already available in CandidateDetails table then duplicate record to insert into DuplicateCandidate

Below is PHP script only for inserting array to CandidateDetails table, but i am not able to check the condition for if employee id is duplication then that record to insert into another DuplicateCandidate table.

<?php
header("Access-Control-Allow-Origin: http://localhost:4200");
header("Access-Control-Allow-Credentials: true ");
header('Access-Control-Allow-Methods: GET, PUT, POST, DELETE, OPTIONS');
header("Access-Control-Allow-Headers: X-Custom-Header, Origin, Content-Type , Authorisation , X-Requested-With");
header("Content-Type: application/json; charset=UTF-8 ");

$json = file_get_contents('php://input');
$decoded = json_decode($json, true);

print_r($decoded);
 $id=$_GET['id'];

function conn() {
  $dbhost = "xxxx";
  $user = "xxx";
  $pass = "xxx";
  $db = "xxxx";
  $conn = new PDO('mysql:host=xxx;dbname=xxx', $user, $pass);
  return $conn;
}
$db = conn();
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);                  
$p = $db->prepare("INSERT INTO CandidateDetails(EmployeeId, FirstName, LastName, Mobile,Email,BatchId)VALUES(:EmployeeId,:FirstName,:LastName,:Mobile,:Email,'$id')");
                   
foreach ($decoded as $item) {
  $p->execute($item);
}

echo json_encode(true);

?>

2

Answers


  1. <?php
    header("Access-Control-Allow-Origin: http://localhost:4200");
    header("Access-Control-Allow-Credentials: true ");
    header('Access-Control-Allow-Methods: GET, PUT, POST, DELETE, OPTIONS');
    header("Access-Control-Allow-Headers: X-Custom-Header, Origin, Content-Type , Authorisation , X-Requested-With");
    header("Content-Type: application/json; charset=UTF-8 ");
    
    $json = file_get_contents('php://input');
    $decoded = json_decode($json, true);
    
    print_r($decoded);
    $id = $_GET['id'];
    
    function conn()
    {
        $dbhost = "x.x.x.x";
        $user = "x";
        $pass = "x";
        $db = "x";
        $conn = new PDO('mysql:host=x;dbname=x', $user, $pass);
        return $conn;
    }
    $db = conn();
    $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    foreach ($decoded as $item)
    {
        echo $item['EmployeeId'];
    
        $sql = "SELECT * FROM CandidateDetails WHERE EmployeeId = " . $item['EmployeeId'];
        //$result = $conn-                         >query($sql);
        echo $item['EmployeeId'];
        echo $sql;
        $result = $db->query($sql);
        //echo $result;
        //echo $result->num_rows;
        $count = $result->rowCount();
        echo $count;
        if ($count > 0)
        {
            //DuplicateCandidate
            echo "duplicte results";
            //$p = $db->prepare("INSERT INTO CandidateDetailsLog(EmployeeId, FirstName, LastName, Mobile,Email,BatchId)VALUES(:EmployeeId,:FirstName,:LastName,:Mobile,:Email,'$id')");
            $p = $db->prepare("INSERT INTO CandidateDetailsLog(EmployeeId, FirstName, LastName, Mobile,Email,BatchId)
                                          VALUES ('" . $item['EmployeeId'] . "', '" . $item['FirstName'] . "',
                                                          '" . $item['LastName'] . "', '" . $item['Mobile'] . "', '" . $item['Email'] . "',
                                                           '" . $id . "')");
    
            $p->execute();
        }
        else
        {
            echo "0 results";
            //$p = $db->prepare("INSERT INTO CandidateDetails(EmployeeId, FirstName, LastName, Mobile,Email,BatchId)VALUES(:EmployeeId,:FirstName,:LastName,:Mobile,:Email,'$id')");
            $p = $db->prepare("INSERT INTO CandidateDetails(EmployeeId, FirstName, LastName, Mobile,Email,BatchId)
                                          VALUES ('" . $item['EmployeeId'] . "', '" . $item['FirstName'] . "',
                                                          '" . $item['LastName'] . "', '" . $item['Mobile'] . "', '" . $item['Email'] . "',
                                                           '" . $id . "')");
    
            $p->execute();
        }
    
    }
    
    $o = $db->prepare("UPDATE BatchDetailsInfo SET BatchStatus='B2' WHERE BatchId='$id'");
    $o->execute();
    
    echo json_encode(true);
    
    ?>
    
    Login or Signup to reply.
  2. While the accepted answer may do the job, it has several SQL injection vulnerabilities, including $_GET['id'] (which should not be trusted – a malicious actor could put anything in here including a SQL command to clear your database), and the JSON harvested from php://input (likewise – even if it’s valid JSON you could hide commands to delete data in here). Parameter escaping (as your original example) is the way to go.

    <?php
    
    /* Your headers etc here*/
    
    ///Build a database connection
    function db_conn() {
        /* Your Mysql setup with user/pass/db etc in a PDO object here*/
        $db=new PDO('mysql:host=x;dbname=x', $user, $pass);
        //You might want to set this here (for all connections:)
        //$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        return $db;
    }
    
    ///Search the candidate table for an entry for the given ID
    function db_employeeCandidateExists($db,$dangerEmployeeId) {
        $stmt=$db->prepare('SELECT EmployeeId FROM CandidateDetails WHERE EmployeeId=?');
        $stmt->execute([$dangerEmployeeId]);
        $result=$stmt->fetchAll();//We're expecting 0 rows (not found) or 1 row with the ID if it's a dup
        return count($result)>0;
    }
    
    ///Add a row to the DuplicateCandidate table
    function db_addDuplicate($db,$dangerRow,$dangerBatchId) {
        //All columns you want to fill out - layed out to be visually obvious how many there are
        $cols=['EmployeeId',
            'FirstName',
            'LastName',
            'Mobile',
            'Email',
            'BatchId'];
        //Values for the above columns - layed out to be visually equal to above
        // don't forget
        $vals=[$dangerRow['EmployeeId'],
            $dangerRow['FirstName'],
            $dangerRow['LastName'],
            $dangerRow['Mobile'],
            $dangerRow['Email'],
            $dangerBatchId];
        //The parameters can use a count of the cols (above)
        $params=substr(str_repeat('?,',count($cols)),0,-1);
    
        $stmt=$db->prepare('INSERT INTO DuplicateCandidate ('.
            implode(',',$cols).
            ') VALUES ('.
            $params.
            ')');
    
        $stmt->execute($vals);
        //todo: You might want to check there are no SQL errors reported here
    }
    
    ///Add a row to the CandidateDetails table
    function db_addCandiate($db,$dangerRow,$dangerBatchId) {
        //All columns you want to fill out - layed out to be visually obvious how many there are
        $cols=['EmployeeId',
            'FirstName',
            'LastName',
            'Mobile',
            'Email',
            'BatchId'];
        //Values for the above columns - layed out to be visually equal to above
        // don't forget
        $vals=[$dangerRow['EmployeeId'],
            $dangerRow['FirstName'],
            $dangerRow['LastName'],
            $dangerRow['Mobile'],
            $dangerRow['Email'],
            $dangerBatchId];
        //The parameters can use a count of the cols (above)
        $params=substr(str_repeat('?,',count($cols)),0,-1);
    
        $stmt=$db->prepare('INSERT INTO CandidateDetails ('.
            implode(',',$cols).
            ') VALUES ('.
            $params.
            ')');
    
        $stmt->execute($vals);
        //todo: You might want to check there are no SQL errors reported here
    }
    
    ///Get JSON from input and decode it into an associative array
    function getJson() {
        $json = file_get_contents('php://input');
        return json_decode($json, true);
    }
    
    $db = db_conn();
    //You might want to set this inside the `conn()` method for all usage?
    $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    
    // *** *** Dangerous CONTENT *** ***
    // Both $id (presuambly an integer) and $json (an associative array of data)
    // are user-provided and therefore the cannot be trusted - you NEED to escape these
    // values before using them in SQL
    $dangerBatchId = $_GET['id'];
    $dangerJson = getJson();
    
    foreach($dangerJson as $dangerItem)
    {
        if (db_employeeCandidateExists($db,$dangerItem['EmployeeId'])) {
            //Duplicate
            db_addDuplicate($db,$dangerItem,$dangerBatchId);
            echo 'Applicant '.$dangerItem['EmployeeId']." was a duplicaten";
        } else {
            db_addCandiate($db,$item,$dangerBatchId);
            echo 'Applicant '.$dangerItem['EmployeeId']." addedn";
        }
    }
    // Further processing
    

    I’ve used position parameter escaping (?) which should also work with MySQL. Named position escaping (:id) is probably better, but doesn’t allow me to quickly generate all parameters (build the $params string), and the database I tested against doesn’t support them.

    After separating the components into functions (as I’ve done), you’ll notice we have a bit of a grouping of functions beginning with db_… you might, instead, configure bundling these into a class. At that point you could avoid passing $db as the first parameter because you could internally share that in the class. But that’s a completely different topic and out of scope of your original question.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search