Usage-Advanced-usage.md 6.3 KB

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.

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

Save to file

Save the QR Code output to /path/to/qrcode.svg:

$options->imageBase64 = false;
$options->cachefile   = '/path/to/qrcode.svg';

$qrcode->render($data);

Alternatively, you can specify an output path, which will override the QROptions::$cachefile setting:

$qrcode->render($data, '/other/path/to/qrcode.svg');

printf('<img src="%s" alt="QR Code" />', '/other/path/to/qrcode.svg');

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

Manual invocation of a QROutputInterface to render a QRMatrix instance:

class MyCustomOutput extends QRMarkupSVG{
	// ...
}

$qrOutputInterface = new MyCustomOutput($options, $matrix);

$output = $qrOutputInterface->dump()
// render to file
$qrOutputInterface->dump('/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;

$result = (new QRCode($options))->readFromFile('path/to/qrcode.png');

The QRMatrix object from the DecoderResult can be reused:

$matrix = $result->getQRMatrix();

// ...matrix modification...

$output = (new QRCode($options))->renderMatrix($matrix);

// ...output