引言
在开发过程种,生成二维码的需求还是比较常见的,二维码的本质是一个url。今天用qr-code库生成二维码
一、安装安装 endroid/qr-code库
找到项目的路径,右键bash 安装二维码库
二、下面是我写的一个批量生成二维码的接口,当作参考
/**
* @return void
* 批量生成二维码
*/
public function batchGenerate()
{
// 获取前端传递的 `serial_numbers`
$serial_numbers = input('get.serial_numbers'); // 获取 GET 参数
$pch = input('get.pch'); // 获取 GET 参数
$serialNumberArray = explode(',', $serial_numbers); // 将字符串转换为数组
$pchArray = explode(',', $pch); // 将字符串转换为数组
if (empty($serial_numbers) || empty($serialNumberArray)) {
return $this->error("序列号不能为空");
}
// 根据序列号查询对应的 `articles_id`
$articleIds = $this->model
->whereIn('serial_number', $serialNumberArray)
->column('articles_id', 'serial_number'); // 获取 ['序列号' => 'articles_id'] 的键值对
if (empty($articleIds)) {
return $this->error("该序列号没有对应文章");
}
$baseUrl = "http://www.keyuyurong.com/manage.php/ldcms/scan/scanArticle";
// 生成临时 ZIP 文件
$zipFile = tempnam(sys_get_temp_dir(), 'qrcodes_') . ".zip";
$zip = new \ZipArchive();
if ($zip->open($zipFile, \ZipArchive::CREATE) === TRUE) {
foreach ($articleIds as $serialNumber => $articleId) {
$text = "$baseUrl?serialNumber=$serialNumber&pch=$pch"; // 生成二维码的链接,包含序列号
// 生成二维码,设置长方形
$result = Builder::create()
->writer(new PngWriter())
->data($text)
->size(300) // 宽度
->margin(10)
->build();
// 生成二维码的长方形效果
$image = $result->getImage();
$width = imagesx($image); // 获取二维码的宽度
$height = imagesy($image); // 获取二维码的高度
// 修改二维码的大小,使其成为长方形 (通过设置一个新的宽度和高度比例)
$newWidth = $width; // 长方形的宽度,适当放大
$newHeight = $height; // 保持高度不变
// 创建新的长方形二维码图片
$newImage = imagecreatetruecolor($newWidth, $newHeight);
imagecopyresampled($newImage, $image, 0, 0, 0, 0, $newWidth, $newHeight, $width, $height);
// 保存长方形二维码到内存
ob_start();
imagepng($newImage);
$qrImage = ob_get_contents();
ob_end_clean();
// 直接添加到 ZIP,不存储 PNG 文件
$zip->addFromString("{$serialNumber}.png", $qrImage);
}
$zip->close();
}
// 让浏览器下载 ZIP 文件
header('Content-Type: application/zip');
header('Content-Disposition: attachment; filename="qrcodes.zip"');
header('Content-Length: ' . filesize($zipFile));
readfile($zipFile);
// 删除 ZIP 临时文件
unlink($zipFile);
exit;
}
我的功能是带着序列号参数生成二维码,当用户扫码的时候,要判断是否携带正确参数等,所以baseUrl 指向扫码接口
扫码接口如下
public function scanArticle()
{
// 获取并清理序列号参数
$serial_number = trim(input('get.serialNumber'));
// 检查是否传递了 serial_number
if (!isset($serial_number) || $serial_number === '') {
return $this->error("设备号不能为空");
}
// 查询该序列号是否存在,并且获取文章ID和批次号
$serial = SerialModel::where('serial_number', $serial_number)
->field('serial_number, pch, articles_id, status, scan_count, max_scans')
->find();
// 设备号不存在
if (!$serial) {
return $this->error("无效的设备号");
}
// 设备号被禁用
if ($serial['status'] == 0) {
return $this->error("设备号已被禁用");
}
// 设备号扫码次数已超上限
if (intval($serial['scan_count']) >= intval($serial['max_scans'])) {
return redirect("http://www.keyuyurong.com/cuowuyemian.html?serialNumber={$serial_number}");
}
// 更新扫码次数
$updateSuccess = SerialModel::where('serial_number', $serial_number)->inc('scan_count')->update();
if (!$updateSuccess) {
return $this->error("扫码次数更新失败,请稍后再试");
}
// 获取批次号,确保字符串安全传递
$pch = urlencode($serial['pch']); // 进行 URL 编码,防止特殊字符导致乱码
// 传递序列号、文章ID和批次号到前端
$url = "http://www.keyuyurong.com/wenzhangjieshao.html"
. "?serialNumber={$serial_number}"
. "&articles_id={$serial['articles_id']}"
. "&pch={$pch}";
return $this->redirect($url);
}
三、效果
最终效果如下
四、重要提醒
php 版本大于等于7.4
还有最重要的一点,觉得这篇文章有用的话动动发财的小手给兄弟点点小关小注。