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;