devilgg86
devilgg86

Reputation: 55

Convert barcode scan string to variables

I have a barcode that after being scanned it needs to be split into five variables.

Example barcode scan: 0109556135082301172207211060221967 21Sk4YGvF8
Alternate scan: 010955704600017017250630102107015

There are 5 delimiters

01 - gtin (14 DIGIT only)
11 - production date (YYMMDD)
17 -  expire date (YYMMDD)
10 - batch no (can be variable but not more than 20 digit)  
<space>21 - serial no (can be variable but not more than 20 digit)


01
09556135082301 (gtin)
17
220721 (production date)
10
60221967 (batch number)
 21
Sk4YGvF8 (serial number)

This is my attempt:

$str = "0109556135082301172207211060221967 21Sk4YGvF8"

if ($strtemp != null){
    $ais = explode("_",$str);
    for ($aa=0;$aa<sizeof($ais);$aa++)
    {
        $ary = $ais[$aa];
        while(strlen($ary) > 0) {
            if (substr($ary,0,2)=="01"){
                $igtin = substr($ary,2,14);
                $ary = substr($ary,-(strlen($ary)-16));
            }

            else if (substr($ary,0,2)=="17"){
                $expirydate = substr($ary,6,2)."-".substr($ary,4,2)."-20".substr($ary,2,2);
                $ary = substr($ary,-(strlen($ary)-8));
            }
            else if (substr($ary,0,2)=="10"){
                $batchno = substr($ary,2,strlen($ary)-2);
                $ary = "";
            }
            else if (substr($ary,0,2)=="21"){
                $serialno = substr($ary,2,strlen($ary)-2);
                $ary = "";
            }
            else if (substr($ary,0,2)=="11"){
                $proddate = substr($ary,6,2)."-".substr($ary,4,2)."-20".substr($ary,2,2);
                $ary = substr($ary,-(strlen($ary)-8));
            }

            else {
                $oth = "";
            }
        }

The result desired:

Items Result
GTIN 09556135082301
EXPIRE DATE 21-07-2022
BATCH/LOT NUMBER 60221967
SERIAL NUMBER Sk4YGvF8

From my code above the variable come out like this:

Items Result
GTIN 09556135082301
EXPIRE DATE 21-07-2022
BATCH/LOT NUMBER 6022196721Sk4YGvF8
SERIAL NUMBER

Upvotes: 0

Views: 743

Answers (2)

Misunderstood
Misunderstood

Reputation: 5665

UPDATE I have it and it is tested.

$str = "0109556135082301172207211060221967 21Sk4YGvF8";
$len = strlen($str);
$gtin = substr($str,2,14);
$date = '20' . substr($str,18,6);
$production = substr($date,0,4) . '-' .  substr($date,4,2) . '-' .  substr($date,6,2);
$time = strtotime($production);
$production = date('M d, Y',$time);
$position =  strrpos($str,' 21');
$serial = substr($str,$position + 2);
$start = strrpos($str,'10',23) + 2;
$batch = substr($str, $start,$position - $start);

echo"\nlen: ";
print_r($len);
echo"\ngtin: ";
print_r($gtin);
echo"\nproduction: ";
print_r($production);
echo"\nposition: ";
print_r($position);
echo"\nbatch: ";
print_r($batch);
echo"\nserial: ";
print_r($serial);



 $str = "010955704600017017250630102107015";

 $len = strlen($str);
 $gtin = substr($str,2,14);
 $position = strpos($str,'17',14) + 2;
 $date = '20' . substr($str,$position,6);
 $expires = substr($date,0,4) . '-' .  substr($date,4,2) . '-' .  substr($date,6,2);
$time = strtotime($expires);
$expires = date('M d, Y',$time);
$start = strpos($str,'10',22) + 2;
$batch = substr($str, $start);


echo"\n\n\nlen: ";
print_r($len);
echo"\ngtin: ";
print_r($gtin);
echo"\nexpires: ";
print_r($expires);
echo"\nposition: ";
print_r($position);
echo"\nbatch: ";
print_r($batch);

Results

len: 45
gtin: 09556135082301
production: Jul 21, 2022
position: 34
batch: 60221967
serial: 1Sk4YGvF8


len: 33
gtin: 09557046000170
expires: Jun 30, 2025
position: 18
batch: 2107015

I doubt there is a bullet proof algorithm to extract all the variables every time with your current syntax. The barcode is just not structured correctly for it to be done reliably.

If you can change the barcode format, I do it this way:

$str = "0955613508230|220721|60221967|Sk4YGvF8";
list($gtin,$date,$batch,$serial) = explode('|',$str);
echo "gtin: $gtin\nDate: $date\nBatch: $batch\nSerial: $serial";

Online Demo

END OF UPDATE

I think I may have it.

01
09556135082301
17
220721
10
60221967
21
Sk4YGvF8

Getting the gtin and expires is simple due to the fixed value lengths.
Presuming "21" will not show up in the serial number. strrpos finds the last position of "21" in $str. So serial number is from that position + 2 where +2 is for the length of "21" and take the substring from that position to the end.
The use the end position of the expires to the position of "21" to get the $batch.

$len = strlen($str);
$gtin = substr($str,2,14);
$expires = substr(18,6);
$position = strrpos('21', $str) + 2;
$serial = substr($str,$position);
$batch = substr($str,24,$len - $position); 

Upvotes: 1

shingo
shingo

Reputation: 27021

else if (substr($ary,0,2)=="10"){
    $batchno = substr($ary,2,strlen($ary)-2);
    $ary = "";
}

To answer your question. The reason is when "10" is found, the remaining string is used. you need do what you've done in other branches.


Give you some advice. Your approach is hard to read, you'd better use for and switch to optimze the code like this:

for($i = 0; $i < strlen($ary); )
{
    $h = substr($ary, $i, 2);
    $i += 2;
    switch($h)
    {
        case '01':
           $igtin = substr($ary,$i,14);
           $i += 14;
           break;

        case '10':
        .......
    }
}

Upvotes: 0

Related Questions