PHP QR Code 是一个PHP二维码生成类库,利用它可以轻松生成二维码,注:请确保你的PHP支持GD2
项目地址:http://phpqrcode.sourceforge.net
- 该类库原生不支持生成固定大小的二维码图片的(默认是根据二维码数据内容的长度而变化大小)
- 该类库不支持生成带有icon的二维码
我对该类库进行了修改,同时封装了一个QRcode类,简化操作的同时,实现了上述两个功能:
<?php
/**
* 二维码服务.
*
* @author 979137@qq.com
* @copyright ©2015, Sina App Engine.
* @version Id
*/
class SaeQRcode {
private errMsg = 'success';
privateerrNum = 0;
//二维码配置参数
public data = '';
publiclevel = 'M';
public width = 200;
publicheight = 200;
public margin = 0;
publicicon = '';
public saveUrl = '';
//生成的二维码文件
privatecode = '';
/**
* 生成二维码图片
*
* @desc
*
* @access public
* @return void
* @exception none
*/
public function build() {
static qrcode = false;
if (!qrcode) {
include(__DIR__.'/phpqrcode.php');
qrcode = true;
}
if (trim(this->data) == '') {
this->errNum = -1;this->errMsg = 'data cannot be empty!';
return false;
} elseif (!in_array(this->level, array('L','M','Q','H'))) {this->errNum = -2;
this->errMsg = 'level optional values: L, M, Q, H';
return false;
} elseif (!is_numeric(this->width) || !is_numeric(this->height)) {this->errNum = -3;
this->errMsg = 'width and height parameter error';
return false;
}this->code = this->saveUrl . md5((microtime(true)*10000).uniqid(time())) . '.png';
try {
defined('QRCODE_IMG_W') or define('QRCODE_IMG_W', this->width);
defined('QRCODE_IMG_H') or define('QRCODE_IMG_H',this->height);
QRcode::png(this->data,this->code, this->level, 3,this->margin);
} catch(Exception e) {this->errNum = -4;
this->errMsg =e->getMessage();
return false;
}
if (trim(this->icon) != '') {
returnthis->iconCover() ? this->code : false;
}
returnthis->code;
}
/**
* icon覆盖
*
* @desc
*
* @access public
* @return boolean
* @exception none
*/
public function iconCover() {
if (!is_file(this->code) ||this->fileType(this->code) != 'png') {this->errNum = -10;
this->errMsg = 'QRcode file does not exist or file type is not supported(Only allow PNG)';
return false;
}
//远程icon,先下载到本地
if (filter_var(this->icon, FILTER_VALIDATE_URL)) {
//TODO..
}
if (!is_file(this->icon) || !in_array(this->fileType(this->icon), array('png','jpg','gif'))) {this->errNum = -11;
this->errMsg = 'icon file does not exist or file type is not supported(Only allow PNG,JPG,GIF)';
return false;
}codeData = file_get_contents(this->code);iconData = file_get_contents(this->icon);code = imagecreatefromstring(codeData);icon = imagecreatefromstring(iconData);
list(code_w, code_h) = array(imagesx(code), imagesy(code));
list(icon_w, icon_h) = array(imagesx(icon), imagesy(icon));
//目标宽高(等比例缩小)icon_code_w = code_w / 5;scale = icon_w /icon_code_w;
icon_code_h =icon_h / scale;
//目标XY坐标(将icon置于二维码正中间)dst_x = (code_w -icon_code_w) / 2;
dst_y = (code_h - icon_code_h) / 2;
imagecopyresampled(code, icon,dst_x, dst_y, 0, 0,icon_code_w, icon_code_h,icon_w, icon_h);
return imagepng(code, this->code);
}
/**
* 取二进制文件头快速准确判断文件类型
* * @desc
* * @access public
* @paramsfile 要判断的文件,支持相对和绝对路径
* @return void
* @exception none
*/
public function fileType(file) {filepath = realpath(file);filetype = array(
7790=>'exe', 7784=>'midi',
8075=>'zip', 8297=>'rar',
7173=>'gif', 6677=>'bmp', 13780=>'png', 255216=>'jpg'
);
if (!(fp = @fopen(filepath, 'rb'))) return false;
bin = fread(fp, 2);
fclose(fp);str_info = @unpack('C2chars', bin);str_code = intval(str_info['chars1'].str_info['chars2']);
return isset(filetype[str_code]) ? filetype[str_code] : false;
}
/**
* 获取错误信息
*
* @desc
*
* @access public
* @return string
* @exception none
*/
public function errmsg() {
ret =this->errMsg;
this->errMsg = 'Success';
returnret;
}
/**
* 获取错误码
*
* @desc
*
* @access public
* @return int
* @exception none
*/
public function errno() {
ret =this->errNum;
this->errNum = 0;
returnret;
}
}
调用示例:
<?php
//二维码名片,格式参考:http://en.wikipedia.org/wiki/VCard
vCard = 'BEGIN:VCARD'.PHP_EOL;vCard .= 'VERSION:4.0'.PHP_EOL;
vCard .= 'FN:倒流'.PHP_EOL;vCard .= 'ORG:SINA Inc'.PHP_EOL;
vCard .= 'TITLE:攻城师'.PHP_EOL;vCard .= 'TEL;WORK;VOICE:(010)62676155'.PHP_EOL;
vCard .= 'TEL;HOME;VOICE:(010)88889999'.PHP_EOL;vCard .= 'TEL;TYPE=cell:18600005940'.PHP_EOL;
vCard .= 'ADR;TYPE=work;LABEL="Office":理想国际大厦17层;北四环西路58号;海淀区;北京市;中国;100089'.PHP_EOL;vCard .= 'EMAIL:979137@qq.com'.PHP_EOL;
vCard .= 'END:VCARD';
//注:不同的扫描工具解码方式不一样,所以不是所有的二维码扫描工具都能唤起相关的功能types = array(
'vCard' => vCard,
'url' => 'http://sae.sina.com.cn',
'tel' => 'tel:18600005940',
'smsto' => 'smsto:18600005940:晚上继续嗨皮',
'mailto' => 'mailto:979137@qq.com?subject='.urlencode('恭喜发财').'&body='.urlencode('红包拿来'),
'skype' => 'skype:'.urlencode('Skype用户名').'?call',
'chinese' => '中文二维码内容',
);qr = new QRcode();
//设置二维码生成参数
//二维码内容数据
qr->data =types['vCard'];
//校正级别(容错率):L(7%)、M(15%)、Q(25%)、H(30%),了解:http://baike.baidu.com/view/4144600.htm
qr->level = 'L';
//二维码宽高(包含间距),为保证二维码更易识别,请尽量保持二维码为正方形,即长宽大致相等,默认200*200qr->width = 300;
qr->height = 300;
//二维码图片边缘间距值,值越大,间距越宽,可自由调整,默认0qr->margin = 1;
//在二维码正中间放置icon,默认为空,即不放置,支持绝对与相对地址
qr->icon = __DIR__ . '/logo.png';qr->icon = 'logo.png';
//图片保存路径
qr->saveUrl = SAE_TMP_PATH;
//生成二维码图片,成功返回文件绝对地址,失败返回falsefile = qr->build();
if (!file) {
var_dump(qr->errno(),qr->errmsg());
exit;
}
//直接输出图片
//header('Content-Type: image/png');
//exit(file_get_contents(file));
//根据实际需求,可上传至Storage(这里以SAE为例)name = 'test/'.pathinfo(file, PATHINFO_BASENAME);domain = 'public';
st = new SaeStorage();st->upload(domain,name, file);url = sprintf('http://%s-%s.stor.sinaapp.com/%s', _SERVER['HTTP_APPNAME'],domain, name);
echo '<img src="'.url.'">';
