У меня есть блок кода, который я пытаюсь переместить из файловой системы в большие двоичные объекты, хранящиеся в базе данных, однако мне трудно найти эквивалентные строковые методы для fread()
методы.
Код, который я пытаюсь преобразовать, выглядит следующим образом:
$max_codewords_array=array(0,26,44,70,100,134,172,196,242,292,346,404,466,532,581,655,733,815,901,991,1085,1156, 1258,1364,1474,1588,1706,1828,1921,2051,2185,2323,2465,2611,2761,2876,3034,3196,3362,3532,3706);
$max_codewords=$max_codewords_array[$this->qrcode_version];
$max_modules_1side=17+($this->qrcode_version <<2);
$matrix_remain_bit=array(0,0,7,7,7,7,7,0,0,0,0,0,0,0,3,3,3,3,3,3,3,4,4,4,4,4,4,4,3,3,3,3,3,3,3,0,0,0,0,0,0);
/* ---- read version ECC data file */
$byte_num=$matrix_remain_bit[$this->qrcode_version]+($max_codewords << 3);
$filename=QRCODE_DATA_PATH."/qrv".$this->qrcode_version."_".$ec.".dat";
$fp1 = fopen ($filename, "rb");
$matx=fread($fp1,$byte_num);
$maty=fread($fp1,$byte_num);
$masks=fread($fp1,$byte_num);
$fi_x=fread($fp1,15);
$fi_y=fread($fp1,15);
$rs_ecc_codewords=ord(fread($fp1,1));
$rso=fread($fp1,128);
fclose($fp1);
У меня есть данные, хранящиеся в базе данных как bin2hex ( gzencode( str ) )
в поле с именем «Данные», и не имеют проблем с чтением этих данных обратно в переменную следующим образом:
$data = gzdecode(hex2bin($field['Data']));
Однако когда дело доходит до fread()
раздел, я не уверен, как поменять местами все эти команды таким образом, что это также бинарный безопасный. (иначе, новый $data
значение содержит все содержимое файла, которое fread()
нормально ломается)
Ниже приведен код, который я хочу заменить fread()
с эквивалентным двоичным методом безопасной строки, а вместо $fp1
дескриптор файла, используйте содержимое, хранящееся в $data
(как уже упоминалось выше).
$matx=fread($fp1,$byte_num);
$maty=fread($fp1,$byte_num);
$masks=fread($fp1,$byte_num);
$fi_x=fread($fp1,15);
$fi_y=fread($fp1,15);
$rs_ecc_codewords=ord(fread($fp1,1));
$rso=fread($fp1,128);
(В ожидании ответа я написал это решение, которое работает)
Класс чтения строк
class sread {
static $position = 0;
static $data;
public static function open($data) {
self::$data = $data;
}
public static function read($bytes) {
if( (self::$position + $bytes ) >= strlen(self::$data) ) {
$data = substr(self::$data, self::$position);
} else {
$data = substr(self::$data, self::$position, $bytes);
}
self::$position = self::$position + strlen($data);
return $data;
}
public static function close() {
self::$data = null;
self::$position = 0;
}
}
использование
$data = ""; // the long string containing the data you wish to move through
sread::open($data);
$matx = sread::read($byte_num);
$maty = sread::read($byte_num);
$masks = sread::read($byte_num);
$f1_x = sread::read(15);
$f1_y = sread::read(15);
$rs_ecc_codewords = ord(sread::read(1));
$rso = sread::read(128);
sread::close();
Это очень грубый пример, но не стесняйтесь расширять его. Решение Barmars делает то же самое, однако этот класс обрабатывает приращение байтов для вас и является почти таким же синтаксисом для замены вставки для fread()
, Принятие решения Barmars 🙂
использование substr
и используйте переменную, чтобы отслеживать текущую позицию при просмотре данных.
$curpos = 0;
$matx = substr($data, $curpos, $byte_num);
$curpos += $byte_num;
$maty = substr($data, $curpos, $byte_num);
$curpos += $byte_num;
$masks = substr($data, $curpos, $byte_num);
$curpos += $byte_num;
$fi_x = substr($data, $curpos, 15);
$curpos += 15;
$fi_y = substr($data, $curpos, 15);
$curpos += 15;
$rs_ecc_codewords = ord(substr($data, $curpos, 1));
$curpos += 1;
$rso = substr($data, $curpos, 128);
Другой способ — использовать регулярное выражение для извлечения каждой части в виде группы захвата:
$regex = "/(.{$byte_num})(.{$byte_num})(.{$byte_num})(.{15})(.{15})(.)(.{128})/";
preg_match($regex, $data, $match);
list ($ignore, $matx, $maty, $masks, $fi_x, $fi_y, $rs_ecc_char, $rso) = $match;
$rss_ecc_codewords = ord($rss_ecc_char);
Других решений пока нет …