QRコード生成モジュールの使い方 for PHP5

ドキュメントを書いているときに QRCode::addData() および QRCode::readData() での第二引数 $mode の取り扱いについて想定外の動作になっていたことに気付いたので、修正版をリリースします。
php_qr-0.1.4.tgz
0.1.4 で致命的なバグを加えてしまっていたので、0.1.5 として再度リリースしました。
php_qr-0.1.5.tgz


さて本題です。前回のエントリで書いたとおり、php_qr の OO-API の使い方をひととおり紹介します。

イントロダクション

まず、この拡張モジュールが提供する関数等の一覧を示しておきます。これはコマンドラインphp --re qr として表示されるモジュール情報を少しだけ整形したものです。

Extension [ <persistent> extension #48 qr version 0.1.4 ] {
  - Dependencies {
    Dependency [ spl (Required) ]
    Dependency [ gd (Required) ]
  }
  - Constants [20] {
    Constant [ integer QR_EM_AUTO ] { -1 }
    Constant [ integer QR_EM_NUMERIC ] { 0 }
    Constant [ integer QR_EM_ALNUM ] { 1 }
    Constant [ integer QR_EM_8BIT ] { 2 }
    Constant [ integer QR_EM_KANJI ] { 3 }
    Constant [ integer QR_ECL_L ] { 0 }
    Constant [ integer QR_ECL_M ] { 1 }
    Constant [ integer QR_ECL_Q ] { 2 }
    Constant [ integer QR_ECL_H ] { 3 }
    Constant [ integer QR_FMT_DIGIT ] { 0 }
    Constant [ integer QR_FMT_ASCII ] { 1 }
    Constant [ integer QR_FMT_JSON ] { 2 }
    Constant [ integer QR_FMT_PBM ] { 3 }
    Constant [ integer QR_FMT_BMP ] { 4 }
    Constant [ integer QR_FMT_SVG ] { 5 }
    Constant [ integer QR_FMT_TIFF ] { 6 }
    Constant [ integer QR_FMT_GIF ] { 7 }
    Constant [ integer QR_FMT_JPEG ] { 8 }
    Constant [ integer QR_FMT_PNG ] { 9 }
    Constant [ integer QR_FMT_WBMP ] { 10 }
  }
  - Functions {
    Function [ <internal> public function qrcode ] {
      - Parameters [2] {
        Parameter #0 [ <required> $data ]
        Parameter #1 [ <optional> array $options ]
      }
    }
    Function [ <internal> public function qr_get_symbol ] {
      - Parameters [2] {
        Parameter #0 [ <required> $data ]
        Parameter #1 [ <optional> array $options ]
      }
    }
    Function [ <internal> public function qr_output_symbol ] {
      - Parameters [3] {
        Parameter #0 [ <required> $output ]
        Parameter #1 [ <required> $data ]
        Parameter #2 [ <optional> array $options ]
      }
    }
    Function [ <internal> public function qr_image_resource ] {
      - Parameters [3] {
        Parameter #0 [ <required> $data ]
        Parameter #1 [ <optional> array $options ]
        Parameter #2 [ <optional> &$colors ]
      }
    }
    Function [ <internal> public function qr_mimetype ] {
      - Parameters [1] {
        Parameter #0 [ <required> $format ]
      }
    }
  }
  - Classes [2] {
    Class [ <internal:qr> <iterateable> class QRCode implements Iterator, Traversable, Countable ] {
      - Constants [23] {
        Constant [ integer EM_AUTO ] { -1 }
        Constant [ integer EM_NUMERIC ] { 0 }
        Constant [ integer EM_ALNUM ] { 1 }
        Constant [ integer EM_8BIT ] { 2 }
        Constant [ integer EM_KANJI ] { 3 }
        Constant [ integer ECL_L ] { 0 }
        Constant [ integer ECL_M ] { 1 }
        Constant [ integer ECL_Q ] { 2 }
        Constant [ integer ECL_H ] { 3 }
        Constant [ integer FMT_DIGIT ] { 0 }
        Constant [ integer FMT_ASCII ] { 1 }
        Constant [ integer FMT_JSON ] { 2 }
        Constant [ integer FMT_PBM ] { 3 }
        Constant [ integer FMT_BMP ] { 4 }
        Constant [ integer FMT_SVG ] { 5 }
        Constant [ integer FMT_TIFF ] { 6 }
        Constant [ integer FMT_GIF ] { 7 }
        Constant [ integer FMT_JPEG ] { 8 }
        Constant [ integer FMT_PNG ] { 9 }
        Constant [ integer FMT_WBMP ] { 10 }
        Constant [ integer ERRMODE_SILENT ] { 0 }
        Constant [ integer ERRMODE_WARNING ] { 1 }
        Constant [ integer ERRMODE_EXCEPTION ] { 2 }
      }
      - Static properties [0] {}
      - Static methods [0] {}
      - Properties [0] {}
      - Methods [19] {
        Method [ <internal, ctor> public method __construct ] {
          - Parameters [1] {
            Parameter #0 [ <optional> array $options ]
          }
        }
        Method [ <internal> public method setErrorHandling ] {
          - Parameters [1] {
            Parameter #0 [ <required> $errmode ]
          }
        }
        Method [ <internal> public method setFormat ] {
          - Parameters [1] {
            Parameter #0 [ <required> $format ]
          }
        }
        Method [ <internal> public method setSeparator ] {
          - Parameters [1] {
            Parameter #0 [ <required> $separator ]
          }
        }
        Method [ <internal> public method setMagnify ] {
          - Parameters [1] {
            Parameter #0 [ <required> $magnify ]
          }
        }
        Method [ <internal> public method setOrder ] {
          - Parameters [1] {
            Parameter #0 [ <required> $order ]
          }
        }
        Method [ <internal> public method addData ] {
          - Parameters [2] {
            Parameter #0 [ <required> $data ]
            Parameter #1 [ <optional> $mode ]
          }
        }
        Method [ <internal> public method readData ] {
          - Parameters [2] {
            Parameter #0 [ <required> $input ]
            Parameter #1 [ <optional> $mode ]
          }
        }
        Method [ <internal> public method finalize ] {}
        Method [ <internal> public method getSymbol ] {}
        Method [ <internal> public method outputSymbol ] {
          - Parameters [1] {
            Parameter #0 [ <optional> $output ]
          }
        }
        Method [ <internal> public method getImageResource ] {
          - Parameters [1] {
            Parameter #0 [ <optional> &$colors ]
          }
        }
        Method [ <internal> public method getMimeType ] {}
        Method [ <internal, prototype Iterator> public method current ] {}
        Method [ <internal, prototype Iterator> public method key ] {}
        Method [ <internal, prototype Iterator> public method next ] {}
        Method [ <internal, prototype Iterator> public method rewind ] {}
        Method [ <internal, prototype Iterator> public method valid ] {}
        Method [ <internal, prototype Countable> public method count ] {}
      }
    }
    Class [ <internal:qr> class QRException extends Exception ] {}
  }
}


上記の通り、SPL と GD 拡張モジュールに依存します。(GD を使わないようにもコンパイルできますが、使わない手はないでしょう)
定数と関数についてはこれまで紹介したとおりなので省略します。
QRException は主にクラス QRCode のメソッドに不正な値が与えられたときに投げられる例外です。
続いて、クラス QRCode の説明に入ります。

コンストラクタとエラー処理

public void QRCode::__construct([array $options])

クラス QRCode のコンストラクタは引数として符号化および出力のオプションを指定できます。
$options については 4/27のエントリを参照してください。
オプション値には定数 QR_* の代わりにクラス定数 QRCode::* も使えます。
符号化オプション version, mode, eclevel, masktype, maxnum はコンストラクタでしか指定できませんが、出力オプション format, magnify, separator, order は後からでも専用のメソッドで変更できます。
不正な符号化オプションが指定された場合は例外 QRException をスローします。
QRCode のインスタンスは clone できません。

public void QRCode::setErrorHandling(int $errmode)

インスタンスごとのエラー処理設定をします。
$errmode には以下のいずれかを指定します。それ以外の値が与えられた場合は例外 QRException をスローします。

  • QRCode::ERRMODE_SILENT
    • エラーが起きても何もしません。値を返すメソッドの返り値は false になります。
  • QRCode::ERRMODE_WARNING
    • エラーが起きたら E_WARNING を発行します。値を返すメソッドの返り値は false になります。
  • QRCode::ERRMODE_EXCEPTION
    • エラーが起きたら QRException をスローします。

デフォルトのエラーモードは QRCode::ERRMODE_EXCEPTION です。

データを入力する

以下の 2メソッドをファイナライズ後にコールした場合、エラーを発生します。

public int QRCode::addData(string $data[, int $mode])

文字列 $data を符号化モード $mode で符号化して QRコードシンボルに格納します。
第二引数 $mode が省略された場合はコンストラクタのオプションで指定された値が適用されます。コンストラクタで符号化オプションが指定されなかった場合のデフォルト値は QRCode::EM_AUTO です。
バージョン 0.1.3 以前にはバグがあり、$mode が省略された場合は QRCode::EM_NUMERIC が適用されていました。
返り値は格納されたデータのバイト数で、strlen($data) と同じです。
入力データが大きすぎる場合と符号化モードに適さない場合にエラーを発生します。

public int QRCode::readData(mixed $input[, int $mode])

$input から読み込んだデータを符号化モード $mode で符号化して QRコードシンボルに格納します。
第一引数 $input はファイル名または読み込み可能なストリームリソースです。
第二引数 $mode は QRCode::addData() と同等です。
返り値は格納されたデータのバイト数で、$input から読み込んだバイト数と同じです。
データを読み込めなかった場合、読み込んだデータが大きすぎる場合、符号化モードに適さない場合にエラーを発生します。

ファイナライズ

public void QRCode::finalize(void)

それ以上データを投入する必要が無くなったら、このメソッドをコールします。
ファイナライズ後に addData() および readData() をコールする、またはファイナライズ前に getSymbol(), outputSymbol(), getImageResource() をコールするとエラーを発生します。

出力設定をする

以下の 4メソッドはファイナライズ前/後のいつでも必要に応じてコールできます。
ある形式で出力した後に設定を変更し、異なる形式で再度出力するといったこともできます。
不正な値が指定されても直ちにはエラーを発生せず、出力時にエラーを発生します。

public void QRCode::setFormat(int $format)

出力形式を設定します。出力形式には定数 QRCode::FMT_{DIGIT,ASCII,JSON,PBM,JPG,BMP,SVG,TIFF,GIF,JPEG,PNG,WBMP} のいずれかを指定します。
TIFF 出力にはコンパイル時に --with-qr-tiff を、GIF/JPEG/PNG/WBMP 出力にはコンパイル時に --enable-qr-gd を指定する必要があります。

public void QRCode::setSeparator(int $separator)

分離パターン (QRコードシンボル周囲の余白) の幅を設定します。有効な値は 0 から 16 までです。
デフォルト値は 4 で、これは QRコード規格上の下限です。
使用メモリを制限するため、値に上限を設けています。

public void QRCode::setMagnify(int $magnify)

QRコードシンボルの拡大率を設定します。有効な値は 1 から 16 までです。
1 の場合、1モジュール (1ドット) あたり 1×1 ピクセルです。
使用メモリを制限するため、値に上限を設けています。

public void QRCode::setOrder(int $order)

連結コード (分割コードとも呼ばれる。正式には構造的連接) を生成する場合ののシンボルの並べ方を設定します。
0 ならなるべく正方形に近くなるように、正の数なら横に $order 個ずつ、負の数なら縦に abs($order) 個ずつ並べます。
JSON の場合は多次元配列として出力するので無視されます。

QRコードを取得/出力/加工する

以下の 3メソッドをファイナライズ前にコールした場合、エラーを発生します。
出力オプションに不正な値が設定されていた場合にもエラーを発生します。

public string QRCode::getSymbol(void)

QRコードシンボルデータを取得します。

public int QRCode::outputSymbol([mixed $output])

$output に QRコードシンボルを書き込みます。
引数 $output はファイル名または書き込み可能なストリームリソースです。省略された場合は標準の出力バッファに書き込みます。
返り値はストリームに書き込まれたバイト数です。

public resource QRCode::getImageResource([array &$colors])

QRコードシンボルをイメージ関数に使用可能なリソースとして取得します。
引数 $colors が与えられた場合、描画色と背景色のカラー ID が代入されます。$colors はリファレンスとして受け取るのでリテラルや定数ではなく変数を与えてください。
$colors[0] が描画色 (暗モジュール)、$colors[1] が背景色 (明モジュール) です。
使用例は 4/29のエントリを参考にしてください。

ユーティリティ

public string QRCode::getMimeType(void)

現在設定されている出力形式に応じた MIME タイプを取得します。

SPL - Iterator & Countable

クラス QRCode はインターフェイス Iterator および Countable を implement しており、インスタンスを foreach 文や count 関数に与えることができます。

foreach ($qrcode as $symbol)

foeach 文にインスタンスを与えた場合、連結コードの各シンボルを個別に取り出すことができます。
各シンボルは出力オプションに応じた形式に変換されています。
ファイナライズ前に foreach 文に与えるとエラーを発生します。

count($qrcode)

count 関数にインスタンスを与えた場合、いくつのシンボルが格納されているかを取得できます。
ファイナライズ前/後のいつでも count できます。