QR codes have become an essential part of modern web applications. From sharing URLs and contact details to enabling quick payments and app downloads, QR codes provide a fast and user-friendly way to exchange information.
In this tutorial, we will explore how to generate QR codes using PHP, a popular server-side scripting language. We will use the custom PHP library that makes it easy to create QR codes in various formats. With this step-by-step guide, youβll learn how to build a professional QR Code Generator using PHP with a clean architecture and reusable components. This guide is based on a real-world PHP project structure and uses the powerful Endroid QR Code library.
By the end of this tutorial, you will understand:
This PHP QR Code Generator can be used for:
We will use custom PHP library to generate QR codes. This library has a dependency on GD extension for image processing. Make sure you have the GD extension enabled in your PHP installation.
Here is the directory structure used in this QR Code Generator project:
qr_code_generator/ βββ config.php βββ index.php βββ api.php βββ includes/ | βββ QRCodeGenerator.php β βββ QRCodeRenderer.php βββ vendor/ βββ assets/ βββ style.css
Each file has a specific responsibility, making the project easy to maintain and extend:
This project uses the Endroid QR Code library, one of the most reliable PHP QR code libraries. To install it, run the following command in your project root:
composer require endroid/qr-code
Composer will create the vendor/ directory and install all required dependencies.
Note that: You donβt need to download the Endroid QR Code library separately, all the required library files are included in our source code package.
The config.php file loads Composerβs autoloader for dependencies and contains all the configuration settings for the QR Code Generator. Here, we define constants for QR code sizes, types, and validation rules.
<?php
// Load Composer autoloader for dependencies
require_once __DIR__ . '/vendor/autoload.php';
// QR Code Configuration
define('QR_CODE_SIZE', 300); // Default QR code size in pixels
define('QR_CODE_SIZE_DOWNLOAD', 500); // Size for downloads in pixels
// QR Code Types
$QR_TYPES = [
'url' => ['label' => 'URL/Website', 'icon' => 'π'],
'email' => ['label' => 'Email', 'icon' => 'βοΈ'],
'phone' => ['label' => 'Phone Call', 'icon' => 'βοΈ'],
'sms' => ['label' => 'SMS Message', 'icon' => 'π¬'],
'contact' => ['label' => 'Contact', 'icon' => 'π€'],
'vcard' => ['label' => 'vCard (Business Card)', 'icon' => 'πΌ'],
'wifi' => ['label' => 'WiFi Network', 'icon' => 'π‘'],
'event' => ['label' => 'Event/Calendar', 'icon' => 'π '],
'location' => ['label' => 'GPS Location', 'icon' => 'π'],
'app' => ['label' => 'App Download Link', 'icon' => 'π±']
];
// WiFi Security Types
$WIFI_SECURITY_TYPES = [
'WPA' => 'WPA/WPA2 (Recommended)',
'WEP' => 'WEP (Legacy)',
'nopass' => 'No Password (Open Network)'
];
// Validation Rules
$VALIDATION_RULES = [
'url' => [
'type' => 'url',
'required' => true,
'message' => 'Please enter a valid URL starting with http:// or https://'
],
'email' => [
'type' => 'email',
'required' => true,
'message' => 'Please enter a valid email address'
],
'phone' => [
'type' => 'tel',
'required' => true,
'pattern' => '/^[0-9+\-\(\) ]+$/',
'message' => 'Please enter a valid phone number'
],
'latitude' => [
'type' => 'number',
'required' => true,
'min' => -90,
'max' => 90,
'message' => 'Latitude must be between -90 and 90'
],
'longitude' => [
'type' => 'number',
'required' => true,
'min' => -180,
'max' => 180,
'message' => 'Longitude must be between -180 and 180'
]
];
?>
The QRCodeGenerator class is used to prepare and validate QR code content before rendering. It includes methods for different QR code types, ensuring the data is formatted correctly.
<?php
class QRCodeGenerator {
/**
* Generate QR code data for a URL
*/
public function generateURL($url) {
if (!filter_var($url, FILTER_VALIDATE_URL)) {
throw new Exception('Invalid URL format');
}
return $url;
}
/**
* Generate QR code data for Email
*/
public function generateEmail($email, $subject = '', $body = '') {
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
throw new Exception('Invalid email format');
}
$mailto = 'mailto:' . $email;
if (!empty($subject) || !empty($body)) {
$params = [];
if (!empty($subject)) {
$params[] = 'subject=' . urlencode($subject);
}
if (!empty($body)) {
$params[] = 'body=' . urlencode($body);
}
$mailto .= '?' . implode('&', $params);
}
return $mailto;
}
/**
* Generate QR code data for Phone Call
*/
public function generatePhone($phone) {
// Remove any non-digit characters except +
$phone = preg_replace('/[^0-9+]/', '', $phone);
if (empty($phone)) {
throw new Exception('Invalid phone number');
}
return 'tel:' . $phone;
}
/**
* Generate QR code data for SMS
*/
public function generateSMS($phone, $message = '') {
$phone = preg_replace('/[^0-9+]/', '', $phone);
if (empty($phone)) {
throw new Exception('Invalid phone number');
}
$sms = 'smsto:' . $phone;
if (!empty($message)) {
$sms .= ':' . urlencode($message);
}
return $sms;
}
/**
* Generate QR code data for Contact (vCard format)
*/
public function generateContact($name, $phone = '', $email = '') {
if (empty($name)) {
throw new Exception('Contact name is required');
}
$vcard = "BEGIN:VCARD\r\n";
$vcard .= "VERSION:3.0\r\n";
$vcard .= "FN:" . $this->escapeVCard($name) . "\r\n";
if (!empty($phone)) {
$phone = preg_replace('/[^0-9+]/', '', $phone);
$vcard .= "TEL:" . $phone . "\r\n";
}
if (!empty($email)) {
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
throw new Exception('Invalid email format');
}
$vcard .= "EMAIL:" . $email . "\r\n";
}
$vcard .= "END:VCARD";
return $vcard;
}
/**
* Generate QR code data for vCard (Business Card)
*/
public function generateVCard($name, $phone = '', $email = '', $org = '', $url = '') {
if (empty($name)) {
throw new Exception('Name is required');
}
$vcard = "BEGIN:VCARD\r\n";
$vcard .= "VERSION:3.0\r\n";
// Split name into first and last name
$names = explode(' ', $name, 2);
$vcard .= "N:" . (isset($names[1]) ? $this->escapeVCard($names[1]) : '') . ";" . $this->escapeVCard($names[0]) . "\r\n";
$vcard .= "FN:" . $this->escapeVCard($name) . "\r\n";
if (!empty($org)) {
$vcard .= "ORG:" . $this->escapeVCard($org) . "\r\n";
}
if (!empty($phone)) {
$phone = preg_replace('/[^0-9+]/', '', $phone);
$vcard .= "TEL;TYPE=VOICE,WORK:" . $phone . "\r\n";
}
if (!empty($email)) {
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
throw new Exception('Invalid email format');
}
$vcard .= "EMAIL;TYPE=INTERNET,WORK:" . $email . "\r\n";
}
if (!empty($url)) {
if (!filter_var($url, FILTER_VALIDATE_URL)) {
throw new Exception('Invalid URL format');
}
$vcard .= "URL:" . $url . "\r\n";
}
$vcard .= "END:VCARD";
return $vcard;
}
/**
* Generate QR code data for WiFi Network
*/
public function generateWiFi($ssid, $password = '', $security = 'WPA') {
if (empty($ssid)) {
throw new Exception('WiFi SSID is required');
}
// WiFi QR code format: WIFI:T:security;S:SSID;P:password;H:hidden;;
$wifi = 'WIFI:';
$wifi .= 'T:' . $security . ';';
$wifi .= 'S:' . $this->escapeWiFi($ssid) . ';';
if (!empty($password)) {
$wifi .= 'P:' . $this->escapeWiFi($password) . ';';
}
$wifi .= 'H:false;;';
return $wifi;
}
/**
* Generate QR code data for Event/Calendar
*/
public function generateEvent($title, $start = '', $end = '', $location = '') {
if (empty($title)) {
throw new Exception('Event title is required');
}
// Using BEGIN:VEVENT format (iCalendar)
$ical = "BEGIN:VCALENDAR\r\n";
$ical .= "VERSION:2.0\r\n";
$ical .= "PRODID:-//QR Code Generator//EN\r\n";
$ical .= "BEGIN:VEVENT\r\n";
// Format dates for iCalendar (YYYYMMDDTHHMMSSZ)
if (!empty($start)) {
$startDate = $this->formatICalDate($start);
$ical .= "DTSTART:" . $startDate . "\r\n";
}
if (!empty($end)) {
$endDate = $this->formatICalDate($end);
$ical .= "DTEND:" . $endDate . "\r\n";
}
$ical .= "SUMMARY:" . $this->escapeICalText($title) . "\r\n";
if (!empty($location)) {
$ical .= "LOCATION:" . $this->escapeICalText($location) . "\r\n";
}
$ical .= "UID:" . uniqid() . "@qrcodegenerator\r\n";
$ical .= "DTSTAMP:" . date('Ymd\THis\Z') . "\r\n";
$ical .= "END:VEVENT\r\n";
$ical .= "END:VCALENDAR";
return $ical;
}
/**
* Generate QR code data for GPS Location
*/
public function generateLocation($latitude, $longitude) {
// Validate coordinates
$lat = floatval($latitude);
$lng = floatval($longitude);
if ($lat < -90 || $lat > 90) {
throw new Exception('Latitude must be between -90 and 90');
}
if ($lng < -180 || $lng > 180) {
throw new Exception('Longitude must be between -180 and 180');
}
// Google Maps format: geo:latitude,longitude
return 'geo:' . $lat . ',' . $lng;
}
/**
* Generate QR code data for App Download Link
*/
public function generateAppDownload($url) {
if (!filter_var($url, FILTER_VALIDATE_URL)) {
throw new Exception('Invalid app URL format');
}
return $url;
}
/**
* Escape special characters for vCard format
*/
private function escapeVCard($text) {
$text = str_replace('\\', '\\\\', $text);
$text = str_replace(',', '\\,', $text);
$text = str_replace(';', '\\;', $text);
$text = str_replace("\r\n", '\\n', $text);
$text = str_replace("\n", '\\n', $text);
return $text;
}
/**
* Escape special characters for WiFi format
*/
private function escapeWiFi($text) {
$text = str_replace('\\', '\\\\', $text);
$text = str_replace(';', '\\;', $text);
$text = str_replace(':', '\\:', $text);
$text = str_replace(',', '\\,', $text);
$text = str_replace('"', '\\"', $text);
return $text;
}
/**
* Escape special characters for iCalendar format
*/
private function escapeICalText($text) {
$text = str_replace('\\', '\\\\', $text);
$text = str_replace(',', '\\,', $text);
$text = str_replace(';', '\\;', $text);
$text = str_replace("\r\n", '\\n', $text);
$text = str_replace("\n", '\\n', $text);
return $text;
}
/**
* Format datetime string to iCalendar format
*/
private function formatICalDate($dateString) {
try {
$date = new DateTime($dateString);
return $date->format('Ymd\THis');
} catch (Exception $e) {
throw new Exception('Invalid date format. Please use YYYY-MM-DD or YYYY-MM-DDTHH:MM:SS format');
}
}
}
?>
This QRCodeRenderer class is responsible for generating the QR code image using Endroid QR Code (endroid/qr-code) library. This class encapsulates all the logic needed to create and customize QR codes based on the provided data.
<?php
use Endroid\QrCode\QrCode;
use Endroid\QrCode\Writer\PngWriter;
use Endroid\QrCode\ErrorCorrectionLevel;
class QRCodeRenderer {
private $errorCorrectionLevel = 'M';
public function __construct($errorCorrectionLevel = 'M') {
$this->errorCorrectionLevel = $errorCorrectionLevel;
}
/**
* Generate QR code and return as data URL
*/
public function generate($text, $size = 300) {
try {
$imageData = $this->createQRImage($text, $size);
return 'data:image/png;base64,' . base64_encode($imageData);
} catch (Exception $e) {
error_log('QR Generation Error: ' . $e->getMessage());
throw $e;
}
}
/**
* Generate QR code and save to file
*/
public function generateToFile($text, $filepath, $size = 300) {
try {
$imageData = $this->createQRImage($text, $size);
return file_put_contents($filepath, $imageData) !== false;
} catch (Exception $e) {
error_log('QR File Generation Error: ' . $e->getMessage());
throw $e;
}
}
/**
* Get image bytes for download
*/
public function getImageBytes($text, $size = 300) {
try {
return $this->createQRImage($text, $size);
} catch (Exception $e) {
error_log('QR Bytes Generation Error: ' . $e->getMessage());
throw $e;
}
}
/**
* Create QR image using Endroid library
*/
private function createQRImage($text, $size) {
$text = (string)$text;
// Map error correction level
$ecLevel = $this->mapErrorCorrectionLevel($this->errorCorrectionLevel);
// Create QR code with proper parameters
$qrCode = new QrCode(
data: $text,
errorCorrectionLevel: $ecLevel,
size: $size,
margin: 10
);
// Render to PNG
$writer = new PngWriter();
$result = $writer->write($qrCode);
return $result->getString();
}
/**
* Map error correction level to Endroid format
*/
private function mapErrorCorrectionLevel($level) {
$levelMap = array(
'L' => ErrorCorrectionLevel::Low,
'M' => ErrorCorrectionLevel::Medium,
'Q' => ErrorCorrectionLevel::Quartile,
'H' => ErrorCorrectionLevel::High
);
return $levelMap[$level] ?? ErrorCorrectionLevel::Medium;
}
}
?>
The index.php file serves as the main entry point (frontend interface) for users to interact with the QR code generator. It provides a simple HTML form where users can input the text or URL they want to encode into a QR code. Upon submission, it processes the input, generates the QR code using the QRCodeRenderer class, and displays the resulting QR code image on the same page.
<?php
// QR Code Generator - Main Page
session_start();
// Include configuration
require_once 'config.php';
// Include the QR Code generator class
require_once 'includes/QRCodeGenerator.php';
// Include the QR Code renderer for internal generation
require_once 'includes/QRCodeRenderer.php';
// Process form submission
$generated_qr = null;
$error_message = null;
$qr_data = null;
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$type = $_POST['qr_type'] ?? '';
try {
$qr_generator = new QRCodeGenerator();
switch ($type) {
case 'url':
$url = $_POST['url'] ?? '';
if (empty($url)) throw new Exception('URL is required');
$qr_data = $qr_generator->generateURL($url);
break;
case 'email':
$email = $_POST['email'] ?? '';
$subject = $_POST['email_subject'] ?? '';
$body = $_POST['email_body'] ?? '';
if (empty($email)) throw new Exception('Email is required');
$qr_data = $qr_generator->generateEmail($email, $subject, $body);
break;
case 'phone':
$phone = $_POST['phone'] ?? '';
if (empty($phone)) throw new Exception('Phone number is required');
$qr_data = $qr_generator->generatePhone($phone);
break;
case 'sms':
$phone = $_POST['sms_phone'] ?? '';
$message = $_POST['sms_message'] ?? '';
if (empty($phone)) throw new Exception('Phone number is required');
$qr_data = $qr_generator->generateSMS($phone, $message);
break;
case 'contact':
$name = $_POST['contact_name'] ?? '';
$phone = $_POST['contact_phone'] ?? '';
$email = $_POST['contact_email'] ?? '';
if (empty($name)) throw new Exception('Contact name is required');
$qr_data = $qr_generator->generateContact($name, $phone, $email);
break;
case 'vcard':
$name = $_POST['vcard_name'] ?? '';
$phone = $_POST['vcard_phone'] ?? '';
$email = $_POST['vcard_email'] ?? '';
$org = $_POST['vcard_org'] ?? '';
$url = $_POST['vcard_url'] ?? '';
if (empty($name)) throw new Exception('Name is required');
$qr_data = $qr_generator->generateVCard($name, $phone, $email, $org, $url);
break;
case 'wifi':
$ssid = $_POST['wifi_ssid'] ?? '';
$password = $_POST['wifi_password'] ?? '';
$security = $_POST['wifi_security'] ?? 'WPA';
if (empty($ssid)) throw new Exception('WiFi SSID is required');
$qr_data = $qr_generator->generateWiFi($ssid, $password, $security);
break;
case 'event':
$title = $_POST['event_title'] ?? '';
$start = $_POST['event_start'] ?? '';
$end = $_POST['event_end'] ?? '';
$location = $_POST['event_location'] ?? '';
if (empty($title)) throw new Exception('Event title is required');
$qr_data = $qr_generator->generateEvent($title, $start, $end, $location);
break;
case 'location':
$lat = $_POST['latitude'] ?? '';
$lng = $_POST['longitude'] ?? '';
if (empty($lat) || empty($lng)) throw new Exception('Latitude and Longitude are required');
$qr_data = $qr_generator->generateLocation($lat, $lng);
break;
case 'app':
$app_url = $_POST['app_url'] ?? '';
if (empty($app_url)) throw new Exception('App URL is required');
$qr_data = $qr_generator->generateAppDownload($app_url);
break;
default:
throw new Exception('Invalid QR code type selected');
}
// Generate QR code image
$generated_qr = generateQRCodeImage($qr_data);
$_SESSION['last_qr_data'] = $qr_data;
$_SESSION['last_qr_type'] = $type;
} catch (Exception $e) {
$error_message = $e->getMessage();
}
}
// Function to generate QR code image using internal library
function generateQRCodeImage($data) {
$renderer = new QRCodeRenderer();
return $renderer->generate($data, QR_CODE_SIZE);
}
?>
<div class="form-section">
<form method="POST" class="qr-form">
<div class="form-group">
<label for="qr_type">Select QR Code Type:</label>
<select id="qr_type" name="qr_type" required onchange="updateFormFields()">
<option value="">-- Choose Type --</option>
<option value="url" <?php echo (isset($_POST['qr_type']) && $_POST['qr_type'] === 'url') ? 'selected' : ''; ?>>URL/Website</option>
<option value="email" <?php echo (isset($_POST['qr_type']) && $_POST['qr_type'] === 'email') ? 'selected' : ''; ?>>Email</option>
<option value="phone" <?php echo (isset($_POST['qr_type']) && $_POST['qr_type'] === 'phone') ? 'selected' : ''; ?>>Phone Call</option>
<option value="sms" <?php echo (isset($_POST['qr_type']) && $_POST['qr_type'] === 'sms') ? 'selected' : ''; ?>>SMS Message</option>
<option value="contact" <?php echo (isset($_POST['qr_type']) && $_POST['qr_type'] === 'contact') ? 'selected' : ''; ?>>Contact</option>
<option value="vcard"<?php echo (isset($_POST['qr_type']) && $_POST['qr_type'] === 'vcard') ? 'selected' : ''; ?>>vCard (Business Card)</option>
<option value="wifi" <?php echo (isset($_POST['qr_type']) && $_POST['qr_type'] === 'wifi') ? 'selected' : ''; ?>>WiFi Network</option>
<option value="event" <?php echo (isset($_POST['qr_type']) && $_POST['qr_type'] === 'event') ? 'selected' : ''; ?>>Event/Calendar</option>
<option value="location" <?php echo (isset($_POST['qr_type']) && $_POST['qr_type'] === 'location') ? 'selected' : ''; ?>>GPS Location</option>
<option value="app" <?php echo (isset($_POST['qr_type']) && $_POST['qr_type'] === 'app') ? 'selected' : ''; ?>>App Download Link</option>
</select>
</div>
<!-- URL Fields -->
<div id="url-fields" class="form-fields" style="display:none;">
<div class="form-group">
<label for="url">Website URL:</label>
<input type="url" id="url" name="url" placeholder="https://example.com" value="<?php echo htmlspecialchars($_POST['url'] ?? ''); ?>">
</div>
</div>
<!-- Email Fields -->
<div id="email-fields" class="form-fields" style="display:none;">
<div class="form-group">
<label for="email">Email Address:</label>
<input type="email" id="email" name="email" placeholder="[email protected]" value="<?php echo htmlspecialchars($_POST['email'] ?? ''); ?>">
</div>
<div class="form-group">
<label for="email_subject">Subject (Optional):</label>
<input type="text" id="email_subject" name="email_subject" placeholder="Email subject" value="<?php echo htmlspecialchars($_POST['email_subject'] ?? ''); ?>">
</div>
<div class="form-group">
<label for="email_body">Message Body (Optional):</label>
<textarea id="email_body" name="email_body" placeholder="Email message" rows="3"><?php echo htmlspecialchars($_POST['email_body'] ?? ''); ?></textarea>
</div>
</div>
<!-- Phone Fields -->
<div id="phone-fields" class="form-fields" style="display:none;">
<div class="form-group">
<label for="phone">Phone Number:</label>
<input type="tel" id="phone" name="phone" placeholder="+1-555-123-4567" value="<?php echo htmlspecialchars($_POST['phone'] ?? ''); ?>">
</div>
</div>
<!-- SMS Fields -->
<div id="sms-fields" class="form-fields" style="display:none;">
<div class="form-group">
<label for="sms_phone">Phone Number:</label>
<input type="tel" id="sms_phone" name="sms_phone" placeholder="+1-555-123-4567" value="<?php echo htmlspecialchars($_POST['sms_phone'] ?? ''); ?>">
</div>
<div class="form-group">
<label for="sms_message">SMS Message (Optional):</label>
<textarea id="sms_message" name="sms_message" placeholder="SMS message" rows="3"><?php echo htmlspecialchars($_POST['sms_message'] ?? ''); ?></textarea>
</div>
</div>
<!-- Contact Fields -->
<div id="contact-fields" class="form-fields" style="display:none;">
<div class="form-group">
<label for="contact_name">Name:</label>
<input type="text" id="contact_name" name="contact_name" placeholder="John Doe" value="<?php echo htmlspecialchars($_POST['contact_name'] ?? ''); ?>">
</div>
<div class="form-group">
<label for="contact_phone">Phone (Optional):</label>
<input type="tel" id="contact_phone" name="contact_phone" placeholder="+1-555-123-4567" value="<?php echo htmlspecialchars($_POST['contact_phone'] ?? ''); ?>">
</div>
<div class="form-group">
<label for="contact_email">Email (Optional):</label>
<input type="email" id="contact_email" name="contact_email" placeholder="[email protected]" value="<?php echo htmlspecialchars($_POST['contact_email'] ?? ''); ?>">
</div>
</div>
<!-- vCard Fields -->
<div id="vcard-fields" class="form-fields" style="display:none;">
<div class="form-group">
<label for="vcard_name">Full Name:</label>
<input type="text" id="vcard_name" name="vcard_name" placeholder="John Doe" value="<?php echo htmlspecialchars($_POST['vcard_name'] ?? ''); ?>">
</div>
<div class="form-group">
<label for="vcard_phone">Phone (Optional):</label>
<input type="tel" id="vcard_phone" name="vcard_phone" placeholder="+1-555-123-4567" value="<?php echo htmlspecialchars($_POST['vcard_phone'] ?? ''); ?>">
</div>
<div class="form-group">
<label for="vcard_email">Email (Optional):</label>
<input type="email" id="vcard_email" name="vcard_email" placeholder="[email protected]" value="<?php echo htmlspecialchars($_POST['vcard_email'] ?? ''); ?>">
</div>
<div class="form-group">
<label for="vcard_org">Organization (Optional):</label>
<input type="text" id="vcard_org" name="vcard_org" placeholder="Company Name" value="<?php echo htmlspecialchars($_POST['vcard_org'] ?? ''); ?>">
</div>
<div class="form-group">
<label for="vcard_url">Website (Optional):</label>
<input type="url" id="vcard_url" name="vcard_url" placeholder="https://example.com" value="<?php echo htmlspecialchars($_POST['vcard_url'] ?? ''); ?>">
</div>
</div>
<!-- WiFi Fields -->
<div id="wifi-fields" class="form-fields" style="display:none;">
<div class="form-group">
<label for="wifi_ssid">WiFi Network Name (SSID):</label>
<input type="text" id="wifi_ssid" name="wifi_ssid" placeholder="MyWiFiNetwork" value="<?php echo htmlspecialchars($_POST['wifi_ssid'] ?? ''); ?>">
</div>
<div class="form-group">
<label for="wifi_password">Password (Optional):</label>
<input type="password" id="wifi_password" name="wifi_password" placeholder="WiFi password" value="<?php echo htmlspecialchars($_POST['wifi_password'] ?? ''); ?>">
</div>
<div class="form-group">
<label for="wifi_security">Security Type:</label>
<select id="wifi_security" name="wifi_security">
<option value="WPA" <?php echo (isset($_POST['wifi_security']) && $_POST['wifi_security'] === 'WPA') ? 'selected' : ''; ?>>WPA/WPA2</option>
<option value="WEP" <?php echo (isset($_POST['wifi_security']) && $_POST['wifi_security'] === 'WEP') ? 'selected' : ''; ?>>WEP</option>
<option value="nopass" <?php echo (isset($_POST['wifi_security']) && $_POST['wifi_security'] === 'nopass') ? 'selected' : ''; ?>>No Password</option>
</select>
</div>
</div>
<!-- Event Fields -->
<div id="event-fields" class="form-fields" style="display:none;">
<div class="form-group">
<label for="event_title">Event Title:</label>
<input type="text" id="event_title" name="event_title" placeholder="Conference 2024" value="<?php echo htmlspecialchars($_POST['event_title'] ?? ''); ?>">
</div>
<div class="form-group">
<label for="event_start">Start Date & Time:</label>
<input type="datetime-local" id="event_start" name="event_start" value="<?php echo htmlspecialchars($_POST['event_start'] ?? ''); ?>">
</div>
<div class="form-group">
<label for="event_end">End Date & Time (Optional):</label>
<input type="datetime-local" id="event_end" name="event_end" value="<?php echo htmlspecialchars($_POST['event_end'] ?? ''); ?>">
</div>
<div class="form-group">
<label for="event_location">Location (Optional):</label>
<input type="text" id="event_location" name="event_location" placeholder="Conference Hall, 123 Main St" value="<?php echo htmlspecialchars($_POST['event_location'] ?? ''); ?>">
</div>
</div>
<!-- Location Fields -->
<div id="location-fields" class="form-fields" style="display:none;">
<div class="form-group">
<label for="latitude">Latitude:</label>
<input type="number" id="latitude" name="latitude" step="0.000001" placeholder="40.7128" value="<?php echo htmlspecialchars($_POST['latitude'] ?? ''); ?>">
</div>
<div class="form-group">
<label for="longitude">Longitude:</label>
<input type="number" id="longitude" name="longitude" step="0.000001" placeholder="-74.0060" value="<?php echo htmlspecialchars($_POST['longitude'] ?? ''); ?>">
</div>
</div>
<!-- App Download Fields -->
<div id="app-fields" class="form-fields" style="display:none;">
<div class="form-group">
<label for="app_url">App Download URL:</label>
<input type="url" id="app_url" name="app_url" placeholder="https://play.google.com/store/apps/details?id=com.example.app" value="<?php echo htmlspecialchars($_POST['app_url'] ?? ''); ?>">
</div>
</div>
<button type="submit" class="btn-generate">Generate QR Code</button>
</form>
</div>
<!-- Result Section -->
<div class="result-section">
<?php if ($error_message): ?>
<div class="alert alert-error">
<strong>Error:</strong> <?php echo htmlspecialchars($error_message); ?>
</div>
<?php endif; ?>
<?php if ($generated_qr): ?>
<div class="qr-result">
<h3>Your QR Code</h3>
<div class="qr-display">
<img src="<?php echo htmlspecialchars($generated_qr); ?>" alt="Generated QR Code">
</div>
<div class="qr-data">
<p><strong>Encoded Data:</strong></p>
<code><?php echo htmlspecialchars($qr_data); ?></code>
</div>
<div class="button-group">
<a href="<?php echo htmlspecialchars($generated_qr); ?>" download class="btn btn-download">π₯ Download QR Code</a>
</div>
</div>
<?php endif; ?>
</div>
JavaScript for Dynamic Form Fields:
The following JavaScript code dynamically shows or hides form fields based on the selected QR code type. Add this script just before the closing </body> tag in index.php.
<script>
function updateFormFields() {
const type = document.getElementById('qr_type').value;
// Hide all fields
document.querySelectorAll('.form-fields').forEach(el => {
el.style.display = 'none';
});
// Show relevant fields
if (type) {
const fieldId = type + '-fields';
const fieldElement = document.getElementById(fieldId);
if (fieldElement) {
fieldElement.style.display = 'block';
}
}
}
// Initialize on page load
document.addEventListener('DOMContentLoaded', function() {
updateFormFields();
// Scroll to form if there's an error or result to show
<?php if ($error_message || $generated_qr): ?>
document.querySelector('.form-section').scrollIntoView({ behavior: 'smooth' });
<?php endif; ?>
});
</script>
Create a new file named api.php in the project directory. This file will handle REST API requests for QR code generation and allows you to generate QR codes programmatically.
Some use cases for this API endpoint include:
API workflow:
<?php
header('Content-Type: application/json');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST, OPTIONS');
require_once 'config.php';
require_once 'includes/QRCodeGenerator.php';
// Include internal QR renderer
require_once 'includes/QRCodeRenderer.php';
// Handle preflight requests
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
http_response_code(200);
exit(json_encode(['status' => 'ok']));
}
$response = [
'success' => false,
'data' => null,
'error' => null,
'qr_image' => null
];
try {
$generator = new QRCodeGenerator();
$type = $_GET['type'] ?? $_POST['type'] ?? null;
if (!$type) {
throw new Exception('QR type is required');
}
$qr_data = null;
switch ($type) {
case 'url':
$url = $_GET['url'] ?? $_POST['url'] ?? $_GET['data'] ?? null;
if (!$url) throw new Exception('URL is required');
$qr_data = $generator->generateURL($url);
break;
case 'email':
$email = $_GET['email'] ?? $_POST['email'] ?? null;
$subject = $_GET['subject'] ?? $_POST['subject'] ?? '';
$body = $_GET['body'] ?? $_POST['body'] ?? '';
if (!$email) throw new Exception('Email is required');
$qr_data = $generator->generateEmail($email, $subject, $body);
break;
case 'phone':
$phone = $_GET['phone'] ?? $_POST['phone'] ?? null;
if (!$phone) throw new Exception('Phone number is required');
$qr_data = $generator->generatePhone($phone);
break;
case 'sms':
$phone = $_GET['phone'] ?? $_POST['phone'] ?? null;
$message = $_GET['message'] ?? $_POST['message'] ?? '';
if (!$phone) throw new Exception('Phone number is required');
$qr_data = $generator->generateSMS($phone, $message);
break;
case 'contact':
$name = $_GET['name'] ?? $_POST['name'] ?? null;
$phone = $_GET['phone'] ?? $_POST['phone'] ?? '';
$email = $_GET['email'] ?? $_POST['email'] ?? '';
if (!$name) throw new Exception('Contact name is required');
$qr_data = $generator->generateContact($name, $phone, $email);
break;
case 'vcard':
$name = $_GET['name'] ?? $_POST['name'] ?? null;
$phone = $_GET['phone'] ?? $_POST['phone'] ?? '';
$email = $_GET['email'] ?? $_POST['email'] ?? '';
$org = $_GET['org'] ?? $_POST['org'] ?? '';
$url = $_GET['url'] ?? $_POST['url'] ?? '';
if (!$name) throw new Exception('Name is required');
$qr_data = $generator->generateVCard($name, $phone, $email, $org, $url);
break;
case 'wifi':
$ssid = $_GET['ssid'] ?? $_POST['ssid'] ?? null;
$password = $_GET['password'] ?? $_POST['password'] ?? '';
$security = $_GET['security'] ?? $_POST['security'] ?? 'WPA';
if (!$ssid) throw new Exception('WiFi SSID is required');
$qr_data = $generator->generateWiFi($ssid, $password, $security);
break;
case 'event':
$title = $_GET['title'] ?? $_POST['title'] ?? null;
$start = $_GET['start'] ?? $_POST['start'] ?? '';
$end = $_GET['end'] ?? $_POST['end'] ?? '';
$location = $_GET['location'] ?? $_POST['location'] ?? '';
if (!$title) throw new Exception('Event title is required');
$qr_data = $generator->generateEvent($title, $start, $end, $location);
break;
case 'location':
$lat = $_GET['lat'] ?? $_POST['lat'] ?? $_GET['latitude'] ?? $_POST['latitude'] ?? null;
$lng = $_GET['lng'] ?? $_POST['lng'] ?? $_GET['longitude'] ?? $_POST['longitude'] ?? null;
if (!$lat || !$lng) throw new Exception('Latitude and Longitude are required');
$qr_data = $generator->generateLocation($lat, $lng);
break;
case 'app':
$url = $_GET['url'] ?? $_POST['url'] ?? $_GET['app_url'] ?? $_POST['app_url'] ?? null;
if (!$url) throw new Exception('App URL is required');
$qr_data = $generator->generateAppDownload($url);
break;
default:
throw new Exception('Invalid QR code type: ' . $type);
}
if ($qr_data) {
// Generate QR code image using internal renderer
$size = (int)($_GET['size'] ?? $_POST['size'] ?? QR_CODE_SIZE);
$renderer = new QRCodeRenderer();
$qr_image = $renderer->generate($qr_data, $size);
$response['success'] = true;
$response['data'] = $qr_data;
$response['qr_image'] = $qr_image;
$response['type'] = $type;
$response['size'] = $size;
http_response_code(200);
}
} catch (Exception $e) {
$response['error'] = $e->getMessage();
http_response_code(400);
}
echo json_encode($response, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
?>
You can also generate QR codes programmatically using the REST API. Here are some examples to call the API using GET and POST methods.
GET /api.php?type=url&data=https://example.com&size=300x300 POST /api.php (with JSON data)
GET Method
To generate a QR code using the GET method, you can use the following URL format:
https://projectdomain.com/api.php?type={type}&data={data}&size={size}
Replace `{type}` with the type of QR code you want to generate (e.g., url, text, email), `{data}` with the content you want to encode, and `{size}` with the desired dimensions of the QR code (e.g., 300×300).
POST Method
To generate a QR code using the POST method, you can send a JSON payload to the API endpoint. Here is an example using cURL:
curl -X POST https://projectdomain.com/api.php \
-H "Content-Type: application/json" \
-d '{"type": "url", "data": "https://example.com", "size": "300x300"}'
Make sure to set the `Content-Type` header to `application/json` and include the necessary parameters in the JSON body.
API Response
The API will respond with the generated QR code image in base64 format along with other relevant information. Here is an example of a successful response:
{
"success": true,
"data": "https://www.example.com",
"qr_image": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAASwAAAEsCAYAAAB5fY51A...",
"type": "url",
"size": 300
}
To ensure the security and reliability of your QR code generation, consider the following best practices:
You can further enhance it by:
This QR Code Generator using PHP is a clean, modern, and production-ready solution. With a structured architecture, reusable classes, and API support, it is suitable for both small tools and enterprise-level applications. If youβre looking for a scalable PHP QR Code solution, this implementation provides the perfect foundation.
Looking for expert assistance to implement or extend this scriptβs functionality? Submit a Service Request
π° Budget-friendly β’ π Global clients β’ π Production-ready solutions