【PHP】ロゴ付きQRコードを生成するサンプルコードを解説
この記事では、PHPの`endroid/qr-code`ライブラリを使用して、ウェブフォームから入力されたテキストとロゴ画像で、オリジナルのロゴ付きQRコードを生成する方法を解説します。ライブラリのインストールから、QRコードの見た目の設定、生成した画像の保存、ウェブページへの表示までを具体的に学べます。
開発環境
- Visual Studio Code:version 1.73.0
- OS:Windows10
- endroid/qr-code:4.6
PHPでQRコードを生成するライブラリ
PHPでQRコードを生成するためのライブラリは、大きく分けて以下の2つがよく使われています。ライブラリとは、特定の機能を実現するために、あらかじめ用意されたプログラムの部品集のことです。これらを使うことで、一からコードを書く手間を省き、効率的に開発を進めることができます。
-
endroid/qr-code: このライブラリは、非常に多くの機能を持ち、QRコードのデザインを細かく調整できる点が特徴です。例えば、ロゴ画像をQRコードの中央に追加したり、背景色やQRコードのドットの色を変更したりできます。また、出力形式もPNG、SVG、EPS、PDFなど、様々な形式に対応しているため、用途に応じて柔軟に使い分けられます。しかし、多くの機能を持つ分、このライブラリを動作させるために必要な他のプログラムの部品(依存関係)が比較的多くなる傾向があります。
-
chillerlan/php-qrcode: こちらは、シンプルさを追求した軽量なライブラリです。基本的なQRコードの生成に特化しており、余計な機能が少ないため、導入が簡単で、システムへの負荷も小さいという利点があります。出力形式はPNG画像のみですが、シンプルなQRコードを素早く生成したい場合には非常に適しています。必要な他のプログラムの部品(依存関係)もほとんどありません。
今回は、QRコードの中に会社のロゴなどを入れたいと考えているため、デザインの自由度が高いendroid/qr-codeを使用します。このライブラリを使うことで、見た目をカスタマイズしたオリジナルのQRコードを作成できるからです。
公式リポジトリ:https://github.com/endroid/qr-code
endroid/qr-codeの使い方
endroid/qr-codeは、PHPを使って簡単にQRコードを作成できるライブラリです。ここでは、基本的な使い方を解説していきます。
ライブラリをインストール
プログラムを作成する際は、まず作業用のフォルダを用意することが一般的です。このフォルダに、作成するプログラムや、今回利用するライブラリをまとめて管理します。
endroid/qr-codeを利用するためには、まずこのライブラリを作業フォルダにインストールする必要があります。PHPのプロジェクトでは、Composerというツールを使ってライブラリを管理するのが一般的です。Composerは、必要なライブラリを自動でダウンロードし、プログラムから利用できるようにしてくれる便利なツールです。
以下のコマンドを作業フォルダのターミナルで実行してください。
このコマンドを実行すると、endroid/qr-codeというライブラリがあなたの作業フォルダにインストールされ、PHPのプログラムから利用できるようになります。
1composer require endroid/qr-code
ビルトインサーバーを起動
作成したPHPプログラムが正しく動作するかをウェブブラウザで確認するために、ウェブサーバーを起動する必要があります。PHPには、開発時に手軽に利用できる「ビルトインサーバー」という簡易的なウェブサーバーが標準で備わっています。
以下のコマンドを作業フォルダのターミナルで実行してください。
このコマンドは、localhostというアドレスの8000番ポートでウェブサーバーを起動します。
サーバーが起動したら、ウェブブラウザを開き、アドレスバーに「http://localhost:8000/index.php」と入力してアクセスします。これにより、作成したindex.phpファイルの内容がブラウザに表示され、プログラムの動作を確認できるようになります。
1php -S localhost:8000
PHPでQRコードを生成する
次にPHPでQRコードを生成するサンプルコードを解説していきます。 今回はテキストとロゴ画像を入力するフォームを作り、送信するとロゴ付きのQRコードが表示されるようにします。
入力フォームのサンプルコード
下記はQRコードに埋め込むテキストとロゴ画像を送信するフォーム(index.php)です。
このコードは、ユーザーがQRコードにしたいテキストと、QRコードの中央に表示したいロゴ画像を選択するためのHTMLフォームを作成しています。
formタグのaction属性には、フォームが送信されたときにデータを受け取って処理するPHPファイルの名前(qrcode.php)を指定しています。
method="post"は、入力されたデータをURLに表示せずにサーバーに送る方法です。
enctype="multipart/form-data"は、ファイルをサーバーにアップロードする際に必ず指定する必要がある設定です。
input type="file"はファイルを選択する入力欄で、accept="image/*"を指定することで、ユーザーが選択できるファイルを画像ファイルだけに限定しています。
フォームの下にあるPHPの部分では、qrcode.phpからリダイレクトされてきた際に、URLのクエリパラメータ(?qrcode=...の部分)にQRコード画像のパスが含まれているかを確認しています。もしパスがあれば、そのパスを使って<img>タグを作成し、生成されたQRコード画像をブラウザに表示します。
htmlspecialcharsは、URLから受け取った文字列をそのまま表示すると、悪意のあるスクリプトが埋め込まれてしまう可能性があるため、それを防ぐために安全な形に変換する関数です。これはウェブアプリケーションのセキュリティ対策として非常に重要です。
1<!DOCTYPE html> 2<html lang="ja"> 3<head> 4 <meta charset="UTF-8"> 5 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 6 <title>QRコード生成</title> 7</head> 8<body> 9 <h1>QRコード生成</h1> 10 <form action="qrcode.php" method="post" enctype="multipart/form-data"> 11 <label for="data">QRコードに埋め込むテキスト:</label><br> 12 <input type="text" id="data" name="data" required><br><br> 13 14 <label for="logo">ロゴ画像を選択:</label><br> 15 <input type="file" id="logo" name="logo" accept="image/*"><br><br> 16 17 <input type="submit" value="QRコードを生成"> 18 </form> 19 20 <?php 21 if (isset($_GET['qrcode'])) { 22 echo '<h2>生成されたQRコード:</h2>'; 23 echo '<img src="' . htmlspecialchars($_GET['qrcode']) . '" alt="QR Code">'; 24 } 25 ?> 26</body> 27</html>
QRコード生成のサンプルコード
下記は送信された内容からQRコードを生成し、画像として保存するqrcode.phpです。
このqrcode.phpファイルは、index.phpから送信されたデータを受け取り、実際にQRコードを生成する処理を行います。
まず、require 'vendor/autoload.php';で、ComposerというツールでインストールしたQRコード生成のためのライブラリを読み込んでいます。これにより、QRコード生成に必要な様々な機能(クラス)を使えるようになります。
use ...の行では、これから使うクラスの完全な名前を省略して記述できるようにしています。
フォームから送信されたテキストデータは$_POST['data']で取得できます。ここでも、セキュリティのためにhtmlspecialcharsでエスケープ処理を行っています。
画像ファイルは$_FILES['logo']という特別な配列で受け取ります。$_FILES['logo']['error'] === UPLOAD_ERR_OKは、画像が正常にアップロードされたかを確認する条件です。正常にアップロードされていれば、一時的に保存されたファイルを指定のuploadsフォルダに移動させます。
次に、Builder::create()から始まる部分は、QRコードの設定を次々と指定していく部分です。これを「メソッドチェーン」と呼びます。
data($data)でQRコードに埋め込むテキストを設定し、size(300)でサイズ、margin(10)で余白などを設定しています。
もしロゴ画像がアップロードされていれば、if ($logoPath)のブロック内でロゴに関する設定(パス、サイズ、背景のくり抜き)を追加しています。
QRコードの設定が完了したら、$builder->build()で実際にQRコードの画像データを生成します。
生成された画像データは$result->getString()で取得し、file_put_contents関数を使ってuploadsフォルダ内にPNG画像として保存します。ファイル名はuniqid()を使って、重複しないユニークな名前を生成しています。
最後に、header('Location: index.php?qrcode=' . urlencode($qrCodePath));という行で、ユーザーのブラウザをindex.phpのページに転送(リダイレクト)しています。このとき、生成して保存したQRコードの画像パスをqrcodeという名前のクエリパラメータとして渡しています。urlencodeは、ファイルパスに含まれる可能性のある特殊な文字を、URLとして安全に扱える形式に変換する関数です。
exit;は、リダイレクトの指示を出した後、それ以上スクリプトが実行されないようにするために記述します。
画像の保存先として、作業用フォルダの中にuploadsフォルダを作成しておいてください。
1<?php 2require 'vendor/autoload.php'; 3 4use Endroid\QrCode\Builder\Builder; 5use Endroid\QrCode\Encoding\Encoding; 6use Endroid\QrCode\ErrorCorrectionLevel\ErrorCorrectionLevelHigh; 7use Endroid\QrCode\Label\Alignment\LabelAlignmentCenter; 8use Endroid\QrCode\Label\Font\NotoSans; 9use Endroid\QrCode\RoundBlockSizeMode\RoundBlockSizeModeMargin; 10use Endroid\QrCode\Writer\PngWriter; 11 12if (isset($_POST['data'])) { 13 $data = htmlspecialchars($_POST['data']); // ユーザー入力のデータを取得 14 15 // アップロードされた画像の処理 16 $logoPath = null; 17 if (isset($_FILES['logo']) && $_FILES['logo']['error'] === UPLOAD_ERR_OK) { 18 $uploadDir = __DIR__ . '/uploads/'; 19 $logoPath = $uploadDir . basename($_FILES['logo']['name']); 20 move_uploaded_file($_FILES['logo']['tmp_name'], $logoPath); 21 } 22 23 // QRコードを生成 24 $builder = Builder::create() 25 ->writer(new PngWriter()) 26 ->writerOptions([]) 27 ->data($data) // ユーザーが入力したデータをQRコードに 28 ->encoding(new Encoding('UTF-8')) 29 ->errorCorrectionLevel(new ErrorCorrectionLevelHigh()) 30 ->size(300) 31 ->margin(10) 32 ->roundBlockSizeMode(new RoundBlockSizeModeMargin()) 33 ->labelText($data) // ユーザーが入力したデータをラベルに設定 34 ->labelFont(new NotoSans(20)) 35 ->labelAlignment(new LabelAlignmentCenter()) 36 ->validateResult(false); 37 38 // ロゴが指定されている場合に追加 39 if ($logoPath) { 40 $builder->logoPath($logoPath) 41 ->logoResizeToWidth(50) 42 ->logoPunchoutBackground(true); 43 } 44 45 $result = $builder->build(); 46 47 // QRコードの画像を保存 48 $qrCodePath = 'uploads/qrcode_' . uniqid() . '.png'; 49 file_put_contents($qrCodePath, $result->getString()); 50 51 // index.phpにリダイレクトしてQRコード画像を表示 52 header('Location: index.php?qrcode=' . urlencode($qrCodePath)); 53 exit; 54} else { 55 echo 'データが指定されていません。'; 56}
ライブラリを読み込む
まずはComposerでインストールしたライブラリを読み込み、使用するクラスを指定します。
require 'vendor/autoload.php';は、Composerを使ってプロジェクトに組み込んだライブラリのファイルを自動的に読み込むための記述です。これにより、自分で一つずつrequire文を書かなくても、ライブラリの機能を使えるようになります。
use ...の行は、PHPの「名前空間」という仕組みを使って、長いクラス名を短く書けるようにするものです。例えば、Endroid\QrCode\Builder\Builderという長い名前のクラスを、Builderという名前だけで使えるようになります。
それぞれ以下の役割があります。
Builder:QRコードの様々な属性(データ、サイズ、色など)や設定をまとめて指定し、生成を開始するための主要なクラスです。Encoding:QRコードに埋め込むデータの文字コード(文字の表現方法)を指定するために使います。ここではUTF-8を指定しています。ErrorCorrectionLevelHigh:QRコードの一部が汚れたり破損したりしても、どれくらいの精度で情報を復元できるか(誤り訂正レベル)を指定します。Highは高い訂正レベルを示します。LabelAlignmentCenter:QRコードの下に表示するテキスト(ラベル)を、中央に配置するために使います。NotoSans:ラベルに使うフォントの種類を指定します。ここではNoto Sansというフォントを使っています。RoundBlockSizeModeMargin:QRコードを構成する四角いブロックのサイズを、周囲の余白とのバランスを考慮して調整するために使います。PngWriter:生成されたQRコードの画像をPNG形式で出力するためのクラスです。
1require 'vendor/autoload.php'; 2 3use Endroid\QrCode\Builder\Builder; 4use Endroid\QrCode\Encoding\Encoding; 5use Endroid\QrCode\ErrorCorrectionLevel\ErrorCorrectionLevelHigh; 6use Endroid\QrCode\Label\Alignment\LabelAlignmentCenter; 7use Endroid\QrCode\Label\Font\NotoSans; 8use Endroid\QrCode\RoundBlockSizeMode\RoundBlockSizeModeMargin; 9use Endroid\QrCode\Writer\PngWriter;
アップロードされたロゴ画像を保存する
次に、フォームから送信されたロゴ画像をuploadsフォルダに保存します。
この部分では、ユーザーがフォームでロゴ画像を選択したかどうか、そしてその画像がサーバーに正しくアップロードされたかを確認し、uploadsフォルダに保存しています。
$_FILESは、HTMLフォームからファイルがアップロードされたときに、そのファイルに関する情報が格納されるPHPの特別な変数(スーパーグローバル変数)です。$_FILES['logo']は、フォームのname="logo"で指定されたファイルの情報を含んでいます。
isset($_FILES['logo'])は、ユーザーがロゴファイルを選択したかを確認します。
$_FILES['logo']['error'] === UPLOAD_ERR_OKは、アップロード中にエラーが発生せず、ファイルが正常にサーバーの一時領域に保存されたことを確認する条件です。UPLOAD_ERR_OKは、エラーがないことを示すPHPの定数です。
もしファイルが正常にアップロードされていれば、まず保存先のディレクトリパスを定義します。__DIR__は、現在実行されているPHPファイルがあるディレクトリの絶対パスを示すPHPの定数です。これに/uploads/を結合して、アップロードディレクトリのパス$uploadDirを作成します。
basename($_FILES['logo']['name'])は、アップロードされたファイルの元の名前から、ディレクトリパスを除いたファイル名だけを取り出す関数です。例えば、/path/to/image.pngというパスからimage.pngだけを取り出します。
最後にmove_uploaded_file($_FILES['logo']['tmp_name'], $logoPath);という関数を使って、サーバーの一時的な保存場所(tmp_name)にあるファイルを、指定したuploadsフォルダの$logoPathへ移動させています。
1$logoPath = null; 2if (isset($_FILES['logo']) && $_FILES['logo']['error'] === UPLOAD_ERR_OK) { 3 $uploadDir = __DIR__ . '/uploads/'; 4 $logoPath = $uploadDir . basename($_FILES['logo']['name']); 5 move_uploaded_file($_FILES['logo']['tmp_name'], $logoPath); 6}
QRコードを生成する
次に、BuilderでQRコードを生成します。
この部分では、QRコードの外観や内容に関する様々な設定を行っています。Builder::create()から始まり、それぞれの設定を.メソッド名(値)のように連続して記述していく方法を「メソッドチェーン」と呼びます。これは、オブジェクト指向プログラミングでよく使われる記述スタイルです。
writer(new PngWriter()):生成するQRコードの画像形式をPNGに指定しています。writerOptions([]):PNG形式の書き出しに関する追加オプションがあればここに記述しますが、ここでは特に指定していません。data($data):QRコードに埋め込む実際の情報(データ)を指定します。ここではフォームから受け取った$data変数の中身を設定しています。encoding(new Encoding('UTF-8')):QRコードに埋め込むデータの文字コードをUTF-8に指定しています。日本語を含むテキストを扱う場合に重要です。errorCorrectionLevel(new ErrorCorrectionLevelHigh()):QRコードの一部が破損しても読み取れるようにするための誤り訂正レベルを「高」に設定しています。size(300):生成されるQRコードの画像サイズを300ピクセルに設定しています。margin(10):QRコードの周囲に10ピクセルの余白を設けるように指定しています。roundBlockSizeMode(new RoundBlockSizeModeMargin()):QRコードを構成する四角いブロックのサイズを、余白を考慮して調整するモードを指定しています。labelText($data):QRコードの下に表示するテキスト(ラベル)を指定します。ここでもフォームから入力された$data変数の中身を使っています。labelFont(new NotoSans(20)):ラベルのフォントとしてNoto Sansを指定し、フォントサイズを20ピクセルに設定しています。labelAlignment(new LabelAlignmentCenter()):ラベルのテキストを中央揃えに配置するように指定しています。validateResult(false):通常、QRコード生成後にそのQRコードが正しく読み取れるか自動で検証しますが、falseに設定することでその検証を行わずにQRコードを返します。これにより処理をわずかに高速化できます。
1$builder = Builder::create() 2 ->writer(new PngWriter()) 3 ->writerOptions([]) 4 ->data($data) 5 ->encoding(new Encoding('UTF-8')) 6 ->errorCorrectionLevel(new ErrorCorrectionLevelHigh()) 7 ->size(300) 8 ->margin(10) 9 ->roundBlockSizeMode(new RoundBlockSizeModeMargin()) 10 ->labelText($data) 11 ->labelFont(new NotoSans(20)) 12 ->labelAlignment(new LabelAlignmentCenter()) 13 ->validateResult(false);
ロゴを追加する
ロゴ画像が保存されている場合は、$builderにロゴの設定を追加します。
この部分では、ユーザーがロゴ画像をアップロードした場合にのみ、QRコードにロゴを追加する設定を行っています。
if ($logoPath)は、$logoPath変数に何らかのパス(値)が設定されていれば(つまり、ロゴ画像が正常にアップロードされていれば)ブロック内の処理を実行するという条件分岐です。
logoPath($logoPath):QRコードの中央に配置するロゴ画像のファイルパスを指定します。$logoPathには、先にuploadsフォルダに保存したロゴ画像の絶対パスが入っています。logoResizeToWidth(50):ロゴ画像の横幅を50ピクセルに縮小するように指定しています。元の画像のサイズに関わらず、QRコード内で適切なサイズに調整されます。logoPunchoutBackground(true):ロゴの背景部分を透明にして、QRコードのデータ部分が隠れすぎないように配置する設定です。これにより、ロゴがQRコードに自然に溶け込み、QRコードの読み取り性能への影響を最小限に抑えます。
1if ($logoPath) { 2 $builder->logoPath($logoPath) 3 ->logoResizeToWidth(50) 4 ->logoPunchoutBackground(true); 5}
QRコードを保存して表示する
最後に、生成したQRコードを画像として保存し、index.phpにリダイレクトして表示します。
ここでは、設定に基づいたQRコードを実際に生成し、ファイルとして保存してから、結果をユーザーに見せるための処理を行っています。
$result = $builder->build();:ここまでの$builderオブジェクトに設定した内容に基づいて、最終的なQRコードの画像データを生成します。このbuild()メソッドが実際にQRコードを作成する処理を実行します。
$qrCodePath = 'uploads/qrcode_' . uniqid() . '.png';:生成されたQRコード画像を保存するためのファイル名を定義しています。uniqid()関数は、重複しないユニークな文字列を生成するために使われます。これにより、複数のユーザーが同時にQRコードを生成しても、ファイル名が衝突するのを防ぐことができます。ファイルはuploadsフォルダの中に、qrcode_という接頭辞とユニークID、そして.pngという拡張子を付けて保存されます。
file_put_contents($qrCodePath, $result->getString());:file_put_contents関数は、指定されたファイルにデータを書き込むための関数です。ここでは、$qrCodePathで指定されたファイル名で、$result->getString()で取得したQRコードの画像データ(バイナリデータ)を書き込み、PNG画像として保存しています。
header('Location: index.php?qrcode=' . urlencode($qrCodePath));:この行は、ブラウザを別のページに転送する(リダイレクトする)ためのHTTPヘッダーを送信しています。ユーザーはqrcode.phpの処理が終わった後、自動的にindex.phpに戻されます。
index.phpへ戻る際、URLのクエリパラメータとして?qrcode=に、保存したQRコードのファイルパス$qrCodePathを渡しています。urlencode()は、ファイルパスに含まれる可能性があるスラッシュ(/)などの特殊文字を、URLで安全に扱える形式に変換するために使用します。
exit;:header()関数でリダイレクトの指示を出した後は、それ以降のPHPスクリプトの処理は不要となるため、ここでスクリプトの実行を終了させています。これを忘れると、意図しない処理が実行されてしまったり、セキュリティ上の問題が発生したりする可能性があります。
この一連の処理により、テキストだけを入力した場合は文字情報が入ったQRコードが生成され、ロゴも選択した場合は中央にロゴが入ったQRコードが生成されて、index.phpの画面に表示されます。
1$result = $builder->build(); 2 3$qrCodePath = 'uploads/qrcode_' . uniqid() . '.png'; 4file_put_contents($qrCodePath, $result->getString()); 5 6header('Location: index.php?qrcode=' . urlencode($qrCodePath)); 7exit;
おわりに
この記事では、PHPのendroid/qr-codeライブラリを使って、ロゴ付きQRコードを生成する手順を学びました。Composerでのライブラリ導入から始め、ウェブフォームから入力されたテキストとロゴ画像をqrcode.phpで受け取る方法を確認しました。そして、Builderクラスを使い、メソッドチェーン形式でQRコードのデータ、サイズ、ロゴ、ラベルテキストといった外観を細かく設定しました。最終的に、生成されたQRコード画像をファイルとして保存し、index.phpにリダイレクトして表示するまでの一連の流れを理解できたことと思います。この知識は、皆さんがシステムエンジニアとして様々なWebアプリケーションを開発する際の基礎力となるでしょう。