|
| 1 | +# Advanced usage |
| 2 | + |
| 3 | +## Configuration via `QROptions` |
| 4 | + |
| 5 | +The [`QROptions`](https://github.com/chillerlan/php-qrcode/blob/main/src/QROptions.php) class is a container based on [chillerlan/php-settings-container](https://github.com/chillerlan/php-settings-container) that behaves similar to a [`\stdClass`](https://www.php.net/manual/class.stdclass) object, but with fixed properties. |
| 6 | + |
| 7 | +```php |
| 8 | +$options = new QROptions; |
| 9 | + |
| 10 | +// set some values |
| 11 | +$options->version = 7; // property "version" exists |
| 12 | +$options->foo = 'bar'; // property "foo" does not exist (and will not be created) |
| 13 | + |
| 14 | +// retrieve values |
| 15 | +var_dump($options->version); // -> 7 |
| 16 | +var_dump($options->foo); // -> null (no error will be thrown) |
| 17 | +``` |
| 18 | + |
| 19 | + |
| 20 | +### Supply an `iterable` of options |
| 21 | + |
| 22 | +The constructor takes an `iterable` of `$key => $value` pairs. For each setting an optional setter will be called if present. |
| 23 | + |
| 24 | +```php |
| 25 | +$myOptions = [ |
| 26 | + 'version' => 5, |
| 27 | + 'outputType' => QROutputInterface::GDIMAGE_PNG, |
| 28 | + 'eccLevel' => EccLevel::M, |
| 29 | +]; |
| 30 | + |
| 31 | +$options = new QROptions($myOptions); |
| 32 | +``` |
| 33 | + |
| 34 | +You can also set an `iterable` of options on an existing QROptions instance: |
| 35 | + |
| 36 | +```php |
| 37 | +$options->fromIterable($myOptions); |
| 38 | +``` |
| 39 | + |
| 40 | + |
| 41 | +### Load and save JSON |
| 42 | + |
| 43 | +The settings can be saved to and loaded from JSON, e.g. to store them in a database: |
| 44 | + |
| 45 | +```php |
| 46 | +$json = $options->toJSON(JSON_THROW_ON_ERROR); |
| 47 | +// via JsonSerializable interface |
| 48 | +$json = json_encode($options, JSON_THROW_ON_ERROR); |
| 49 | +// via __toString() |
| 50 | +$json = (string)$options; |
| 51 | + |
| 52 | +$options = (new QROptions)->fromJSON($json); |
| 53 | +// on an existing instance - properties will be overwriten |
| 54 | +$options->fromJSON($json); |
| 55 | +``` |
| 56 | + |
| 57 | +### Extending the `QROptions` class |
| 58 | + |
| 59 | +In case you need additional settings for your output module, just extend `QROptions`... |
| 60 | + |
| 61 | +```php |
| 62 | +class MyCustomOptions extends QROptions{ |
| 63 | + protected string $myParam = 'defaultValue'; |
| 64 | + // ... |
| 65 | +} |
| 66 | +``` |
| 67 | +...or use the [`SettingsContainerInterface`](https://github.com/chillerlan/php-settings-container/blob/main/src/SettingsContainerInterface.php), which is the more flexible approach. |
| 68 | + |
| 69 | +```php |
| 70 | +trait MyCustomOptionsTrait{ |
| 71 | + protected string $myParam = 'defaultValue'; |
| 72 | + // ... |
| 73 | + |
| 74 | + // an optional magic setter, named "set_" + property name |
| 75 | + protected function set_myParam(string $myParam):void{ |
| 76 | + $this->myParam = trim($myParam); |
| 77 | + } |
| 78 | + |
| 79 | + // an optional magic getter, named "get_" + property name |
| 80 | + protected function get_myParam():string{ |
| 81 | + return strtoupper($this->myParam); |
| 82 | + } |
| 83 | +} |
| 84 | + |
| 85 | +class MyCustomOptions extends SettingsContainerAbstract{ |
| 86 | + use QROptionsTrait, MyCustomOptionsTrait; |
| 87 | +} |
| 88 | + |
| 89 | +// set the options |
| 90 | +$myCustomOptions = new MyCustomOptions; |
| 91 | +$myCustomOptions->myParam = 'whatever value'; |
| 92 | +``` |
| 93 | + |
| 94 | +Extend the `SettingsContainerInterface` on-the-fly: |
| 95 | + |
| 96 | +```php |
| 97 | +$myOptions = [ |
| 98 | + 'myParam' => 'whatever value', |
| 99 | + // ... |
| 100 | +]; |
| 101 | + |
| 102 | +$myCustomOptions = new class($myOptions) extends SettingsContainerAbstract{ |
| 103 | + use QROptionsTrait, MyCustomOptionsTrait; |
| 104 | +}; |
| 105 | +``` |
| 106 | + |
| 107 | + |
| 108 | +## `QRCode` methods |
| 109 | + |
| 110 | +Aside of invoking a `QRCode` instance with an optional `QROptions` object as parameter, you can also set the options instance after invocation. |
| 111 | +After invocation of the `QROptions` instance, values can be set without calling `QRCode::setOptions()` again (instance is backreferenced), however, this may create side effects. |
| 112 | + |
| 113 | +```php |
| 114 | +// instance will be invoked with default settings |
| 115 | +$qrcode = new QRCode; |
| 116 | + |
| 117 | +// set options after QRCode invocation |
| 118 | +$options = new QROptions; |
| 119 | + |
| 120 | +$qrcode->setOptions($options); |
| 121 | +``` |
| 122 | + |
| 123 | + |
| 124 | +### Save to file |
| 125 | + |
| 126 | +Save the QR Code output to `/path/to/qrcode.svg`: |
| 127 | + |
| 128 | +```php |
| 129 | +$options->imageBase64 = false; |
| 130 | +$options->cachefile = '/path/to/qrcode.svg'; |
| 131 | + |
| 132 | +$qrcode->render($data); |
| 133 | +``` |
| 134 | + |
| 135 | +Alternatively, you can specify an output path, which will override the `QROptions::$cachefile` setting: |
| 136 | + |
| 137 | +```php |
| 138 | +$qrcode->render($data, '/other/path/to/qrcode.svg'); |
| 139 | + |
| 140 | +printf('<img src="%s" alt="QR Code" />', '/other/path/to/qrcode.svg'); |
| 141 | +``` |
| 142 | + |
| 143 | + |
| 144 | +### Render a `QRMatrix` instance |
| 145 | + |
| 146 | +You can render a [`QRMatrix`](https://github.com/chillerlan/php-qrcode/blob/main/src/Data/QRMatrix.php) instance directly: |
| 147 | + |
| 148 | +```php |
| 149 | +// a matrix from the current data segments |
| 150 | +$matrix = $qrcode->getQRMatrix(); |
| 151 | +// from the QR Code reader |
| 152 | +$matrix = $readerResult->getQRMatrix(); |
| 153 | +// manually invoked |
| 154 | +$matrix = (new QRMatrix(new Version(7), new EccLevel(EccLevel::M)))->initFunctionalPatterns(); |
| 155 | + |
| 156 | +$output = $qrcode->renderMatrix($matrix); |
| 157 | +// save to file |
| 158 | +$qrcode->renderMatrix($matrix, '/path/to/qrcode.svg'); |
| 159 | +``` |
| 160 | + |
| 161 | +Manual invocation of a `QROutputInterface` to render a `QRMatrix` instance: |
| 162 | + |
| 163 | +```php |
| 164 | +class MyCustomOutput extends QRMarkupSVG{ |
| 165 | + // ... |
| 166 | +} |
| 167 | + |
| 168 | +$qrOutputInterface = new MyCustomOutput($options, $matrix); |
| 169 | + |
| 170 | +$output = $qrOutputInterface->dump() |
| 171 | +// render to file |
| 172 | +$qrOutputInterface->dump('/path/to/qrcode.svg'); |
| 173 | +``` |
| 174 | + |
| 175 | + |
| 176 | +### Mixed mode |
| 177 | + |
| 178 | +Mixed mode QR Codes can be generated by adding several data segments: |
| 179 | + |
| 180 | +```php |
| 181 | +// make sure to set a proper internal encoding character set |
| 182 | +// ideally, this should be set in php.ini internal_encoding, |
| 183 | +// default_charset or mbstring.internal_encoding |
| 184 | +mb_internal_encoding('UTF-8'); |
| 185 | + |
| 186 | +// clear any existing data segments |
| 187 | +$qrcode->clearSegments(); |
| 188 | + |
| 189 | +$qrcode |
| 190 | + ->addNumericSegment($numericData) |
| 191 | + ->addAlphaNumSegment($alphaNumData) |
| 192 | + ->addKanjiSegment($kanjiData) |
| 193 | + ->addHanziSegment($hanziData) |
| 194 | + ->addByteSegment($binaryData) |
| 195 | + ->addEciSegment(ECICharset::GB18030, $encodedEciData) |
| 196 | +; |
| 197 | + |
| 198 | +$output = $qrcode->render(); |
| 199 | +// render to file |
| 200 | +$qrcode->render(null, '/path/to/qrcode.svg'); |
| 201 | +``` |
| 202 | + |
| 203 | +The [`QRDataModeInterface`](https://github.com/chillerlan/php-qrcode/blob/main/src/Data/QRDataModeInterface.php) offers the `validateString()` method (implemended for `AlphaNum`, `Byte`, `Hanzi`, `Kanji` and `Number`). |
| 204 | +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. |
| 205 | + |
| 206 | +```php |
| 207 | +if(!Hanzi::validateString($data)){ |
| 208 | + throw new Exception('invalid GB2312 data'); |
| 209 | +} |
| 210 | + |
| 211 | +$qrcode->addHanziSegment($data); |
| 212 | +``` |
| 213 | + |
| 214 | + |
| 215 | +### QR Code reader |
| 216 | + |
| 217 | +In some cases it might be necessary to increase the contrast of a QR Code image: |
| 218 | + |
| 219 | +```php |
| 220 | +$options->readerUseImagickIfAvailable = true; |
| 221 | +$options->readerIncreaseContrast = true; |
| 222 | +$options->readerGrayscale = true; |
| 223 | + |
| 224 | +$result = (new QRCode($options))->readFromFile('path/to/qrcode.png'); |
| 225 | +``` |
| 226 | + |
| 227 | +The `QRMatrix` object from the [`DecoderResult`](https://github.com/chillerlan/php-qrcode/blob/main/src/Decoder/DecoderResult.php) can be reused: |
| 228 | + |
| 229 | +```php |
| 230 | +$matrix = $result->getQRMatrix(); |
| 231 | + |
| 232 | +// ...matrix modification... |
| 233 | + |
| 234 | +$output = (new QRCode($options))->renderMatrix($matrix); |
| 235 | + |
| 236 | +// ...output |
| 237 | +``` |
0 commit comments