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
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>
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
- 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.