2016-03-22 2 views
0

J'ai un bloc de code que j'essaie de déplacer d'un système basé sur des fichiers vers des blobs stockés dans la base de données, mais j'ai du mal à trouver les méthodes équivalentes les méthodes fread().Conversion du contenu du champ fread() en sql

Le code que je suis en train de convertir est la suivante:

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

je les données stockées dans la base de données bin2hex (gzencode(str)) dans le champ intitulé « Données », et ne pas avoir des problèmes de lecture de ces données retourner dans une variable comme suit:

$data = gzdecode(hex2bin($field['Data'])); 

Cependant, quand il vient à la section fread(), je ne suis pas sûr de savoir comment échanger toutes les commandes d'une manière qui est également sûr binaire. (Aka, la nouvelle valeur $data contient l'intégralité du contenu de fichiers fread() morceaux normalement à travers)

Voici le code que je souhaite remplacer fread() par la méthode binaire de chaînes équivalent, et au lieu de la poignée de fichier $fp1, utilisez le contenu stocké dans $data (comme mentionné ci-dessus).

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

(En attendant sur une réponse, j'ai écrit cette solution qui fonctionne)

lecteur de classe String

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

Utilisation

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

C'est un examen très approximatif Cependant, n'hésitez pas à développer. La solution Barmars fait la même chose, mais cette classe gère l'incrément d'octet pour vous et est presque la même syntaxe pour un remplacement direct pour fread(). Accepter la solution Barmars :)

+0

Utiliser 'substr()' pour extraire 'sous-chaînes de data' de $. – Barmar

+0

Ne serait-il pas plus facile de stocker chaque valeur comme une colonne séparée, au lieu de l'encoder comme un blob? – Barmar

Répondre

1

Utilisez substr et utilisez une variable pour garder une trace de la position actuelle lorsque vous parcourez les données.

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

Une autre façon serait une expression régulière pour extraire chaque partie en tant que groupe de capture:

$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); 
+0

Pendant que vous écriviez ceci, je faisais quelque chose de similaire sous la forme d'une classe que je pourrais enrouler et déposer n'importe où (à peu près) 'fopen',' fread', 'fclose' sont situés lors de l'échange pour travailler avec les données comme une chaîne au lieu d'une ressource de fichier. La syntaxe regex, je ne suis pas sûr de savoir comment cela fonctionnerait sur les données binaires, mais après avoir creusé quelque peu 'substr' semblait être plus flexible que' mb_substr'. Merci pour la réponse :) –

+1

Pour les données binaires, jetez un oeil à 'unpack()'. – Barmar