Public Holidays Coupon Code Code Compiler

How To Generate QR Code Dynamically using PHP


Oct 1, 2025

How To Generate QR Code Dynamically using PHP

QR codes have become an essential part of modern digital communication, enabling quick access to information through smartphones and other devices. In this comprehensive guide, you'll learn how to generate QR codes dynamically using PHP, allowing you to create custom QR codes for URLs, text, contact information, and more without relying on external services.

Whether you're building a ticketing system, creating digital business cards, or implementing a product tracking solution, this tutorial will walk you through the entire process step by step, from installation to implementation.

What is a QR Code?

A QR (Quick Response) code is a two-dimensional barcode that can store various types of information such as text, URLs, contact details, or any other data format. When scanned with a smartphone camera or QR code reader, it instantly displays or processes the encoded information.

QR codes offer several advantages including fast readability, error correction capabilities, and the ability to store more data compared to traditional barcodes. They're widely used in marketing, payment systems, authentication, and inventory management.

Prerequisites

Before we begin, ensure you have the following installed on your system:

  • PHP 7.4 or higher - The programming language we'll use
  • Composer - PHP dependency manager for installing libraries
  • Web server - Apache, Nginx, or PHP built-in server
  • Basic PHP knowledge - Understanding of PHP syntax and functions

Method 1: Using PHP QR Code Library (Recommended)

The most efficient way to generate QR codes in PHP is by using the phpqrcode library. This method provides excellent customization options and doesn't require any external API calls.

Step 1: Install the PHP QR Code Library

First, create a new directory for your project. Open your terminal or command prompt and navigate to your project folder:

mkdir qr-code-generator
cd qr-code-generator

Now, install the phpqrcode library using Composer:

composer require chillerlan/php-qrcode
Note: If you don't have Composer installed, you can download the phpqrcode library manually from GitHub and include it in your project using require statements.

Step 2: Create the QR Code Generator Script

Create a new file named generate_qr.php in your project root directory. This file will contain the main logic for generating QR codes.

<?php
require_once 'vendor/autoload.php';

use chillerlan\QRCode\QRCode;
use chillerlan\QRCode\QROptions;

// Configure QR code options
$options = new QROptions([
    'version'      => 5,
    'outputType'   => QRCode::OUTPUT_IMAGE_PNG,
    'eccLevel'     => QRCode::ECC_L,
    'scale'        => 10,
    'imageBase64'  => false,
]);

// Initialize QR code generator
$qrcode = new QRCode($options);

// Data to encode in QR code
$data = 'https://www.example.com';

// Generate and save QR code
$qrcode->render($data, 'qrcode.png');

echo "QR Code generated successfully!";
?>

This script creates a QR code that encodes a URL. The generated QR code will be saved as qrcode.png in the same directory.

Step 3: Create a Web Interface

Now let's create a user-friendly HTML form where users can input their data. Create a new file named index.php in your project directory:

<?php
require_once 'vendor/autoload.php';

use chillerlan\QRCode\QRCode;
use chillerlan\QRCode\QROptions;

$qrCodeImage = '';
$message = '';

if ($_SERVER['REQUEST_METHOD'] === 'POST' && !empty($_POST['data'])) {
    $data = htmlspecialchars($_POST['data']);
    
    // Configure QR code options
    $options = new QROptions([
        'version'      => 5,
        'outputType'   => QRCode::OUTPUT_IMAGE_PNG,
        'eccLevel'     => QRCode::ECC_L,
        'scale'        => 10,
        'imageBase64'  => true,
    ]);
    
    // Generate QR code
    $qrcode = new QRCode($options);
    $qrCodeImage = $qrcode->render($data);
    $message = 'QR Code generated successfully!';
}
?>

<!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>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
        
        body {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            min-height: 100vh;
            display: flex;
            justify-content: center;
            align-items: center;
            padding: 20px;
        }
        
        .container {
            background: white;
            padding: 40px;
            border-radius: 15px;
            box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
            max-width: 500px;
            width: 100%;
        }
        
        h1 {
            color: #333;
            margin-bottom: 30px;
            text-align: center;
        }
        
        .form-group {
            margin-bottom: 25px;
        }
        
        label {
            display: block;
            margin-bottom: 8px;
            color: #555;
            font-weight: 600;
        }
        
        input[type="text"],
        textarea {
            width: 100%;
            padding: 12px;
            border: 2px solid #ddd;
            border-radius: 8px;
            font-size: 16px;
            transition: border-color 0.3s;
        }
        
        input[type="text"]:focus,
        textarea:focus {
            outline: none;
            border-color: #667eea;
        }
        
        textarea {
            min-height: 100px;
            resize: vertical;
        }
        
        button {
            width: 100%;
            padding: 15px;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
            border: none;
            border-radius: 8px;
            font-size: 18px;
            font-weight: 600;
            cursor: pointer;
            transition: transform 0.2s;
        }
        
        button:hover {
            transform: translateY(-2px);
        }
        
        .result {
            margin-top: 30px;
            text-align: center;
        }
        
        .message {
            color: #28a745;
            font-weight: 600;
            margin-bottom: 20px;
        }
        
        .qr-code img {
            max-width: 100%;
            border-radius: 10px;
            box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>QR Code Generator</h1>
        
        <form method="POST">
            <div class="form-group">
                <label for="data">Enter Text or URL:</label>
                <textarea 
                    name="data" 
                    id="data" 
                    placeholder="https://www.example.com or any text..."
                    required
                ></textarea>
            </div>
            
            <button type="submit">Generate QR Code</button>
        </form>
        
        <?php if ($qrCodeImage): ?>
        <div class="result">
            <p class="message"><?php echo $message; ?></p>
            <div class="qr-code">
                <img src="<?php echo $qrCodeImage; ?>" alt="Generated QR Code">
            </div>
        </div>
        <?php endif; ?>
    </div>
</body>
</html>

Step 4: Run the Application

Start the PHP built-in server by running this command in your project directory:

php -S localhost:8000

Open your web browser and navigate to http://localhost:8000. You should see the QR code generator interface.

Method 2: Using Google Charts API

An alternative method is to use the Google Charts API. While this method is simpler, it requires an internet connection and depends on an external service.

Create API-Based Generator

Create a new file named google_qr.php:

<?php
function generateQRCode($data, $size = 300) {
    $encodedData = urlencode($data);
    $apiUrl = "https://chart.googleapis.com/chart?chs={$size}x{$size}&cht=qr&chl={$encodedData}&choe=UTF-8";
    return $apiUrl;
}

$qrCodeUrl = '';
if ($_SERVER['REQUEST_METHOD'] === 'POST' && !empty($_POST['data'])) {
    $data = htmlspecialchars($_POST['data']);
    $qrCodeUrl = generateQRCode($data);
}
?>

<!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 - Google API</title>
</head>
<body>
    <h1>QR Code Generator (Google API)</h1>
    
    <form method="POST">
        <label>Enter Data:</label>
        <input type="text" name="data" required>
        <button type="submit">Generate</button>
    </form>
    
    <?php if ($qrCodeUrl): ?>
        <h2>Your QR Code:</h2>
        <img src="<?php echo $qrCodeUrl; ?>" alt="QR Code">
    <?php endif; ?>
</body>
</html>
Important: Google Charts API has been deprecated for new projects. It's recommended to use Method 1 with the phpqrcode library for production applications.

Advanced Customization Options

The phpqrcode library offers extensive customization options. Here's how to create a more advanced QR code generator:

Customizing QR Code Appearance

Create a file named advanced_qr.php:

<?php
require_once 'vendor/autoload.php';

use chillerlan\QRCode\QRCode;
use chillerlan\QRCode\QROptions;

// Advanced configuration
$options = new QROptions([
    'version'           => 7,
    'outputType'        => QRCode::OUTPUT_IMAGE_PNG,
    'eccLevel'          => QRCode::ECC_H, // High error correction
    'scale'             => 15,
    'imageBase64'       => false,
    'moduleValues'      => [
        // Data modules
        1024 => [0, 0, 0],      // Dark modules (black)
        4    => [255, 255, 255], // Light modules (white)
    ],
    'drawCircularModules' => true,
    'circleRadius'        => 0.45,
    'keepAsSquare'        => [
        QRCode::IS_FINDER,
        QRCode::IS_FINDER_DOT,
    ],
]);

$qrcode = new QRCode($options);

// Generate QR code with custom data
$data = 'https://www.yourwebsite.com';
$qrcode->render($data, 'custom_qrcode.png');

echo "Custom QR Code generated!";
?>

Saving QR Codes to Database

For applications that need to track generated QR codes, you can save them to a database. First, create a database table:

CREATE TABLE qr_codes (
    id INT AUTO_INCREMENT PRIMARY KEY,
    data TEXT NOT NULL,
    qr_image LONGBLOB NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

Now create save_qr.php to save QR codes to the database:

<?php
require_once 'vendor/autoload.php';

use chillerlan\QRCode\QRCode;
use chillerlan\QRCode\QROptions;

// Database configuration
$host = 'localhost';
$dbname = 'your_database';
$username = 'your_username';
$password = 'your_password';

try {
    $pdo = new PDO("mysql:host=$host;dbname=$dbname", $username, $password);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    
    if ($_SERVER['REQUEST_METHOD'] === 'POST' && !empty($_POST['data'])) {
        $data = htmlspecialchars($_POST['data']);
        
        // Generate QR code
        $options = new QROptions([
            'outputType' => QRCode::OUTPUT_IMAGE_PNG,
            'imageBase64' => false,
        ]);
        
        $qrcode = new QRCode($options);
        $qrImage = $qrcode->render($data);
        
        // Save to database
        $stmt = $pdo->prepare("INSERT INTO qr_codes (data, qr_image) VALUES (?, ?)");
        $stmt->execute([$data, $qrImage]);
        
        echo "QR Code saved to database successfully!";
    }
} catch (PDOException $e) {
    echo "Database Error: " . $e->getMessage();
}
?>

Creating Downloadable QR Codes

To allow users to download generated QR codes, create a file named download_qr.php:

<?php
require_once 'vendor/autoload.php';

use chillerlan\QRCode\QRCode;
use chillerlan\QRCode\QROptions;

if (isset($_GET['data']) && !empty($_GET['data'])) {
    $data = htmlspecialchars($_GET['data']);
    
    // Configure QR code options
    $options = new QROptions([
        'version'      => 5,
        'outputType'   => QRCode::OUTPUT_IMAGE_PNG,
        'eccLevel'     => QRCode::ECC_L,
        'scale'        => 10,
        'imageBase64'  => false,
    ]);
    
    // Generate QR code
    $qrcode = new QRCode($options);
    $qrImage = $qrcode->render($data);
    
    // Set headers for download
    header('Content-Type: image/png');
    header('Content-Disposition: attachment; filename="qrcode_' . time() . '.png"');
    header('Content-Length: ' . strlen($qrImage));
    
    echo $qrImage;
    exit;
} else {
    echo "No data provided!";
}
?>

Add a download button to your main form in index.php:

<a href="download_qr.php?data=<?php echo urlencode($data); ?>" 
   download class="download-btn">
    Download QR Code
</a>

Generating Different Types of QR Codes

QR codes can encode various types of information. Here are some common formats:

URL QR Code

<?php
$url = "https://www.example.com";
$qrcode->render($url, 'url_qrcode.png');
?>

Email QR Code

<?php
$email = "mailto:contact@example.com?subject=Hello&body=Message";
$qrcode->render($email, 'email_qrcode.png');
?>

Phone Number QR Code

<?php
$phone = "tel:+1234567890";
$qrcode->render($phone, 'phone_qrcode.png');
?>

WiFi QR Code

<?php
$wifi = "WIFI:T:WPA;S:NetworkName;P:Password123;;";
$qrcode->render($wifi, 'wifi_qrcode.png');
?>

vCard (Contact) QR Code

<?php
$vcard = "BEGIN:VCARD\n";
$vcard .= "VERSION:3.0\n";
$vcard .= "FN:John Doe\n";
$vcard .= "TEL:+1234567890\n";
$vcard .= "EMAIL:john@example.com\n";
$vcard .= "END:VCARD";

$qrcode->render($vcard, 'vcard_qrcode.png');
?>

Complete Multi-Type QR Generator

Let's create a comprehensive QR code generator that supports multiple data types. Create a file named multi_qr_generator.php:

<?php
require_once 'vendor/autoload.php';

use chillerlan\QRCode\QRCode;
use chillerlan\QRCode\QROptions;

$qrCodeImage = '';
$message = '';

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $type = $_POST['type'] ?? '';
    $data = '';
    
    switch ($type) {
        case 'url':
            $data = htmlspecialchars($_POST['url']);
            break;
            
        case 'email':
            $email = htmlspecialchars($_POST['email']);
            $subject = htmlspecialchars($_POST['subject'] ?? '');
            $body = htmlspecialchars($_POST['body'] ?? '');
            $data = "mailto:$email?subject=$subject&body=$body";
            break;
            
        case 'phone':
            $phone = htmlspecialchars($_POST['phone']);
            $data = "tel:$phone";
            break;
            
        case 'sms':
            $phone = htmlspecialchars($_POST['sms_phone']);
            $message_text = htmlspecialchars($_POST['sms_message']);
            $data = "sms:$phone?body=$message_text";
            break;
            
        case 'wifi':
            $ssid = htmlspecialchars($_POST['wifi_ssid']);
            $password = htmlspecialchars($_POST['wifi_password']);
            $encryption = htmlspecialchars($_POST['wifi_encryption']);
            $data = "WIFI:T:$encryption;S:$ssid;P:$password;;";
            break;
            
        case 'text':
            $data = htmlspecialchars($_POST['text']);
            break;
            
        default:
            $message = 'Invalid type selected!';
            break;
    }
    
    if (!empty($data)) {
        $options = new QROptions([
            'version'      => 5,
            'outputType'   => QRCode::OUTPUT_IMAGE_PNG,
            'eccLevel'     => QRCode::ECC_L,
            'scale'        => 10,
            'imageBase64'  => true,
        ]);
        
        $qrcode = new QRCode($options);
        $qrCodeImage = $qrcode->render($data);
        $message = 'QR Code generated successfully!';
    }
}
?>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Multi-Type QR Code Generator</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            max-width: 800px;
            margin: 50px auto;
            padding: 20px;
        }
        
        .form-section {
            display: none;
            margin-top: 20px;
            padding: 20px;
            border: 1px solid #ddd;
            border-radius: 5px;
        }
        
        .form-section.active {
            display: block;
        }
        
        input, textarea, select {
            width: 100%;
            padding: 10px;
            margin: 10px 0;
            border: 1px solid #ddd;
            border-radius: 4px;
        }
        
        button {
            background: #667eea;
            color: white;
            padding: 12px 30px;
            border: none;
            border-radius: 5px;
            cursor: pointer;
        }
    </style>
</head>
<body>
    <h1>Multi-Type QR Code Generator</h1>
    
    <select id="qrType" onchange="showForm(this.value)">
        <option value="">Select QR Type</option>
        <option value="url">URL</option>
        <option value="email">Email</option>
        <option value="phone">Phone</option>
        <option value="sms">SMS</option>
        <option value="wifi">WiFi</option>
        <option value="text">Plain Text</option>
    </select>
    
    <!-- URL Form -->
    <form method="POST" class="form-section" id="urlForm">
        <input type="hidden" name="type" value="url">
        <input type="url" name="url" placeholder="https://www.example.com" required>
        <button type="submit">Generate QR Code</button>
    </form>
    
    <!-- Email Form -->
    <form method="POST" class="form-section" id="emailForm">
        <input type="hidden" name="type" value="email">
        <input type="email" name="email" placeholder="Email Address" required>
        <input type="text" name="subject" placeholder="Subject (optional)">
        <textarea name="body" placeholder="Message (optional)"></textarea>
        <button type="submit">Generate QR Code</button>
    </form>
    
    <!-- Phone Form -->
    <form method="POST" class="form-section" id="phoneForm">
        <input type="hidden" name="type" value="phone">
        <input type="tel" name="phone" placeholder="+1234567890" required>
        <button type="submit">Generate QR Code</button>
    </form>
    
    <!-- SMS Form -->
    <form method="POST" class="form-section" id="smsForm">
        <input type="hidden" name="type" value="sms">
        <input type="tel" name="sms_phone" placeholder="+1234567890" required>
        <textarea name="sms_message" placeholder="Message" required></textarea>
        <button type="submit">Generate QR Code</button>
    </form>
    
    <!-- WiFi Form -->
    <form method="POST" class="form-section" id="wifiForm">
        <input type="hidden" name="type" value="wifi">
        <input type="text" name="wifi_ssid" placeholder="Network Name (SSID)" required>
        <input type="text" name="wifi_password" placeholder="Password" required>
        <select name="wifi_encryption" required>
            <option value="WPA">WPA/WPA2</option>
            <option value="WEP">WEP</option>
            <option value="nopass">No Password</option>
        </select>
        <button type="submit">Generate QR Code</button>
    </form>
    
    <!-- Text Form -->
    <form method="POST" class="form-section" id="textForm">
        <input type="hidden" name="type" value="text">
        <textarea name="text" placeholder="Enter any text" required></textarea>
        <button type="submit">Generate QR Code</button>
    </form>
    
    <?php if ($qrCodeImage): ?>
    <div style="margin-top: 30px; text-align: center;">
        <p style="color: green; font-weight: bold;"><?php echo $message; ?></p>
        <img src="<?php echo $qrCodeImage; ?>" alt="QR Code">
    </div>
    <?php endif; ?>
    
    <script>
        function showForm(type) {
            document.querySelectorAll('.form-section').forEach(form => {
                form.classList.remove('active');
            });
            
            if (type) {
                document.getElementById(type + 'Form').classList.add('active');
            }
        }
    </script>
</body>
</html>

Error Handling and Validation

It's important to implement proper error handling and input validation. Create a file named secure_qr_generator.php:

<?php
require_once 'vendor/autoload.php';

use chillerlan\QRCode\QRCode;
use chillerlan\QRCode\QROptions;

class QRCodeGenerator {
    private $qrcode;
    private $errors = [];
    
    public function __construct() {
        $options = new QROptions([
            'version'      => 5,
            'outputType'   => QRCode::OUTPUT_IMAGE_PNG,
            'eccLevel'     => QRCode::ECC_L,
            'scale'        => 10,
            'imageBase64'  => true,
        ]);
        
        $this->qrcode = new QRCode($options);
    }
    
    public function validateData($data, $maxLength = 1000) {
        if (empty($data)) {
            $this->errors[] = "Data cannot be empty";
            return false;
        }
        
        if (strlen($data) > $maxLength) {
            $this->errors[] = "Data exceeds maximum length of $maxLength characters";
            return false;
        }
        
        return true;
    }
    
    public function validateURL($url) {
        if (!filter_var($url, FILTER_VALIDATE_URL)) {
            $this->errors[] = "Invalid URL format";
            return false;
        }
        return true;
    }
    
    public function validateEmail($email) {
        if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
            $this->errors[] = "Invalid email format";
            return false;
        }
        return true;
    }
    
    public function generate($data) {
        try {
            if (!$this->validateData($data)) {
                return false;
            }
            
            return $this->qrcode->render($data);
        } catch (Exception $e) {
            $this->errors[] = "QR Code generation failed: " . $e->getMessage();
            return false;
        }
    }
    
    public function getErrors() {
        return $this->errors;
    }
}

// Usage example
$generator = new QRCodeGenerator();
$qrCodeImage = '';
$errors = [];

if ($_SERVER['REQUEST_METHOD'] === 'POST' && !empty($_POST['data'])) {
    $data = htmlspecialchars($_POST['data']);
    
    $qrCodeImage = $generator->generate($data);
    
    if (!$qrCodeImage) {
        $errors = $generator->getErrors();
    }
}
?>

Best Practices and Tips

Performance Optimization:
  • Cache generated QR codes to avoid regenerating the same code multiple times
  • Use appropriate error correction levels based on your use case
  • Optimize image size for web display while maintaining scannability
  • Consider using lazy loading for pages with multiple QR codes

Security Considerations

  • Input Validation: Always sanitize and validate user input before generating QR codes
  • Data Limits: Implement character limits to prevent excessive data encoding
  • Rate Limiting: Prevent abuse by implementing rate limiting on QR code generation
  • HTTPS: Use HTTPS when encoding URLs to ensure secure connections

Testing QR Codes

Always test your generated QR codes with multiple devices and QR code readers to ensure compatibility. Consider the following:

  • Test with different smartphone models and operating systems
  • Verify readability at various distances and lighting conditions
  • Check that encoded data is correctly interpreted
  • Ensure QR codes maintain quality when printed

Project Structure

Here's the recommended folder structure for your QR code generator project:

qr-code-generator/
├── vendor/
│   └── (Composer dependencies)
├── generated/
│   └── (Store generated QR codes)
├── index.php
├── generate_qr.php
├── download_qr.php
├── multi_qr_generator.php
├── secure_qr_generator.php
├── composer.json
└── README.md

Common Issues and Solutions

Issue 1: QR Code Not Displaying

If your QR code doesn't display, check the following:

  • Ensure the phpqrcode library is properly installed
  • Verify file permissions for the output directory
  • Check PHP error logs for any errors
  • Confirm imageBase64 is set to true for inline display

Issue 2: QR Code Not Scannable

If generated QR codes can't be scanned:

  • Increase the scale parameter for larger QR codes
  • Use higher error correction levels (ECC_H)
  • Ensure sufficient contrast between foreground and background
  • Avoid excessive data encoding

Issue 3: Memory Errors

For large-scale QR code generation, you may encounter memory issues. Solutions include:

<?php
// Increase memory limit in your PHP script
ini_set('memory_limit', '256M');

// Or adjust in php.ini file
// memory_limit = 256M
?>

Conclusion

In this comprehensive tutorial, we've explored how to generate QR codes dynamically using PHP. We covered multiple approaches, from using the phpqrcode library to implementing Google Charts API, and created various types of QR codes including URLs, emails, phone numbers, WiFi credentials, and vCards.

Key takeaways include understanding QR code generation fundamentals, implementing proper validation and error handling, customizing QR code appearance, and following security best practices. The phpqrcode library provides a robust, self-hosted solution that doesn't depend on external services, making it ideal for production applications.

Whether you're building a ticketing system, implementing contactless payments, or creating digital marketing campaigns, QR codes offer a versatile solution for bridging physical and digital experiences. With the knowledge gained from this tutorial, you can now create powerful QR code generators tailored to your specific requirements.

Next Steps: Consider extending this project by adding features like QR code analytics tracking, bulk QR code generation, custom branding with logos, or integrating with popular CMS platforms like WordPress or Laravel.

Copyright 2025. All rights are reserved