【PHP】QRコードを作成するAPI

API

QRコードを出力するAPIを作成しました。composerの使い方に慣れていないので、使い方が間違っていればご指摘ください。
OPEN環境で公開するのはもう少しテストをしてからにします。

●環境

 ・クライアント
  Windows11 
 ・サーバ(VMware上)
  ubuntu 24.04 (IP 192.168.19.129)
  PHP 8.3.6
  Composer 2.7.6
  Apache 2.4.58

●APIの仕様

 POSTメソッドで文字列を送信すると、QRコードのpngを生成しダウンロードできる仕組みです。
 生成に失敗した場合は、JSONを返します。

●プロジェクトの作成

 ①次のコマンドでapiを置くためのフォルダを作成します。

$> sudo mkdir -m 777 /var/www/html/api/qrcode

パーミッション777を指定するのが怖いのですが、QRコードの画像ファイルを保存する仕様上、777が必要です…

 ②composerプロジェクトを作成し、初期設定を行います  

$ > cd /var/www/html/api/qrcode
$ > composer init
                                         
  Welcome to the Composer config generator 
This command will guide you through creating your composer.json config.
# パッケージの名前を指定してください
Package name (<vendor>/<name>) [ub-axis/qrcode]: tansu/qrcode-generator
# プロジェクトの説明を入力してください
Description []: generate qrcode
# 作成者の名前を入力してください
Author [n to skip]: kirabbit
#dev :開発版 stable :リリース版
Minimum Stability []: stable
Package Type (e.g. library, project, metapackage, composer-plugin) []: project
# MIT オープンソース
License []: MIT

Define your dependencies.

Would you like to define your dependencies (require) interactively [yes]? no
Would you like to define your dev dependencies (require-dev) interactively [yes]? no
Add PSR-4 autoload mapping? Maps namespace "Tansu\QrcodeGenerator" to the entered relative path. [src/, n to skip]: src/

{
    "name": "tansu/qrcode-generator",
    "description": "generate qrcode",
    "type": "project",
    "license": "MIT",
    "autoload": {
        "psr-4": {
            "Tansu\\QrcodeGenerator\\": "src/"
        }
    },
    "authors": [
        {
            "name": "kirabbit"
        }
    ],
    "minimum-stability": "stable",
    "require": {}
}

Do you confirm generation [yes]? y
Generating autoload files
Generated autoload files
PSR-4 autoloading configured. Use "namespace Tansu\QrcodeGenerator;" in src/
Include the Composer autoloader with: require 'vendor/autoload.php';
#プロジェクトの作成が完了

# QRコードライブラリのインポート
$> composer require endroid/qr-code
./composer.json has been updated
Running composer update endroid/qr-code
Loading composer repositories with package information
Updating dependencies
Lock file operations: 3 installs, 0 updates, 0 removals
  - Locking bacon/bacon-qr-code (v3.0.0)
  - Locking dasprid/enum (1.0.5)
  - Locking endroid/qr-code (5.0.9)
Writing lock file
Installing dependencies from lock file (including require-dev)
Package operations: 3 installs, 0 updates, 0 removals
  - Installing dasprid/enum (1.0.5): Extracting archive
  - Installing bacon/bacon-qr-code (v3.0.0): Extracting archive
  - Installing endroid/qr-code (5.0.9): Extracting archive
3 package suggestions were added by new dependencies, use `composer suggest` to see details.
Generating autoload files
1 package you are using is looking for funding.
Use the `composer fund` command to find out more!
No security vulnerability advisories found.
Using version ^5.0 for endroid/qr-code

③ソースプログラムを配置

次のソースを配置しました。 
配置先は、
/var/www/html/api/qrcode/qrcode.php
で、パーミッションは755としました。

<?php

require 'vendor/autoload.php';

use Endroid\QrCode\Builder\Builder;
use Endroid\QrCode\Encoding\Encoding;
use Endroid\QrCode\ErrorCorrectionLevel;
use Endroid\QrCode\RoundBlockSizeMode;
use Endroid\QrCode\Writer\PngWriter;

header('Content-Type: application/json');

if ($_SERVER['REQUEST_METHOD'] == 'POST') {
    // フォームから送信されたデータを取得
    if (isset($_POST['text']) && !empty($_POST['text'])) {
        try {
            $qrCode = Builder::create()
                ->writer(new PngWriter())
                ->data($_POST['text'])
                ->encoding(new Encoding('UTF-8'))
                ->errorCorrectionLevel(ErrorCorrectionLevel::High)
                ->size(300)
                ->margin(10)
                ->roundBlockSizeMode(RoundBlockSizeMode::Margin)
                ->build();
            
            // 結果をpingファイルに出力
            $filename = 'qrcode_' . time() . '.png';
            $qrCode->saveToFile(__DIR__ . '/' . $filename);

            // ダウンロードするファイルの名前を指定
            $download_filename = 'qr_code.png';
            
            // Content-Type を指定します
            header('Content-Type: application/file');
            
            // ダウンロードするファイルのサイズを指定します
            header('Content-Length: ' . filesize(__DIR__ . '/' . $filename));
            
            // ダウンロードファイルの名前を指定します
            header('Content-Disposition: attachment; filename="' . $download_filename . '"');
            
            // ファイルの内容を出力します
            readfile(__DIR__ . '/' . $filename);
            
            // ファイルを削除します
            unlink(__DIR__ . '/' . $filename);

            echo json_encode([
                'status' => 'success',
                'message' => 'QR code generated successfully.',
            ]);
            
        } catch (Exception $e) {
            echo json_encode([
                'status' => 'error',
                'message' => 'Failed to generate QR code: ' . $e->getMessage()
            ]);
        }
    } else {
        echo json_encode([
            'status' => 'error',
            'message' => 'Invalid input data.'
        ]);
    }
} else {
    echo json_encode([
        'status' => 'error',
        'message' => 'Invalid request method.'
    ]);
}

APIを呼び出すためのHTMLは次のようにしました。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>QR Code Generator</title>
</head>
<body>
    <form action="http://192.168.19.129/api/qrcode/qrcode.php" method="POST">
        <label for="text">Text for QR Code:</label>
        <input type="text" id="text" name="text" required>
        <button type="submit">Generate QR Code</button>
    </form>
</body>
</html>

④Apacheの再起動

webサーバのApacheは次のコマンドで再起動させます

$> sudo service apache2 restart

●実行結果

クライアントの様子

適当な文字列を入力して「GenerateQRCode」をクリックすると

pngファイルのダウンロードが始まります。

出来上がったQRコードはこんな感じです。

携帯電話から読み込むと、「abcdefg」と表示されていることを確認しました。

●注意書き

 composerを使ったプロジェクトを作るのは初めてだったので、セキュリティ的にこれでいいのか不安な気持ちです。
 とりあえずは動いていますので、ローカル環境での実験は十分ですが、公開するにはもう少しテストを繰り返してからにする必要があるかと思っています。