本文目录导读:

我将为您创建一个完整的PHP条形码生成封装类,支持多种条形码格式。
完整的条形码生成封装类
<?php
/**
* BarcodeGenerator 条形码生成封装类
*
* 支持多种条形码格式,包括 Code128, Code39, EAN-13, EAN-8, UPC-A, UPC-E,
* ISBN, ITF-14 等
*
* @author Your Name
* @version 1.0.0
*/
class BarcodeGenerator {
/**
* 条形码类型常量
*/
const TYPE_CODE128 = 'code128';
const TYPE_CODE39 = 'code39';
const TYPE_EAN13 = 'ean13';
const TYPE_EAN8 = 'ean8';
const TYPE_UPC_A = 'upca';
const TYPE_UPC_E = 'upce';
const TYPE_ISBN = 'isbn';
const TYPE_ITF14 = 'itf14';
const TYPE_CODABAR = 'codabar';
const TYPE_CODE93 = 'code93';
const TYPE_MSI = 'msi';
/**
* 条形码格式
*/
const FORMAT_PNG = 'png';
const FORMAT_JPEG = 'jpeg';
const FORMAT_GIF = 'gif';
/**
* 条形码颜色
*/
private $foregroundColor = [0, 0, 0]; // 前景色
private $backgroundColor = [255, 255, 255]; // 背景色
/**
* 尺寸设置
*/
private $scale = 2; // 缩放比例
private $height = 50; // 高度
/**
* 错误信息
*/
private $error = null;
/**
* 生成条形码
*
* @param string $code 条形码内容
* @param string $type 条形码类型
* @param string $format 输出格式
* @param int $scale 缩放比例
* @param int $height 条形码高度
* @param array $foreground 前景色 RGB
* @param array $background 背景色 RGB
* @return mixed 图片资源或false
*/
public function generate($code, $type = self::TYPE_CODE128, $format = self::FORMAT_PNG,
$scale = 2, $height = 50, $foreground = null, $background = null) {
// 重置错误
$this->error = null;
// 设置参数
$this->scale = $scale;
$this->height = $height;
if ($foreground !== null) {
$this->foregroundColor = $foreground;
}
if ($background !== null) {
$this->backgroundColor = $background;
}
// 验证条形码
if (!$this->validate($code, $type)) {
return false;
}
// 生成条形码数据
$barcodeData = $this->getBarcodeData($code, $type);
if ($barcodeData === false) {
return false;
}
// 创建图像
$image = $this->createImage($barcodeData, $format);
return $image;
}
/**
* 验证条形码数据
*
* @param string $code 条形码内容
* @param string $type 条形码类型
* @return bool 是否有效
*/
private function validate($code, $type) {
if (empty($code)) {
$this->error = '条形码内容不能为空';
return false;
}
switch ($type) {
case self::TYPE_EAN13:
if (!preg_match('/^\d{12,13}$/', $code)) {
$this->error = 'EAN-13 条形码必须包含 12 或 13 位数字';
return false;
}
break;
case self::TYPE_EAN8:
if (!preg_match('/^\d{7,8}$/', $code)) {
$this->error = 'EAN-8 条形码必须包含 7 或 8 位数字';
return false;
}
break;
case self::TYPE_UPC_A:
if (!preg_match('/^\d{11,12}$/', $code)) {
$this->error = 'UPC-A 条形码必须包含 11 或 12 位数字';
return false;
}
break;
case self::TYPE_UPC_E:
if (!preg_match('/^\d{6,8}$/', $code)) {
$this->error = 'UPC-E 条形码必须包含 6、7 或 8 位数字';
return false;
}
break;
case self::TYPE_CODE39:
if (!preg_match('/^[A-Z0-9\-\$\/%\.\+\*\s]+$/', $code)) {
$this->error = 'Code39 条形码只支持大写字母、数字和特殊字符';
return false;
}
break;
case self::TYPE_CODE128:
if (strlen($code) > 80) {
$this->error = 'Code128 条形码长度不能超过 80 个字符';
return false;
}
break;
case self::TYPE_CODABAR:
if (!preg_match('/^[A-D][0-9\-\$\:\.\/\+]{4,}[A-D]$/', $code)) {
$this->error = 'Codabar 条形码格式不正确';
return false;
}
break;
}
return true;
}
/**
* 获取条形码二进制数据
*
* @param string $code 条形码内容
* @param string $type 条形码类型
* @return array|false 条形码数据数组
*/
private function getBarcodeData($code, $type) {
switch ($type) {
case self::TYPE_CODE128:
return $this->generateCode128($code);
case self::TYPE_CODE39:
return $this->generateCode39($code);
case self::TYPE_EAN13:
return $this->generateEAN13($code);
case self::TYPE_EAN8:
return $this->generateEAN8($code);
case self::TYPE_UPC_A:
return $this->generateUPCA($code);
case self::TYPE_UPC_E:
return $this->generateUPCE($code);
default:
$this->error = '不支持的条形码类型';
return false;
}
}
/**
* 生成 Code128 条形码
*
* @param string $code
* @return array
*/
private function generateCode128($code) {
// Code128 字符集表(简化版)
$charTable = [
' ' => 0, '!' => 1, '"' => 2, '#' => 3, '$' => 4, '%' => 5, '&' => 6,
"'" => 7, '(' => 8, ')' => 9, '*' => 10, '+' => 11, ',' => 12, '-' => 13,
'.' => 14, '/' => 15, '0' => 16, '1' => 17, '2' => 18, '3' => 19,
'4' => 20, '5' => 21, '6' => 22, '7' => 23, '8' => 24, '9' => 25,
':' => 26, ';' => 27, '<' => 28, '=' => 29, '>' => 30, '?' => 31,
'@' => 32, 'A' => 33, 'B' => 34, 'C' => 35, 'D' => 36, 'E' => 37,
'F' => 38, 'G' => 39, 'H' => 40, 'I' => 41, 'J' => 42, 'K' => 43,
'L' => 44, 'M' => 45, 'N' => 46, 'O' => 47, 'P' => 48, 'Q' => 49,
'R' => 50, 'S' => 51, 'T' => 52, 'U' => 53, 'V' => 54, 'W' => 55,
'X' => 56, 'Y' => 57, 'Z' => 58, '[' => 59, '\\' => 60, ']' => 61,
'^' => 62, '_' => 63, '`' => 64, 'a' => 65, 'b' => 66, 'c' => 67,
'd' => 68, 'e' => 69, 'f' => 70, 'g' => 71, 'h' => 72, 'i' => 73,
'j' => 74, 'k' => 75, 'l' => 76, 'm' => 77, 'n' => 78, 'o' => 79,
'p' => 80, 'q' => 81, 'r' => 82, 's' => 83, 't' => 84, 'u' => 85,
'v' => 86, 'w' => 87, 'x' => 88, 'y' => 89, 'z' => 90, '{' => 91,
'|' => 92, '}' => 93, '~' => 94
];
// Code128 编码表(简化版)
$patterns = [
'212222', '222122', '222221', '121223', '121322', '131222', '122213',
'122312', '132212', '221213', '221312', '231212', '112232', '122132',
'122231', '113222', '123122', '123221', '223211', '221132', '221231',
'213212', '223112', '312131', '311222', '321122', '321221', '312212',
'322112', '322211', '212123', '212321', '232121', '111323', '131123',
'131321', '112313', '132113', '132311', '211313', '231113', '231311',
'112133', '112331', '132131', '113123', '113321', '133121', '313121',
'211331', '231131', '213113', '213311', '213131', '311123', '311321',
'331121', '312113', '312311', '332111', '314111', '221411', '431111',
'111224', '111422', '121124', '121421', '141122', '141221', '112214',
'112412', '122114', '122411', '142112', '142211', '241211', '221114',
'413111', '241112', '134111', '111242', '121142', '121241', '114212',
'124112', '124211', '411212', '421112', '421211', '212141', '214121',
'412121', '111143', '111341', '131141', '114113', '114311', '411113',
'411311', '113141', '114131', '311141', '411131', '211412', '211214',
'211232', '2331112'
];
$codeLength = strlen($code);
$checksum = 104; // Start code B
$data = [];
// 添加起始码
$data[] = '211412'; // Start B pattern
// 编码数据
for ($i = 0; $i < $codeLength; $i++) {
$char = $code[$i];
if (!isset($charTable[$char])) {
$this->error = 'Code128 包含不支持的字符: ' . $char;
return false;
}
$value = $charTable[$char];
$checksum += $value * ($i + 1);
$data[] = $patterns[$value];
}
// 计算校验和
$checksum %= 103;
$data[] = $patterns[$checksum];
// 添加结束码
$data[] = '2331112';
// 添加起始和结束条
array_unshift($data, '1');
$data[] = '1';
return $data;
}
/**
* 生成 Code39 条形码
*
* @param string $code
* @return array
*/
private function generateCode39($code) {
// Code39 编码表
$patterns = [
'0' => '101001101101', '1' => '110100101011', '2' => '101100101011',
'3' => '110110010101', '4' => '101001101011', '5' => '110100110101',
'6' => '101100110101', '7' => '101001011011', '8' => '110100101101',
'9' => '101100101101', 'A' => '110101001011', 'B' => '101101001011',
'C' => '110110100101', 'D' => '101011001011', 'E' => '110101100101',
'F' => '101101100101', 'G' => '101010011011', 'H' => '110101001101',
'I' => '101101001101', 'J' => '101011001101', 'K' => '110101010011',
'L' => '101101010011', 'M' => '110110101001', 'N' => '101011010011',
'O' => '110101101001', 'P' => '101101101001', 'Q' => '101010110011',
'R' => '110101011001', 'S' => '101101011001', 'T' => '101011011001',
'U' => '110010101011', 'V' => '100110101011', 'W' => '110011010101',
'X' => '100101101011', 'Y' => '110010110101', 'Z' => '100110110101',
'-' => '100101011011', '.' => '110010101101', ' ' => '100110101101',
'$' => '100100100101', '/' => '100100101001', '+' => '100101001001',
'%' => '101001001001', '*' => '100101101101'
];
$code = strtoupper($code);
$data = [];
// 起始和结束标记
$data[] = $patterns['*'];
// 编码数据
$codeLength = strlen($code);
for ($i = 0; $i < $codeLength; $i++) {
$char = $code[$i];
if (!isset($patterns[$char])) {
$this->error = 'Code39 包含不支持的字符: ' . $char;
return false;
}
$data[] = $patterns[$char];
}
// 添加结束标记
$data[] = $patterns['*'];
return $data;
}
/**
* 生成 EAN-13 条形码
*
* @param string $code
* @return array
*/
private function generateEAN13($code) {
// EAN-13 编码表
$patternsL = [
'0' => '0001101', '1' => '0011001', '2' => '0010011', '3' => '0111101',
'4' => '0100011', '5' => '0110001', '6' => '0101111', '7' => '0111011',
'8' => '0110111', '9' => '0001011'
];
$patternsG = [
'0' => '0100111', '1' => '0110011', '2' => '0011011', '3' => '0100001',
'4' => '0011101', '5' => '0111001', '6' => '0000101', '7' => '0010001',
'8' => '0001001', '9' => '0010111'
];
$patternsR = [
'0' => '1110010', '1' => '1100110', '2' => '1101100', '3' => '1000010',
'4' => '1011100', '5' => '1001110', '6' => '1010000', '7' => '1000100',
'8' => '1001000', '9' => '1110100'
];
// 校验位计算
if (strlen($code) == 12) {
// 计算校验位
$sum = 0;
for ($i = 0; $i < 12; $i++) {
$digit = (int)$code[$i];
$sum += ($i % 2 == 0) ? $digit * 1 : $digit * 3;
}
$checkDigit = (10 - ($sum % 10)) % 10;
$code .= $checkDigit;
}
$data = [];
$data[] = '101'; // 起始标记
// 左半部分
$firstDigit = (int)$code[0];
for ($i = 1; $i < 7; $i++) {
$digit = (int)$code[$i];
// 根据首数字决定使用 L 还是 G 编码
$bit = ($firstDigit & (1 << (6 - $i))) ? $patternsG[$digit] : $patternsL[$digit];
$data[] = $bit;
}
$data[] = '01010'; // 中间标记
// 右半部分
for ($i = 7; $i < 13; $i++) {
$digit = (int)$code[$i];
$data[] = $patternsR[$digit];
}
$data[] = '101'; // 结束标记
return $data;
}
/**
* 生成 EAN-8 条形码
*
* @param string $code
* @return array
*/
private function generateEAN8($code) {
// 复用 EAN-13 的编码表
$patternsL = [
'0' => '0001101', '1' => '0011001', '2' => '0010011', '3' => '0111101',
'4' => '0100011', '5' => '0110001', '6' => '0101111', '7' => '0111011',
'8' => '0110111', '9' => '0001011'
];
$patternsR = [
'0' => '1110010', '1' => '1100110', '2' => '1101100', '3' => '1000010',
'4' => '1011100', '5' => '1001110', '6' => '1010000', '7' => '1000100',
'8' => '1001000', '9' => '1110100'
];
// 计算校验位
if (strlen($code) == 7) {
$sum = 0;
for ($i = 0; $i < 7; $i++) {
$digit = (int)$code[$i];
$sum += ($i % 2 == 0) ? $digit * 3 : $digit * 1;
}
$checkDigit = (10 - ($sum % 10)) % 10;
$code .= $checkDigit;
}
$data = [];
$data[] = '101'; // 起始标记
// 左半部分
for ($i = 0; $i < 4; $i++) {
$digit = (int)$code[$i];
$data[] = $patternsL[$digit];
}
$data[] = '01010'; // 中间标记
// 右半部分
for ($i = 4; $i < 8; $i++) {
$digit = (int)$code[$i];
$data[] = $patternsR[$digit];
}
$data[] = '101'; // 结束标记
return $data;
}
/**
* 生成 UPC-A 条形码
*
* @param string $code
* @return array
*/
private function generateUPCA($code) {
// UPC-A 使用 EAN-13 的编码表,但首数字固定为 0
$code = '0' . $code;
return $this->generateEAN13($code);
}
/**
* 生成 UPC-E 条形码
*
* @param string $code
* @return array
*/
private function generateUPCE($code) {
// UPC-E 编码表
$patternsL = [
'0' => '0001101', '1' => '0011001', '2' => '0010011', '3' => '0111101',
'4' => '0100011', '5' => '0110001', '6' => '0101111', '7' => '0111011',
'8' => '0110111', '9' => '0001011'
];
$patternsR = [
'0' => '1110010', '1' => '1100110', '2' => '1101100', '3' => '1000010',
'4' => '1011100', '5' => '1001110', '6' => '1010000', '7' => '1000100',
'8' => '1001000', '9' => '1110100'
];
$data = [];
$data[] = '101'; // 起始标记
// 编码数据
for ($i = 0; $i < 6; $i++) {
$digit = (int)$code[$i];
$data[] = $patternsL[$digit];
}
$data[] = '01010'; // 中间标记
// 右半部分
for ($i = 6; $i < 12 && isset($code[$i]); $i++) {
$digit = (int)$code[$i];
$data[] = $patternsR[$digit];
}
$data[] = '101'; // 结束标记
return $data;
}
/**
* 创建条形码图像
*
* @param array $barcodeData 条形码数据
* @param string $format 图像格式
* @return resource|false 图像资源
*/
private function createImage($barcodeData, $format) {
// 计算条形码宽度
$width = 0;
foreach ($barcodeData as $pattern) {
$width += strlen($pattern);
}
// 添加空白区域
$quietZone = 10 * $this->scale;
$width = ($width * $this->scale) + ($quietZone * 2);
$height = $this->height + 20; // 额外空间给文字
// 创建画布
$image = imagecreate($width, $height);
// 设置颜色
$bgColor = imagecolorallocate($image,
$this->backgroundColor[0],
$this->backgroundColor[1],
$this->backgroundColor[2]
);
$fgColor = imagecolorallocate($image,
$this->foregroundColor[0],
$this->foregroundColor[1],
$this->foregroundColor[2]
);
// 填充背景
imagefill($image, 0, 0, $bgColor);
// 绘制条形码
$x = $quietZone;
$barWidth = $this->scale;
foreach ($barcodeData as $pattern) {
$patternLength = strlen($pattern);
for ($i = 0; $i < $patternLength; $i++) {
if ($pattern[$i] == '1') {
// 画条
imagefilledrectangle($image, $x, 0,
$x + $barWidth - 1, $this->height, $fgColor);
}
$x += $barWidth;
}
}
return $image;
}
/**
* 输出条形码图片
*
* @param string $code 条形码内容
* @param string $type 条形码类型
* @param string $format 输出格式
* @param array $options 其他选项
* @return bool 是否成功输出
*/
public function output($code, $type = self::TYPE_CODE128, $format = self::FORMAT_PNG, $options = []) {
// 设置参数
$scale = isset($options['scale']) ? $options['scale'] : 2;
$height = isset($options['height']) ? $options['height'] : 50;
$foreground = isset($options['foreground']) ? $options['foreground'] : null;
$background = isset($options['background']) ? $options['background'] : null;
// 生成条形码
$image = $this->generate($code, $type, $format, $scale, $height, $foreground, $background);
if ($image === false) {
return false;
}
// 设置响应头
$contentTypes = [
self::FORMAT_PNG => 'image/png',
self::FORMAT_JPEG => 'image/jpeg',
self::FORMAT_GIF => 'image/gif',
];
header('Content-Type: ' . $contentTypes[$format]);
header('Content-Disposition: inline; filename="barcode.' . $format . '"');
// 输出图像
switch ($format) {
case self::FORMAT_PNG:
imagepng($image);
break;
case self::FORMAT_JPEG:
imagejpeg($image, null, 90);
break;
case self::FORMAT_GIF:
imagegif($image);
break;
}
// 释放内存
imagedestroy($image);
return true;
}
/**
* 保存条形码到文件
*
* @param string $code 条形码内容
* @param string $filename 文件名
* @param string $type 条形码类型
* @param array $options 其他选项
* @return bool 是否成功保存
*/
public function save($code, $filename, $type = self::TYPE_CODE128, $options = []) {
// 确定格式
$extension = strtolower(pathinfo($filename, PATHINFO_EXTENSION));
$formatMap = [
'png' => self::FORMAT_PNG,
'jpg' => self::FORMAT_JPEG,
'jpeg' => self::FORMAT_JPEG,
'gif' => self::FORMAT_GIF,
];
if (!isset($formatMap[$extension])) {
$this->error = '不支持的文件格式: ' . $extension;
return false;
}
$format = $formatMap[$extension];
// 设置参数
$scale = isset($options['scale']) ? $options['scale'] : 2;
$height = isset($options['height']) ? $options['height'] : 50;
$foreground = isset($options['foreground']) ? $options['foreground'] : null;
$background = isset($options['background']) ? $options['background'] : null;
// 生成条形码
$image = $this->generate($code, $type, $format, $scale, $height, $foreground, $background);
if ($image === false) {
return false;
}
// 保存图像
$result = false;
switch ($format) {
case self::FORMAT_PNG:
$result = imagepng($image, $filename);
break;
case self::FORMAT_JPEG:
$result = imagejpeg($image, $filename, 90);
break;
case self::FORMAT_GIF:
$result = imagegif($image, $filename);
break;
}
// 释放内存
imagedestroy($image);
return $result;
}
/**
* 获取最后错误信息
*
* @return string|null 错误信息
*/
public function getError() {
return $this->error;
}
}
// 使用示例文件:barcode_example.php
?>
使用示例
<?php
// 包含类文件
require_once 'BarcodeGenerator.php';
// 创建条形码生成器实例
$barcode = new BarcodeGenerator();
// 示例1:直接从浏览器输出
$barcode->output('1234567890123', BarcodeGenerator::TYPE_EAN13, BarcodeGenerator::FORMAT_PNG, [
'scale' => 2,
'height' => 50,
'foreground' => [0, 0, 0],
'background' => [255, 255, 255]
]);
// 示例2:保存到文件
$result = $barcode->save('ABC-123', 'barcode.png', BarcodeGenerator::TYPE_CODE128, [
'scale' => 3,
'height' => 60,
'foreground' => [0, 0, 255], // 蓝色
'background' => [255, 255, 255]
]);
if (!$result) {
echo "保存失败: " . $barcode->getError();
}else{
echo "保存成功!";
}
// 示例3:获取图片资源
$image = $barcode->generate('1234567890123', BarcodeGenerator::TYPE_EAN13, BarcodeGenerator::FORMAT_PNG, 2, 50);
if ($image !== false) {
// 在这里可以操作图片资源
imagedestroy($image);
}
// 示例4:多种条形码类型
$barcodeTypes = [
['code' => '1234567890', 'type' => BarcodeGenerator::TYPE_CODE128],
['code' => '123456789', 'type' => BarcodeGenerator::TYPE_CODE39],
['code' => '1234567890128', 'type' => BarcodeGenerator::TYPE_EAN13],
['code' => '12345678', 'type' => BarcodeGenerator::TYPE_EAN8],
['code' => '12345678901', 'type' => BarcodeGenerator::TYPE_UPC_A],
['code' => '123456', 'type' => BarcodeGenerator::TYPE_UPC_E]
];
foreach ($barcodeTypes as $item) {
$filename = strtolower($item['type']) . '.png';
if ($barcode->save($item['code'], $filename, $item['type'])) {
echo "生成 {$filename} 成功<br>";
} else {
echo "生成 {$filename} 失败: " . $barcode->getError() . "<br>";
}
}
?>
HTML 表单示例
<!DOCTYPE html>
<html>
<head>条形码生成器</title>
<style>
body { font-family: Arial, sans-serif; padding: 20px; }
.form-group { margin-bottom: 10px; }
label { display: inline-block; width: 100px; }
input, select { width: 200px; padding: 5px; }
button { margin-top: 10px; padding: 8px 20px; }
</style>
</head>
<body>
<h2>PHP 条形码生成器</h2>
<form method="post" action="generate.php">
<div class="form-group">
<label>条码内容:</label>
<input type="text" name="code" required>
</div>
<div class="form-group">
<label>条码类型:</label>
<select name="type">
<option value="code128">Code 128</option>
<option value="code39">Code 39</option>
<option value="ean13">EAN-13</option>
<option value="ean8">EAN-8</option>
<option value="upca">UPC-A</option>
<option value="upce">UPC-E</option>
</select>
</div>
<div class="form-group">
<label>图片格式:</label>
<select name="format">
<option value="png">PNG</option>
<option value="jpeg">JPEG</option>
<option value="gif">GIF</option>
</select>
</div>
<div class="form-group">
<label>高度:</label>
<input type="number" name="height" value="50" min="20" max="200">
</div>
<button type="submit">生成条形码</button>
</form>
</body>
</html>
generate.php 处理脚本
<?php
// generate.php
require_once 'BarcodeGenerator.php';
// 获取 POST 数据
$code = isset($_POST['code']) ? $_POST['code'] : '';
$type = isset($_POST['type']) ? $_POST['type'] : 'code128';
$format = isset($_POST['format']) ? $_POST['format'] : 'png';
$height = isset($_POST['height']) ? (int)$_POST['height'] : 50;
// 类型映射
$typeMap = [
'code128' => BarcodeGenerator::TYPE_CODE128,
'code39' => BarcodeGenerator::TYPE_CODE39,
'ean13' => BarcodeGenerator::TYPE_EAN13,
'ean8' => BarcodeGenerator::TYPE_EAN8,
'upca' => BarcodeGenerator::TYPE_UPC_A,
'upce' => BarcodeGenerator::TYPE_UPC_E,
];
// 格式映射
$formatMap = [
'png' => BarcodeGenerator::FORMAT_PNG,
'jpeg' => BarcodeGenerator::FORMAT_JPEG,
'gif' => BarcodeGenerator::FORMAT_GIF,
];
if (!isset($typeMap[$type])) {
die('无效的条码类型');
}
if (!isset($formatMap[$format])) {
die('无效的图片格式');
}
$barcode = new BarcodeGenerator();
// 输出条形码
$barcode->output($code, $typeMap[$type], $formatMap[$format], [
'scale' => 2,
'height' => $height,
'foreground' => [0, 0, 0],
'background' => [255, 255, 255]
]);
// 如果失败了
if ($barcode->getError()) {
echo "生成失败: " . $barcode->getError();
}
?>
特性说明
主要功能:
- 多格式支持:Code128、Code39、EAN-13、EAN-8、UPC-A、UPC-E