mirror of
https://github.com/chillerlan/php-qrcode.git
synced 2026-08-31 04:28:03 +00:00
✨ wiki
This commit is contained in:
@@ -34,7 +34,8 @@ namespaced, cleaned up, improved and other stuff.
|
||||
|
||||
## Documentation
|
||||
|
||||
A documentation created with [phpDocumentor](https://www.phpdoc.org/) can be found at https://chillerlan.github.io/php-qrcode/ (WIP).
|
||||
See [the wiki](https://github.com/chillerlan/php-qrcode/wiki) for advanced documentation.
|
||||
An API documentation created with [phpDocumentor](https://www.phpdoc.org/) can be found at https://chillerlan.github.io/php-qrcode/ (WIP).
|
||||
|
||||
### Requirements
|
||||
- PHP 7.4+
|
||||
@@ -49,7 +50,7 @@ A documentation created with [phpDocumentor](https://www.phpdoc.org/) can be fou
|
||||
|
||||
via terminal: `composer require chillerlan/php-qrcode`
|
||||
|
||||
*composer.json* (note: replace `dev-main` with a [version constraint](https://getcomposer.org/doc/articles/versions.md#writing-version-constraints), e.g. `^3.2` - see [releases](https://github.com/chillerlan/php-qrcode/releases) for valid versions)
|
||||
*composer.json*
|
||||
```json
|
||||
{
|
||||
"require": {
|
||||
@@ -59,18 +60,19 @@ via terminal: `composer require chillerlan/php-qrcode`
|
||||
}
|
||||
```
|
||||
|
||||
Note: replace `dev-main` with a [version constraint](https://getcomposer.org/doc/articles/versions.md#writing-version-constraints), e.g. `^3.2` - see [releases](https://github.com/chillerlan/php-qrcode/releases) for valid versions.
|
||||
For PHP version ...
|
||||
- 7.4+ use `^4.2`
|
||||
- 7.2+ use `^3.3`
|
||||
- 7.0+ use `^2.0`
|
||||
- 5.6+ use `1.0.9` (please let PHP 5 die!)
|
||||
|
||||
### Usage
|
||||
### Quickstart
|
||||
We want to encode this URI for a mobile authenticator into a QRcode image:
|
||||
```php
|
||||
$data = 'otpauth://totp/test?secret=B3JX4VCVJDVNXNZ5&issuer=chillerlan.net';
|
||||
|
||||
//quick and simple:
|
||||
// quick and simple:
|
||||
echo '<img src="'.(new QRCode)->render($data).'" alt="QR Code" />';
|
||||
```
|
||||
|
||||
@@ -79,312 +81,7 @@ echo '<img src="'.(new QRCode)->render($data).'" alt="QR Code" />';
|
||||
<img alt="QR codes are awesome!" src="https://raw.githubusercontent.com/chillerlan/php-qrcode/main/examples/example_svg.png">
|
||||
</p>
|
||||
|
||||
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`](https://github.com/chillerlan/php-settings-container/blob/master/src/SettingsContainerInterface.php), respectively) object as the only parameter.
|
||||
|
||||
```php
|
||||
$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](#custom-qroutputinterface).
|
||||
|
||||
```php
|
||||
$matrix = $qrcode->getMatrix($data);
|
||||
|
||||
foreach($matrix->matrix() as $y => $row){
|
||||
foreach($row as $x => $module){
|
||||
|
||||
// get a module's value
|
||||
$value = $module;
|
||||
|
||||
// or via the matrix's getter method
|
||||
$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](https://github.com/chillerlan/php-qrcode/tree/main/examples) for some more usage examples.
|
||||
|
||||
#### Custom module values
|
||||
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 value (light) 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...
|
||||
```php
|
||||
// for true (dark)
|
||||
($value >> 8) === $M_TYPE;
|
||||
|
||||
// for false (light)
|
||||
$value === $M_TYPE;
|
||||
```
|
||||
...or you can perform a loose check, ignoring the module value
|
||||
```php
|
||||
// for true
|
||||
($value >> 8) > 0;
|
||||
|
||||
// for false
|
||||
($value >> 8) === 0;
|
||||
```
|
||||
|
||||
See also `QRMatrix::set()`, `QRMatrix::check()` and [`QRMatrix` constants](#qrmatrix-constants).
|
||||
|
||||
To map the values and properly render the modules for the given `QROutputInterface`, it's necessary to overwrite the default values:
|
||||
```php
|
||||
$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](https://github.com/chillerlan/php-qrcode/tree/main/src/Output).
|
||||
|
||||
```php
|
||||
class MyCustomOutput extends QROutputAbstract{
|
||||
|
||||
// inherited from QROutputAbstract
|
||||
protected QRMatrix $matrix; // QRMatrix
|
||||
protected int $moduleCount; // modules QRMatrix::size()
|
||||
protected QROptions $options; // MyCustomOptions or QROptions
|
||||
protected int $scale; // scale factor from options
|
||||
protected int $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 string $myParam = 'defaultValue';
|
||||
|
||||
// ...
|
||||
}
|
||||
```
|
||||
...or use the [`SettingsContainerInterface`](https://github.com/chillerlan/php-settings-container/blob/main/src/SettingsContainerInterface.php), which is the more flexible approach.
|
||||
|
||||
```php
|
||||
trait MyCustomOptionsTrait{
|
||||
protected string $myParam = 'defaultValue';
|
||||
|
||||
// ...
|
||||
}
|
||||
```
|
||||
set the options:
|
||||
```php
|
||||
$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...
|
||||
```php
|
||||
(new QRCode($myCustomOptions))->render($data);
|
||||
```
|
||||
...or invoke the `QROutputInterface` manually.
|
||||
```php
|
||||
$qrOutputInterface = new MyCustomOutput($myCustomOptions, (new QRCode($myCustomOptions))->getMatrix($data));
|
||||
|
||||
//dump the output, which is equivalent to QRCode::render()
|
||||
$qrOutputInterface->dump();
|
||||
```
|
||||
|
||||
### API
|
||||
|
||||
#### `QRCode` methods
|
||||
method | return | description
|
||||
------ | ------ | -----------
|
||||
`__construct(QROptions $options = null)` | - | see [`SettingsContainerInterface`](https://github.com/chillerlan/php-settings-container/blob/main/src/SettingsContainerInterface.php)
|
||||
`render(string $data, string $file = null)` | mixed, `QROutputInterface::dump()` | renders a QR Code for the given `$data` and `QROptions`, saves `$file` optional
|
||||
`getMatrix(string $data)` | `QRMatrix` | returns a `QRMatrix` object for the given `$data` and current `QROptions`
|
||||
`initDataInterface(string $data)` | `QRDataInterface` | returns a fresh `QRDataInterface` for the given `$data`
|
||||
`isNumber(string $string)` | bool | checks if a string qualifies for `Number`
|
||||
`isAlphaNum(string $string)` | bool | checks if a string qualifies for `AlphaNum`
|
||||
`isKanji(string $string)` | bool | checks if a string qualifies for `Kanji`
|
||||
`isByte(string $string)` | bool | checks if a string is non-empty
|
||||
|
||||
#### `QRCode` constants
|
||||
name | description
|
||||
---- | -----------
|
||||
`VERSION_AUTO` | `QROptions::$version`
|
||||
`MASK_PATTERN_AUTO` | `QROptions::$maskPattern`
|
||||
`OUTPUT_MARKUP_SVG`, `OUTPUT_MARKUP_HTML` | `QROptions::$outputType` markup
|
||||
`OUTPUT_IMAGE_PNG`, `OUTPUT_IMAGE_JPG`, `OUTPUT_IMAGE_GIF` | `QROptions::$outputType` image
|
||||
`OUTPUT_STRING_JSON`, `OUTPUT_STRING_TEXT` | `QROptions::$outputType` string
|
||||
`OUTPUT_IMAGICK` | `QROptions::$outputType` ImageMagick
|
||||
`OUTPUT_FPDF` | `QROptions::$outputType` PDF, using [FPDF](https://github.com/setasign/fpdf)
|
||||
`OUTPUT_CUSTOM` | `QROptions::$outputType`, requires `QROptions::$outputInterface`
|
||||
`ECC_L`, `ECC_M`, `ECC_Q`, `ECC_H`, | ECC-Level: 7%, 15%, 25%, 30% in `QROptions::$eccLevel`
|
||||
`DATA_NUMBER`, `DATA_ALPHANUM`, `DATA_BYTE`, `DATA_KANJI` | `QRDataInterface::$datamode`
|
||||
|
||||
#### `QROptions` properties
|
||||
property | type | default | allowed | description
|
||||
-------- | ---- | ------- | ------- | -----------
|
||||
`$version` | int | `QRCode::VERSION_AUTO` | 1...40 | the [QR Code version number](http://www.qrcode.com/en/about/version.html)
|
||||
`$versionMin` | int | 1 | 1...40 | Minimum QR version (if `$version = QRCode::VERSION_AUTO`)
|
||||
`$versionMax` | int | 40 | 1...40 | Maximum QR version (if `$version = QRCode::VERSION_AUTO`)
|
||||
`$eccLevel` | int | `QRCode::ECC_L` | `QRCode::ECC_X` | Error correct level, where X = L (7%), M (15%), Q (25%), H (30%)
|
||||
`$maskPattern` | int | `QRCode::MASK_PATTERN_AUTO` | 0...7 | Mask Pattern to use
|
||||
`$addQuietzone` | bool | `true` | - | Add a "quiet zone" (margin) according to the QR code spec
|
||||
`$quietzoneSize` | int | 4 | clamped to 0 ... `$matrixSize / 2` | Size of the quiet zone
|
||||
`$dataModeOverride` | string | `null` | `Number`, `AlphaNum`, `Kanji`, `Byte` | allows overriding the data type detection
|
||||
`$outputType` | string | `QRCode::OUTPUT_IMAGE_PNG` | `QRCode::OUTPUT_*` | built-in output type
|
||||
`$outputInterface` | string | `null` | * | FQCN of the custom `QROutputInterface` if `QROptions::$outputType` is set to `QRCode::OUTPUT_CUSTOM`
|
||||
`$cachefile` | string | `null` | * | optional cache file path
|
||||
`$eol` | string | `PHP_EOL` | * | newline string (HTML, SVG, TEXT)
|
||||
`$scale` | int | 5 | * | size of a QR code pixel (SVG, IMAGE_*), HTML -> via CSS
|
||||
`$cssClass` | string | `null` | * | a common css class
|
||||
`$svgOpacity` | float | 1.0 | 0...1 |
|
||||
`$svgDefs` | string | * | * | anything between [`<defs>`](https://developer.mozilla.org/docs/Web/SVG/Element/defs)
|
||||
`$svgViewBoxSize` | int | `null` | * | a positive integer which defines width/height of the [viewBox attribute](https://css-tricks.com/scale-svg/#article-header-id-3)
|
||||
`$textDark` | string | '🔴' | * | string substitute for dark
|
||||
`$textLight` | string | '⭕' | * | string substitute for light
|
||||
`$markupDark` | string | '#000' | * | markup substitute for dark (CSS value)
|
||||
`$markupLight` | string | '#fff' | * | markup substitute for light (CSS value)
|
||||
`$imageBase64` | bool | `true` | - | whether to return the image data as base64 or raw like from `file_get_contents()`
|
||||
`$imageTransparent` | bool | `true` | - | toggle transparency (no jpeg support)
|
||||
`$imageTransparencyBG` | array | `[255, 255, 255]` | `[R, G, B]` | the RGB values for the transparent color, see [`imagecolortransparent()`](http://php.net/manual/function.imagecolortransparent.php)
|
||||
`$pngCompression` | int | -1 | -1 ... 9 | `imagepng()` compression level, -1 = auto
|
||||
`$jpegQuality` | int | 85 | 0 - 100 | `imagejpeg()` quality
|
||||
`$imagickFormat` | string | 'png' | * | ImageMagick output type, see `Imagick::setType()`
|
||||
`$imagickBG` | string | `null` | * | ImageMagick background color, see `ImagickPixel::__construct()`
|
||||
`$moduleValues` | array | `null` | * | Module values map, see [Custom output modules](#custom-qroutputinterface) and `QROutputInterface::DEFAULT_MODULE_VALUES`
|
||||
|
||||
#### `QRMatrix` methods
|
||||
method | return | description
|
||||
------ | ------ | -----------
|
||||
`__construct(int $version, int $eclevel)` | - | -
|
||||
`init(int $maskPattern, bool $test = null)` | `QRMatrix` |
|
||||
`matrix()` | array | the internal matrix representation as a 2 dimensional array
|
||||
`version()` | int | the current QR Code version
|
||||
`eccLevel()` | int | current ECC level
|
||||
`maskPattern()` | int | the used mask pattern
|
||||
`size()` | int | the absoulute size of the matrix, including quiet zone (if set). `$version * 4 + 17 + 2 * $quietzone`
|
||||
`get(int $x, int $y)` | int | returns the value of the module
|
||||
`set(int $x, int $y, bool $value, int $M_TYPE)` | `QRMatrix` | sets the `$M_TYPE` value for the module
|
||||
`check(int $x, int $y)` | bool | checks whether a module is true (dark) or false (light)
|
||||
|
||||
#### `QRMatrix` constants
|
||||
name | light (false) | dark (true) | description
|
||||
---- | ------------- | ----------- | -----------
|
||||
`M_NULL` | 0 | - | module not set (should never appear. if so, there's an error)
|
||||
`M_DARKMODULE` | - | 512 | once per matrix at `$xy = [8, 4 * $version + 9]`
|
||||
`M_DATA` | 4 | 1024 | the actual encoded data
|
||||
`M_FINDER` | 6 | 1536 | the 7x7 finder patterns
|
||||
`M_SEPARATOR` | 8 | - | separator lines around the finder patterns
|
||||
`M_ALIGNMENT` | 10 | 2560 | the 5x5 alignment patterns
|
||||
`M_TIMING` | 12 | 3072 | the timing pattern lines
|
||||
`M_FORMAT` | 14 | 3584 | format information pattern
|
||||
`M_VERSION` | 16 | 4096 | version information pattern
|
||||
`M_QUIETZONE` | 18 | - | margin around the QR Code
|
||||
`M_LOGO` | 20 | - | space for a logo image (not used yet)
|
||||
`M_TEST` | 255 | 65280 | test value
|
||||
|
||||
|
||||
### 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*<br>
|
||||
http://www.denso-wave.com/qrcode/faqpatent-e.html
|
||||
Wait, what was that? Please again, slower! See [Advanced usage](https://github.com/chillerlan/php-qrcode/wiki/Advanced-usage) on the wiki.
|
||||
|
||||
### Framework Integration
|
||||
- Drupal [Google Authenticator Login `ga_login`](https://www.drupal.org/project/ga_login)
|
||||
@@ -394,10 +91,17 @@ http://www.denso-wave.com/qrcode/faqpatent-e.html
|
||||
- [Cachet](https://github.com/CachetHQ/Cachet)
|
||||
- other uses: [dependents](https://github.com/chillerlan/php-qrcode/network/dependents) / [packages](https://github.com/chillerlan/php-qrcode/network/dependents?dependent_type=PACKAGE)
|
||||
|
||||
|
||||
### Shameless advertising
|
||||
Hi, please check out my other projects that are way cooler than qrcodes!
|
||||
|
||||
- [php-oauth-core](https://github.com/chillerlan/php-oauth-core) - an OAuth 1/2 client library along with a bunch of [providers](https://github.com/chillerlan/php-oauth-providers)
|
||||
- [php-httpinterface](https://github.com/chillerlan/php-httpinterface) - a PSR-7/15/17/18 implemetation
|
||||
- [php-database](https://github.com/chillerlan/php-database) - a database client & querybuilder for MySQL, Postgres, SQLite, MSSQL, Firebird
|
||||
|
||||
### 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*<br>
|
||||
http://www.denso-wave.com/qrcode/faqpatent-e.html
|
||||
|
||||
Reference in New Issue
Block a user