xsuchy09/php-qrcode

A QR code generator. PHP 7.2+

Fund package maintenance!
Ko Fi

3.1.2 2019-08-29 07:39 UTC

README

Fork from chillerlan/php-qrcode.

A PHP7.2+ QR Code library based on the implementation by Kazuhiko Arase, namespaced, cleaned up, improved and other stuff.

Packagist version License Travis CI

Documentation

Requirements

  • PHP 7.2+
    • ext-gd, ext-json, ext-mbstring
    • optional ext-imagick

Installation

requires composer

Just run:

composer require xsuchy09/php-qrcode

Or edit your composer.json (note: replace dev-master with a version boundary)

{
	"require": {
		"php": "^7.2",
		"xsuchy09/php-qrcode": "dev-master"
	}
}

Manual installation

Download the desired version of the package from master or release and extract the contents to your project folder. After that:

  • run composer install to install the required dependencies and generate /vendor/autoload.php.
  • if you use a custom autoloader, point the namespace xsuchy09\QRCode to the folder src of the package

Profit!

Usage

We want to encode this URI for a mobile authenticator into a QRcode image:

$data = 'otpauth://totp/test?secret=B3JX4VCVJDVNXNZ5&issuer=chillerlan.net';

//quick and simple:
echo '<img src="'.(new QRCode)->render($data).'" alt="QR Code" />';

QR codes are awesome! QR codes are awesome!

Wait, what was that? Please again, slower!

Advanced usage

Ok, step by step. First you'll need a QRCode instance, which can be optionally invoked with a QROptions (or a SettingsContainerInterface, respectively) object as the only parameter.

$options = new QROptions([
	'version'    => 5,
	'outputType' => QRCode::OUTPUT_MARKUP_SVG,
	'eccLevel'   => QRCode::ECC_L,
]);

// invoke a fresh QRCode instance
$qrcode = new QRCode($options);

// and dump the output
$qrcode->render($data);

// ...with additional cache file
$qrcode->render($data, '/path/to/file.svg');

In case you just want the raw QR code matrix, call QRCode::getMatrix() - this method is also called internally from QRCode::render(). See also Custom output modules.

$matrix = $qrcode->getMatrix($data);

foreach($matrix->matrix() as $y => $row){
	foreach($row as $x => $module){

		// get a module's value
		$value = $module;
		$value = $matrix->get($x, $y);

		// boolean check a module
		if($matrix->check($x, $y)){ // if($module >> 8 > 0)
			// do stuff, the module is dark
		}
		else{
			// do other stuff, the module is light
		}

	}
}

Have a look in this folder for some more usage examples.

Custom module values

Previous versions of QRCode held only boolean matrix values that only allowed to determine whether a module was dark or not. Now you can distinguish between different parts of the matrix, namely the several required patterns from the QR Code specification, and use them in different ways.

The dark value is the module (light) value shifted by 8 bits to the left: $value = $M_TYPE << ($bool ? 8 : 0);, where $M_TYPE is one of the QRMatrix::M_* constants. You can check the value for a type explicitly like...

// for true (dark)
$value >> 8 === $M_TYPE;

//for false (light)
$value === $M_TYPE;

...or you can perform a loose check, ignoring the module value

// for true
$value >> 8 > 0;

// for false
$value >> 8 === 0

See also QRMatrix::set(), QRMatrix::check() and QRMatrix constants.

To map the values and properly render the modules for the given QROutputInterface, it's necessary to overwrite the default values:

$options = new QROptions;

// for HTML, SVG and ImageMagick
$options->moduleValues = [
	// finder
	1536 => '#A71111', // dark (true)
	6    => '#FFBFBF', // light (false)
	// alignment
	2560 => '#A70364',
	10   => '#FFC9C9',
	// timing
	3072 => '#98005D',
	12   => '#FFB8E9',
	// format
	3584 => '#003804',
	14   => '#00FB12',
	// version
	4096 => '#650098',
	16   => '#E0B8FF',
	// data
	1024 => '#4A6000',
	4    => '#ECF9BE',
	// darkmodule
	512  => '#080063',
	// separator
	8    => '#AFBFBF',
	// quietzone
	18   => '#FFFFFF',
];

// for the image output types
$options->moduleValues = [
	512  => [0, 0, 0],
	// ...
];

// for string/text output
$options->moduleValues = [
	512  => '#',
	// ...
];

Custom QROutputInterface

Instead of bloating your code you can simply create your own output interface by extending QROutputAbstract. Have a look at the built-in output modules.

class MyCustomOutput extends QROutputAbstract{

	// inherited from QROutputAbstract
	protected $matrix;      // QRMatrix
	protected $moduleCount; // modules QRMatrix::size()
	protected $options;     // MyCustomOptions or QROptions
	protected $scale;       // scale factor from options
	protected $length;      // length of the matrix ($moduleCount * $scale)

	// ...check/set default module values (abstract method, called by the constructor)
	protected function setModuleValues():void{
		// $this->moduleValues = ...
	}

	// QROutputInterface::dump()
	public function dump(string $file = null):string{
		$output = '';

		for($row = 0; $row < $this->moduleCount; $row++){
			for($col = 0; $col < $this->moduleCount; $col++){
				$output .= (int)$this->matrix->check($col, $row);
			}
		}

		return $output;
	}

}

In case you need additional settings for your output module, just extend QROptions...

class MyCustomOptions extends QROptions{
	protected $myParam = 'defaultValue';

	// ...
}

...or use the SettingsContainerInterface, which is the more flexible approach.

trait MyCustomOptionsTrait{
	protected $myParam = 'defaultValue';

	// ...
}

set the options:

$myOptions = [
	'version'         => 5,
	'eccLevel'        => QRCode::ECC_L,
	'outputType'      => QRCode::OUTPUT_CUSTOM,
	'outputInterface' => MyCustomOutput::class,
	// your custom settings
	'myParam'         => 'whatever value',
 ];

// extends QROptions
$myCustomOptions = new MyCustomOptions($myOptions);

// using the SettingsContainerInterface
$myCustomOptions = new class($myOptions) extends SettingsContainerAbstract{
	use QROptionsTrait, MyCustomOptionsTrait;
};

You can then call QRCode with the custom modules...

(new QRCode($myCustomOptions))->render($data);

...or invoke the QROutputInterface manually.

$qrOutputInterface = new MyCustomOutput($myCustomOptions, (new QRCode($myCustomOptions))->getMatrix($data));

//dump the output, which is equivalent to QRCode::render()
$qrOutputInterface->dump();

API

QRCode methods

QRCode constants

QROptions properties

QRMatrix methods

QRMatrix constants

Notes

The QR encoder, especially the subroutines for mask pattern testing, can cause high CPU load on increased matrix size. You can avoid a part of this load by choosing a fast output module, like OUTPUT_IMAGE_* and setting the mask pattern manually (which may result in unreadable QR Codes). Oh hey and don't forget to sanitize any user input!

Disclaimer!

I don't take responsibility for molten CPUs, misled applications, failed log-ins etc.. Use at your own risk!

Trademark Notice

The word "QR Code" is registered trademark of DENSO WAVE INCORPORATED
http://www.denso-wave.com/qrcode/faqpatent-e.html