简体   繁体   中英

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
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':
        .......
    }
}

Your code is a little long and too clumsy to read and debug. Instead, I propose another approach with a regex as regex seems to be the right tool for this.

  • Split the string with /(?=\(\d+\))/ which is a positive lookahead assertion splitting the string based on (some code) some string pattern.

  • Now, for each one, capture the starting code as key and rest as the value using another regex /^(\(\d+\))(.+)$/ . This matches the starting code followed by any character 1 or more times.

Snippet:

<?php


$str = '(01)09556135082301(17)220721(10)60221967(21)Sk4YGvF8';

$result = [];

foreach(preg_split('/(?=\(\d+\))/', $str) as $match){
  $matches = [];
  if(preg_match('/^(\(\d+\))(.+)$/', $match, $matches) === 1){
    $result[ $matches[1] ] = $matches[2];
  }
}

print_r($result);

Online Demo .

Note: You can later split the value at key (17) to get yourself that date format.

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); 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM