back to top

Una classe per creare QR Codes con PHP

In questo articolo affronteremo un argomento di grande attualità: andremo alla scoperta dei QR Codes e vedremo come crearceli da soli attraverso il servizio Google Chart API e PHP.

Cosa sono i QR Codes

I QR codes sono dei codici a barre bidimensionali di forma quadrata pensati per essere letti e decodificati velocemente, caratteristica da cui prendono il nome: Quick Response.

Essendo sviluppati per essere decodificati velocemente, i QR Codes vengono utilizzati soprattutto per memorizzare informazioni (come la url di una pagina web o di una app, oppure un numero di telefono) che devono essere lette tramite dispositivi mobili (smartphone), i quali sono generalmente provvisti di software che ne permettono una facile decodifica.

Qui sotto vediamo un esempio pratico dell’uso dei QR codes, ne abbiamo, infatti, inserito uno contenente il link alla home-page di Mr.Webmaster. In questo modo, qualora l’articolo venisse stampato, sarà possibile accedere velocemente a questo sito web attraverso un qualsiasi dispositivo dodato di un interprete di QR Codes.

QR code

Altra caratteristica importante di questi codici è la robustezza. Infatti anche se danneggiati (si pensi, ad esempio, a delle macchie sulla pagina stampata) grazie al codice Reed-Solomon si è in grado di recuperare fino al 30% dell’informazione contenuta nel QR Code compromesso.

Vediamo, in questa tabella, i quattro livelli di correzione errori disponibili per i QR Codes e la relativa capacità di recupero:

Livello% di dati recuperabili
L7%
M15%
Q25%
H30%

Capacità di memorizzazione

I QR codes possono contenere fino a 7.089 caratteri numerici, oppure fino a 4.296 caratteri alfanumerici. Essendo codici di forma quadrata hanno un numero uguale di righe e colonne, e proprio dal loro numero dipende la capacità di memorizzazione del QR Code. Il numero di righe e colonne di un QR Code viene identificato dalla sua version. Le version vanno da 1 a 40, e l’incremento di una version comporta l’aggiunta di 4 righe e 4 colonne, si parte da 21 per arrivare a 177. Quindi un QR Code di version 1 è un quadrato formato da 21 righe e 21 colonne con capacità di memorizzazione fino a 25 caratteri alfanumerici, mentre un QR Code di version 40 ha 177 righe e 177 colonne e capacità di memorizzazione massima.

Capacità di memorizzazione per alcune version:

VersionRighe x ColonneLivello correzione dell’erroreMassimo numero di caratteri
NumericoAlfanumericoBinarioKanji
121×21L41251710
M3420148
Q2716117
H171074
225×25L77473220
M63382616
Q48292012
H3420148
1057×57L652395271167
M513311213131
Q36422115193
H28817411974
40177×177L7,0894,2962,9531,817
M5,5963,3912,3311,435
Q3,9932,4201,6631,024
H3,0571,8521,273784

La capacità di memorizzazione di un QR Code dipende esclusivamente dalla sua versione e dal livello di correzione dell’errore (più il livello è basso e maggiore è la quantità di dati immagazzinabili), non dalla sua dimensione in pixel.

QR Code con Google Chart Api

Le Google Chart Api è una API messa a disposizione da Google che restituisce una immagine contenente un grafico in risposta a una richiesta fatta tramite GET o POST. Ci sono diversi tipi di grafici che si possono creare attraverso questa API, ma noi ci concentreremo esclusivamente sui grafici di tipo QR Code.

La url alla quale fare le richieste per ottenere un grafico è https://chart.googleapis.com/chart a cui vanno aggiunti i parametri necessari, che nel nostro caso sono:

  • cht: Tipo di grafico, nel nostro caso cht=qr
  • chs: Dimensioni dell’immagine nel formato larghezza x altezza
  • chl: I dati da inserire nel nostro QR Code in codifica UTF-8

Con questi tre parametri siamo già in grado di creare il nostro QR Code, ma volendo abbiamo la possibilità di usare altri due parametri opzionali:

  • choe: Codifica del grafico, i possibili valori sono: UTF-8 (Default), Shift_JIS, ISO-8859-1. Si consiglia di lasciare UTF-8 se non in caso di esigenze particolari.
  • chld: Livello di correzione dell’errore: L (default), M, Q, H

La version del QR Code viene determinata automaticamente dall’API, che tiene in considerazione il numero di caratteri e il livello di correzione dell’errore selezionato. Bisogna tenere presente però che uno smartphone, normalmente, riesce a leggere solo QR Code fino alla version 4.

Un esempio di richiesta per la generazione di un QR Code è https://chart.googleapis.com/chart?cht=qr&chl=Hello+world&chs=200×200

QR Code con PHP e metodo GET

Vediamo ora come ottenere un QR Code attraverso una GET fatta in PHP. Iniziamo definendo la classe QRCode che come buona prassi vuole troviamo nel file qrcode.class.php:

<?php
class QRCode {
  
  //tipo di chart
  private static $_CHT = "qr"; 
  
  //url della Google Chart Api
  private static $_API_URL = "http://chart.apis.google.com/chart";
}
?>

Come possiamo vedere abbiamo definito solo due costanti che definiscono il tipo di grafico e la url base delle API. Aggiungiamo ora il metodo getQrCodeUrl per costruire la url completa per creare un QRCode:

public function getQrCodeUrl($data,$width,$height,$encoding=false,$correctionLevel=false) {
  
  //faccio encoding dei dati
  $data = urlencode($data);
  
  //creo la url con i parametri obbligatori
  $url = QRCode::$_API_URL . "?cht=". QRCode::$_CHT
               . "&chl=" . $data
               . "&chs=" . $width . "x" . $height;

  //controllo i parametri opzionali
  if($encoding){
    $url .= "&choe=" . $encoding;
  }
  
  if($correctionLevel){
    $url .= "&chld=" . $correctionLevel;
  }
  
  return $url;
}

Il metodo è molto semplice e si occupa di costruire una url attraverso i dati forniti, occupandosi anche di fare l’econding dei dati nel caso vengano inseriti caratteri non ASCII.

Ora possiamo testare la nostra classe attraverso questo codice di esempio che genera un tag <img> avente come parametro src la url costruita dinamicamente dal metodo getQrCodeUrl:

<?php 
  //includo la liberia
  require_once 'qrcode.class.php';
  
  //instanzio l'oggetto QRCode
  $qrcode = new QRCode();
  
  //renderizzo l'immagine
  echo '<img alt="ciao" src="' . $qrcode->getQrCodeUrl("ciao",100,100,"UTF-8","H") . '" />';
?>

QR Code con PHP e metodo POST

Le richieste GET hanno un limite di 2Kb sulla lunghezza totale, quindi se vogliamo creare un QR Code che contenga più di 2Kb di dati la GET non ci è d’aiuto. In questi casi bisogna usare il metodo POST. Aggiungiamo quindi un metodo getQrCodeData alla nostra classe che si occuperà di fare una POST alla API di Google:

public function getQrCodeData($data,$width,$height,$encoding=false,$correctionLevel=false){
  //faccio encoding dei dati
  $data = urlencode($data);

  // creo un'array con i parametri obbligatori
  $parameterList = array(
      'cht' => QRCode::$_CHT,
      'chs' => $width . "x" . $height,
      'chl' => $data);
  
  //controllo i parametri opzionali
  if($encoding){
    $parameterList['choe'] = $encoding;
  }

  if($correctionLevel){
    $parameterList['chld'] = $correctionLevel;
  }

  //creo il contenuto della post
  $content = http_build_query($parameterList);
  
  //creo il context
  $context = stream_context_create(array('http' => array('method' => 'POST', 'content' => $content)));

  //apro la connessione
  $fp = fopen(QRCode::$_API_URL, 'r', false, $context);
  
  //recupero i dati
  $response = stream_get_contents($fp);
  
  return $response;
}

Il metodo è molto simile al precedente e crea una lista di parametri che vanno a formare il contenuto della POST, vengono poi usate le funzioni fopen e stream_get_contents rispettivamente per fare la POST e per recuperare lo stream di dati dell’immagine. Per inserire l’immagine in una nostra pagina basta encodare i dati in BASE 64 e inserirli in un tag img in questo modo:

echo '<img src="data:image/png;base64,' . base64_encode($qrcode->getQrCodeData("ciao",100,100,"UTF-8","H")) . '" />';

Conclusioni

Le Google Chart Api sono molto potenti e molto facili da usare, quindi sono ideali per la generazione di QR Codes (non solo attraverso PHP).

Un’altra libreria interessante (ovviamente non è l’unica in circolazione) la si può trovare in questa pagina PHP QR Code. Scritta interamente in PHP e offre molte funzionalità tra cui la possibilità di usare una cache, ma si è deciso di non tenerla in considerazione poiché a mio avviso è poco e mal documentata.

Sotto vediamo uno screenshot della nostra pagina di esempio e il codice completo di questo articolo.

Esempio

Segue il codice completo della nostra classe qrcode.class.php:

<?php
class QRCode{

  //tipo di chart
  private static $_CHT = "qr";

  //url della Google Chart Api
  private static $_API_URL = "http://chart.apis.google.com/chart";

  //crea un qr code via GET
  public function getQrCodeUrl($data,$width,$height,$encoding=false,$correctionLevel=false){
    //faccio encoding dei dati
    $data = urlencode($data);

    //creo la url con i parametri obbligatori
    $url = QRCode::$_API_URL . "?cht=". QRCode::$_CHT
    . "&chl=" . $data
    . "&chs=" . $width . "x" . $height;

    //controllo i parametri opzionali
    if($encoding){
      $url .= "&choe=" . $encoding;
    }

    if($correctionLevel){
      $url .= "&chld=" . $correctionLevel;
    }

    return $url;
  }

  //crea un qr code via POST
  public function getQrCodeData($data,$width,$height,$encoding=false,$correctionLevel=false){
    //faccio encoding dei dati
    $data = urlencode($data);

    // creo un'array con i parametri obbligatori
    $parameterList = array(
        'cht' => QRCode::$_CHT,
        'chs' =>  $width . "x" . $height,
        'chl' => $data);
    
    //controllo i parametri opzionali
    if($encoding){
      $parameterList['choe'] = $encoding;
    }

    if($correctionLevel){
      $parameterList['chld'] = $correctionLevel;
    }

    //creo il contenuto della post
    $content = http_build_query($parameterList);
    
    //creo il context
    $context = stream_context_create(array('http' => array('method' => 'POST', 'content' => $content)));

    //apro la connessione
    $fp = fopen(QRCode::$_API_URL, 'r', false, $context);
    
    //recupero i dati
    $response = stream_get_contents($fp);
    
    return $response;
  }
}
?>

Segue, infine, il semplice codice che produce l’output (utilizzando, ovviamente, l’apposita classe):

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Test QR Code</title>
</head>

<h1>Test QR Code</h1>
<?php 
  //includo la liberia
  require_once 'qrcode.class.php';
  
  //instanzio l'oggetto QRCode
  $qrcode = new QRCode();
  
  //renderizzo l'immagine (metodo GET)
  echo '<h2>GET MODE</h2>';
  echo '<img alt="ciao" src="' . $qrcode->getQrCodeUrl("ciao",100,100,"UTF-8","H") . '" />';
  
  //encodo i dati ricevuti dalla POST
  echo '<h2>POST MODE</h2>';
  echo '<img src="data:image/png;base64,' . base64_encode($qrcode->getQrCodeData("ciao",100,100,"UTF-8","H")) . '" />';
?>
</html>
Pubblicitร 
Articolo precedente
Articolo successivo

Leggi anche...

Correggere l’errore the uploaded file exceeds the upload_max_filesize directive in php.ini

L'errore the uploaded file exceeds the upload_max_filesize directive in...

Cannot modify header information – headers already sent: come risolvere l’errore PHP

L'errore di PHP cannot modify header information - headers...

Ricavare l’estensione di un file con PHP

Quando si lavora con i file in un'applicazione web,...

GD Library: creazione, manipolazione e ridimensionamento immagini con PHP

Le librerie GD (o GD Library), sono componenti fondamentali...

PHP: impostare il fuso orario italiano

Le tue pagine PHP non mostrano l’orario corretto? Probabilmente...
Pubblicitร