Advanced usage
Configuration via QROptions
The QROptions
class is a container based on chillerlan/php-settings-container that behaves similar to a \stdClass
object, but with fixed properties.
A list with all available QROptions
can be found under configuration settings.
$options = new QROptions;
// set some values
$options->version = 7; // property "version" exists
$options->foo = 'bar'; // property "foo" does not exist (and will not be created)
// retrieve values
var_dump($options->version); // -> 7
var_dump($options->foo); // -> null (no error will be thrown)
Supply an iterable
of options
The constructor takes an iterable
of $key => $value
pairs. For each setting an optional setter will be called if present.
$myOptions = [
'version' => 5,
'outputType' => QROutputInterface::GDIMAGE_PNG,
'eccLevel' => EccLevel::M,
];
$options = new QROptions($myOptions);
You can also set an iterable
of options on an existing QROptions instance:
$options->fromIterable($myOptions);
Load and save options from/to JSON
The settings can be saved to and loaded from JSON, e.g. to store them in a database:
$json = $options->toJSON(JSON_THROW_ON_ERROR);
// via JsonSerializable interface
$json = json_encode($options, JSON_THROW_ON_ERROR);
// via __toString()
$json = (string)$options;
$options = (new QROptions)->fromJSON($json);
// on an existing instance - properties will be overwriten
$options->fromJSON($json);
Extending the QROptions
class
In case you need additional settings for your output module, just extend QROptions
…
class MyCustomOptions extends QROptions{
protected string $myParam = 'defaultValue';
// ...
}
…or use the SettingsContainerInterface
, which is the more flexible approach.
trait MyCustomOptionsTrait{
protected string $myParam = 'defaultValue';
// ...
// an optional magic setter, named "set_" + property name
protected function set_myParam(string $myParam):void{
$this->myParam = trim($myParam);
}
// an optional magic getter, named "get_" + property name
protected function get_myParam():string{
return strtoupper($this->myParam);
}
}
class MyCustomOptions extends SettingsContainerAbstract{
use QROptionsTrait, MyCustomOptionsTrait;
}
// set the options
$myCustomOptions = new MyCustomOptions;
$myCustomOptions->myParam = 'whatever value';
Extend the SettingsContainerInterface
on-the-fly:
$myOptions = [
'myParam' => 'whatever value',
// ...
];
$myCustomOptions = new class($myOptions) extends SettingsContainerAbstract{
use QROptionsTrait, MyCustomOptionsTrait;
};
QRCode
methods
Aside of invoking a QRCode
instance with an optional QROptions
object as parameter, you can also set the options instance after invocation.
After invocation of the QROptions
instance, values can be set without calling QRCode::setOptions()
again (instance is backreferenced), however, this may create side effects.
// instance will be invoked with default settings
$qrcode = new QRCode;
// set options after QRCode invocation
$options = new QROptions;
$qrcode->setOptions($options);
Render a QRMatrix
instance
You can render a QRMatrix
instance directly:
// a matrix from the current data segments
$matrix = $qrcode->getQRMatrix();
// from the QR Code reader
$matrix = $readerResult->getQRMatrix();
// manually invoked
$matrix = (new QRMatrix(new Version(7), new EccLevel(EccLevel::M)))->initFunctionalPatterns();
$output = $qrcode->renderMatrix($matrix);
// save to file
$qrcode->renderMatrix($matrix, '/path/to/qrcode.svg');
Mixed mode
Mixed mode QR Codes can be generated by adding several data segments:
// make sure to set a proper internal encoding character set
// ideally, this should be set in php.ini internal_encoding,
// default_charset or mbstring.internal_encoding
mb_internal_encoding('UTF-8');
// clear any existing data segments
$qrcode->clearSegments();
$qrcode
->addNumericSegment($numericData)
->addAlphaNumSegment($alphaNumData)
->addKanjiSegment($kanjiData)
->addHanziSegment($hanziData)
->addByteSegment($binaryData)
->addEciSegment(ECICharset::GB18030, $encodedEciData)
;
$output = $qrcode->render();
// render to file
$qrcode->render(null, '/path/to/qrcode.svg');
The QRDataModeInterface
offers the validateString()
method (implemended for AlphaNum
, Byte
, Hanzi
, Kanji
and Number
).
This method is used internally when a data mode is invoked, but it can come in handy if you need to check input data beforehand.
if(!Hanzi::validateString($data)){
throw new Exception('invalid GB2312 data');
}
$qrcode->addHanziSegment($data);
QR Code reader
In some cases it might be necessary to increase the contrast of a QR Code image:
$options->readerUseImagickIfAvailable = true;
$options->readerIncreaseContrast = true;
$options->readerGrayscale = true;
$qrcode = new QRCode($options);
$result = $qrcode->readFromFile('path/to/qrcode.png');
$result = $qrcode->readFromBlob($imagedata);
The QRMatrix
object from the DecoderResult
can be reused:
$matrix = $result->getQRMatrix();
// ...matrix modification...
$output = (new QRCode($options))->renderMatrix($matrix);
// ...output
Common output options
Save to file
You can specify an output file path in which the QR Code content is stored:
$options->outputBase64 = false;
$options->cachefile = '/path/to/qrcode.svg';
$qrcode->render($data);
printf('<img src="%s" alt="QR Code" />', $options->cachefile);
The file path can also be supplied as second parameter to the render methods (this will override the QROptions::$cachefile
setting):
$qrcode->render($data, '/path/to/qrcode.svg');
Base64 URI output
By default, a Base64 encoded data URI will be returned (where applicable):
echo $qrcode->render($data); // -> data:image/png;base64,...
Disable Base64 output:
$options->outputBase64 = false;
header('Content-type: image/png');
echo $qrcode->render($data);
Return the image resource
In some cases you might want to modify the QR image after creation (without crating a custom output class), in which case you want the internal image resource rather than the final output.
$options->outputType = QROutputInterface::IMAGICK;
$options->returnResource = true;
/** @var Imagick $imagick */
$imagick = $qrcode->render($data);
echo $imagick->getImageBlob();
Add a logo space
$options->addLogoSpace = true;
$options->logoSpaceWidth = 9;
$options->logoSpaceHeight = 9;
$options->logoSpaceStartX = 10;
$options->logoSpaceStartY = 10;