Layer是一个很好用且实用性较强的弹窗解决方案。

但对于icon的参数,官方没有给出明确的说明,我便在此记录一下,便于之后使用。


官方说明:


调试代码:

layer.open({
icon:0-6
,title: '图标调试'
,content: '这是0-6'
});


调试结果:  









提示:默认皮肤可以传入0-6为icon参数,如果传入大于6的值,会显示为参数为0的图标!如下:


调试代码:

layer.open({
icon:10000
,title: '图标调试'
,content: '这是10000'
});

结果:


  •  2019-05-26 14:55:09   857
因为本人毕业设计中需要用到excel表的导入导出,后台使用的ThinkPHP5框架,所以使用PhpSpreadsheet来完成该功能,此处记录导出功能遇到的问题。
先画个重点:PhpSpreadsheet中$writer -> save('php://output');虽然可以不保存直接下载excel文件,但如果我们是使用ajax和后台交互的话,excel文件是不会下载的。

这种时候,我想到的解决方式有三种:

1.不使用ajax。因为我之前的项目必须使用ajax,所以这种方式我就不介绍了,不使用ajax的话百度有大把方案可行;

2.$writer -> save('php://output')改为$writer -> save('filename.xlsx'),即不下载保存在服务器中,然后我们把文件路径返回,在ajax的成功回调函数中拉起下载。这个方法是我一开始的思路,但是想到下载之后还有清除服务器上的文件,好像搞得麻烦很多,所以我也没采用此方案;

3.在一番面向百度编程后,我发现了一个好东西——jquery.fileDownload.js,该js可以让我们使用ajax也能调起excel文件下载,刚好解决了我们的问题。


步骤:

1.页面中导入该js:



2.后台的excel导出功能的封装函数:

<?php
/*
*excel导入导出操作封装类
*/

namespace app\admin\controller;


//使用Spreadsheet类
use PhpOffice\PhpSpreadsheet\Spreadsheet;
//xlsx格式类
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
//可以生成多种格式类
use PhpOffice\PhpSpreadsheet\IOFactory;



class Office
{

/**
* 导出excel表
* $data:要导出excel表的数据,接受一个二维数组
* $name:excel表的表名
* $head:excel表的表头,接受一个一维数组
* $key:$data中对应表头的键的数组,接受一个一维数组
* 备注:此函数缺点是,表头(对应列数)不能超过26;
*循环不够灵活,一个单元格中不方便存放两个数据库字段的值
*/
public function outdata($name='默认表名', $data=[], $head=[], $keys=[])
{
$count = count($head); //计算表头数量

$spreadsheet = new Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();

for ($i = 65; $i < $count + 65; $i++) { //数字转字母从65开始,循环设置表头:
$sheet->setCellValue(strtoupper(chr($i)) . '1', $head[$i - 65]);
}

/*--------------开始从数据库提取信息插入Excel表中------------------*/
foreach ($data as $key => $item) { //循环设置单元格:
//$key+2,因为第一行是表头,所以写到表格时 从第二行开始写
for ($i = 65; $i < $count + 65; $i++) { //数字转字母从65开始:
$sheet->setCellValue(strtoupper(chr($i)) . ($key + 2), $item[$keys[$i - 65]]);
$spreadsheet->getActiveSheet()->getColumnDimension(strtoupper(chr($i)))->setWidth(20); //固定列宽
}

}
header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');//告诉浏览器输出07Excel文件
header('Content-Disposition: attachment;filename="' . $name . '.xlsx"');
header('Cache-Control: max-age=0');//禁止缓存
header('Set-Cookie: fileDownload=true; path=/');
$writer = new Xlsx($spreadsheet);
$writer -> save('php://output');

//释放内存,防止内存泄露:
$spreadsheet->disconnectWorksheets();
unset($spreadsheet);
exit;
}
}


3.使用jquery.fileDownload.js传输数据下载excel:

function excelOutputStuList(res) {
    //res为我需要导出到excel表中的数据,因为我是先读取数据在页面上展示,展示页面有导出excel按钮,此变量为该按钮传来的页面上展示的所有数据。
    var index = layer.confirm('确定导出课程学生列表?', {
btn: ['确定','取消']
}, function(){
$.fileDownload('/admin.php/course/outputStuList', {
httpMethod: 'POST', /*我在调试时报错发现后台接收到的数据是[object object],[object object]形式的,无法解析; *所有在这里我用JSON.stringify(res)把传去后台的数据转换为json字符串,后台再使用json_decode($data,TRUE)转换为数组。
*/ data: 'data=' + JSON.stringify(res),
successCallback: function() {
layer.close(index);
},
failCallback: function() {
layer.msg('加载中..');
}
});
});
}


4.course控制器中的outputStuList()方法:

//excel导出课程学生列表
public function outputStuList(){
$data = request()->param('data');//json字符串 /*将json字符串转换为数组需要加第二个参数'TRUE',因为默认json_decode()函数第二个参数为FALSE,会将json字符串转换为对象*/ $res = json_decode($data,TRUE);
$excel = new Office();
//设置表头:
$head = ['学号','英文名','中文姓名','班级','国籍'];
//数据中对应的字段,用于读取相应数据:
$keys = ['stu_id', 'en_name', 'cn_name', 'class', 'nationality']; //调用封装的excel导出方法outdata($name='默认表名', $data=[], $head=[], $keys=[]);

$excel->outdata($data[0]['course_name'].'学生列表', $res, $head, $keys);
}
注:json_encode() 对变量进行JSON编码;json_decode() 对JSON数据进行解码,转换为PHP变量。


至此,excel成功导出!


  •  2019-03-30 22:41:05   1378

平时写前端经常会写到表单,而表单的label标签会因为字符数的长度不一样而造成对不齐,如图:


这种时候,我们就需要使用中文占位符来使表单对齐。

&#32; == 普通的英文半角空格;
&#160; == &nbsp; == &#xA0; == no-break space (普通的英文半角空格但不换行);
&#12288; == 一个中文宽度;
&#8194; == &ensp; == 半个中文宽度;
&#8195; == &emsp; == 一个中文宽度;
&#8197; == 四分之一中文宽度;


对齐代码:

<label for="pwd">新 密 码:</label>


对齐后:


  •  2019-03-20 16:15:24   712

产生原因  

模板文件生成html文件之后会在body开头处加入一个可见的控制符,

导致页面头部会出现一个空白行。原因是页面的编码是UTF-8 + BOM。 

这种编码方式一般会在windows操作系统中出现,

比如WINDOWS自带的记事本等软件,在保存一个以UTF-8编码的文件时,

会在文件开始的地方插入三个不可见的字符(0xEF 0xBB 0xBF,即BOM)。

它是一串隐藏的字符,用于让记事本等编辑器识别这个文件是否以UTF-8编码。对于一般的文件,这样并不会产生什么麻烦。但对于 PHP来说,BOM是个大麻烦。因为PHP并不会忽略BOM,所以在读取、包含或者引用这些文件时,会把BOM作为该文件开头正文的一部分。根据嵌入式语言的特点,这串字符将被直接执行(显示)出来。由此造成即使页面的 top padding 设置为0,也无法让整个网页紧贴浏览器顶部,因为在html一开头有这3个隐藏字符! 


解决办法

最好写代码的时候用编译器编写,不要用记事本编写代码。

出现出错后,下载一个UltraEdit

打开UltraEdit,在UltraEdit里打开带隐藏字符的文件,然后另存为,窗口最下面最左边有一个选项,显示默认,打开下拉条选择utf-8无BOM,然后回车,去你保存的文件位置找到,拖拽到项目里,完成。

  •  2019-02-04 01:01:14   1007

  因为本人毕业设计选题是留学生教务管理系统,使用的是TP5框架,而在做的过程中,需要用户(留学生)能够进行多语言的切换,所以详细看了TP5的文档也百度查阅了一些资料,在这记录一下。

  首先,在配置文件中开启多语言模块:

// 默认语言
'default_lang'=> 'zh-cn',

//多语言开启
'lang_switch_on' => true, //语言列表
'lang_list' => ['zh-cn','en-us'],

  在这里,我就要自己写入en-us.php文件,关于此文件位置,文档里是这么说的:


在我的项目中我放在了模块下面:


然后en-us.php语言文件定义采用返回数组方式:

return [
'HomePage' => '网站首页',
'RecruitStudents' => '本科招生',
'Student status' => '学籍管理',
'Exam Manage' => '考试管理',
'Practice Teaching' => '实践教学',
'educational technology' => '教育技术',
'Download Area' => '下载区'
];

在视图文件中用{:lang()}标签渲染关键字:

//语言切换按钮

<div type="button" lang='cn' class='cn_en'>{:lang('Chinese')}</div>
<div type="button" lang='en' class='cn_en'>{:lang('English')}</div>
<nav>
<ul>
<li><a href="{:url('index/index')}">{:lang('HomePage')}</a></li>
<li><a href="#">{:lang('RecruitStudents')}</a></li>
<li><a href="#">{:lang('Student status')}</a></li>
<li><a href="#">{:lang('Exam Manage')}</a></li>
<li><a href="#">{:lang('Practice Teaching')}</a></li>
<li><a href="#">{:lang('Practice Teaching')}</a></li>
<li><a href="#">{:lang('educational technology')}</a></li>
<li><a href="#">{:lang('Download Area')}</a></li>
</ul>
</nav>

在控制器中写入语言切换的方法(如果多页面都要切换建议写入公共父类控制器中,此处我写在了common/Base.php中):

class Base extends Controller
{
public function lang() {
switch ($_GET['lang']) {
case 'cn':
cookie('think_var', 'en-us');
break;
case 'en':
cookie('think_var', 'zh-cn');
break;
//其它语言

default:
cookie('think_var','zh');

}
}
}

然后,当我们点击语言按钮的时候,通过Ajax访问控制器中的lang()方法:

<script>
$('.cn_en').click(function () {
var data = {'lang': $(this).attr('lang')} //Index控制器继承自Base.php $.get("{:url('Index/lang')}", data, function () { //页面刷新 location.reload();
})
})
</script>

到此,我们参照官方手册进行的多语言切换就算完成了,但如果遇到默认语言没有反应,跳转页面之后,也没有检测当前的语言的BUG的话,修改 thinkphp/library/think/Lang.php 里面的detect()自动检测语言方法:

public static function detect()
{
// 自动侦测设置获取语言选择
$langSet = Config::get('default_lang');
if (isset($_GET[self::$langDetectVar])) {
// url中设置了语言变量
$langSet = strtolower($_GET[self::$langDetectVar]);
Cookie::set(self::$langCookieVar, $langSet, 3600);
} elseif (Cookie::get(self::$langCookieVar)) {
// 获取上次用户的选择
$langSet = strtolower(Cookie::get(self::$langCookieVar));
} elseif ($langSet) {
// 获取默认语言
Cookie::set(self::$langCookieVar, $langSet, 3600);
} elseif (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
// 自动侦测浏览器语言
preg_match('/^([a-z\d\-]+)/i', $_SERVER['HTTP_ACCEPT_LANGUAGE'], $matches);
$langSet = strtolower($matches[1]);
Cookie::set(self::$langCookieVar, $langSet, 3600);
}
if (empty(self::$allowLangList) || in_array($langSet, self::$allowLangList)) {
// 合法的语言
self::$range = $langSet;
}
return self::$range;
}

效果截图:



  •  2019-01-15 13:53:18   672
  • 在我们完善一个网站的时候,会遇到上传头像、文档、压缩文件等等问题,html中用表单的 input:type="file"来把文件信息传递给后台都是众所周知的。
  • 那么在后台应该怎么处理呢?
  • php在处理交互方面有天然的优势,自然有强大的函数来处理“上传文件”。 


1.服务器端php.ini文件配置:


2.html的form表单:

<form action="doAction.php" method="post" enctype="multipart/form-data">
请选择文件:
<input type="file" name="myFile"><br>
<input type="submit" value="上传文件">
</form>

注意:1)表单必须为post方式提交;

          2)form中必须有 enctype="multipart/form-data" 属性


3.在doAction.php中先打印上传文件信息:

  //$_FILES:文件上传变量

print_r($_FILES);
exit();


网页信息: 

 


其中,myFile是form表单中input="file"的name属性的值。

解释:[name]:上传文件的原文件名;

          [type]:上传文件的属性;

          [tmp_name]:上传文件的临时保存目录及临时保存文件名;

          [error]:上传错误信息;

          [size]:上传文件大小。


[error]错误信息说明:  



4.doAction.php:  

<?php
header("content-type:text/html;charset:utf-8");//头信息
//1.通过$_FILES文件上传变量接收上传文件信息
$fileInfo = $_FILES['myFile'];
$filename = $fileInfo['name'];
$type = $fileInfo['type'];
$tmp_name = $fileInfo['tmp_name'];
$size = $fileInfo['size'];
$error = $fileInfo['error'];
//2.判断错误号,只有为0或者是UPLOAD_ERR_OK,没有错误发生,上传成功
if($error === UPLOAD_ERR_OK){
//上传成功将服务器上的临时文件移动到指定目录下(两种方式)
//move_uploaded_file($tmp_name,$destination):将服务器上的临时文件移动到指定目录下。成功返回true,否则返回false
//copy($src,$dst):将文件拷贝到指定目录,拷贝成功返回true,否则返回false
if(move_uploaded_file($tmp_name,"uploads/".$filename)){
echo "文件".$filename."上传成功";
}else{
echo "文件".$filename."上传失败";
}
}else{
//匹配错误信息
switch($error){
case 1:
echo '上传文件超过了php配置文件中upload_max_filesize选项的值';
break;
case 2:
echo '超过了表单MAX_FILE_SIZE限制的大小';
break;
case 3:
echo '文件部分被上传';
break;
case 4:
echo '没有选择上传文件';
break;
case 6:
echo '没有找到临时目录';
break;
case 7:
case 8:
echo '系统错误';
break;
}
}



转自博主PHP中文网博客 —— 吾生也有涯,而知也无涯
  •  2019-01-01 22:52:19   1021

首先,我们拆分一下验证码的组成: 

1)一个长方形的底图

2)验证码的内容(数字,数字+英文,中文)

3)各色的干扰点

4)长短颜色不一的干扰线段


下面,我们就拆分出来的这四点一一实现:

1.长方形的底图   

  我们所见的验证码一般都是一个100*30px的底图,有的中文验证码底图会大一点(200*60px),而这个底图是如何来的呢?

    在php语言中,有关于图像的处理有专门的函数库--GD库,不了解的先查询手册---php-图像处理和 GD

    了解该库后,我们还要确保自己的php中带有该库且该库开启。一般php都会带有且默认开启。我们可以用phpinfo();函数查看是否有该库存在,如果GD库已有但未开启则需要在php.ini extension=php_gd2.dll前面的分号去掉,重启apache。

    制作验证码所需的该GD库函数如下:

imagecreatetruecolor(int $width , int $height) — 新建一个真彩色图像(网页黑色背景);

imagecolorallocate( resource $image , int $red , int $green , int $blue ) — 为一幅图像分配颜色(RGB);

imagefill(resource $image , int $x , int $y , int $color ) — 区域填充(在$image上从坐标$x,$y处开始填充颜色$color);

imagestring(resource $image , int $font , int $x , int $y , string $s , int$col) — 水平地画一行字符串( 用 $col 颜色将字符串 $s 画到 $image 所代表的图像的$x,$y 坐标处);

imagettftext( resource $image , float $size , float $angle , int $x , int$y , int $color , string $fontfile , string $text)— 用 TrueType 字体向图像写入文本($angle表示字符偏转的角度)

imagesetpixel(resource $image , int $x , int $y , int $color) — 画一个单一像素点(在 $image 图像中用 $color 颜色在$x,$y 坐标上画一个点),即验证码上的干扰点;

imageline(resource $image , int $x1 , int $y1 , int $x2 , int $y2 , int$color) — 画一条线段(两点确定一条直线,用于验证码干扰线段);

imagepng(resource $image , string $filename) — 以 PNG 格式将图像输出到浏览器或文件(将 GD 图像流($image)以 PNG 格式输出到标准输出(通常为浏览器),或者如果用$filename 给出了文件名则将其输出到该文件。)

imagedestroy(resource $image) — 销毁一图像(资源销毁)

上面这些函数,足够完成我们的验证码,我们先完成验证码底图的制作: 

<?php
session_start();//开启session。session功能保存验证码内容用于验证输入验证码是否正确

$image = imagecreatetruecolor(100,30);//生成一个100*30px的真彩色图像
$bgcolor = imagecolorallocate($image,255,255,255);//白色
imagefill($image,0,0,$bgcolor);//将$image完全填充为白色,即白色底图

2.验证码的内容(数字,数字+英文,中文)  

 100*30底图完成后,我们应在底图上添加验证码内容:

        a.数字验证码:

$captch_code = '';//保存验证码字符串,后面存入session用于session验证
//验证码随机四个数字
for ($i=0;$i<4;$i++){
$fontsize = 6;//使用字体
$fontcolor = imagecolorallocate($image,rand(0,120),rand(0,120),rand(0,120));//数字颜色,因为底图为白色,所以四个数字随机区域为深色区域
$fontcontent = rand(0,9);//0-9随机数字
$captch_code .= $fontcontent;//字符串拼接到$captch_code

$x=($i*100/4) + rand(5,10);//数字在底图上的x坐标,利用变量$i使数字保持间距
$y=rand(5,10);//y坐标

imagestring($image,$fontsize,$x,$y,$fontcontent,$fontcolor);//将数字$fontcontent以颜色$fontcolor、字体大小$fontsize画到$image的$x,$y处
}
$_SESSION['authcode'] = $captch_code;//保存验证信息,等待校验

        b.数字+字母验证码: 

$captch_code = '';//保存验证码字符串,后面存入session用于session验证
//数字字母混合
for ($i=0;$i<4;$i++){
$fontsize = 6;
$fontcolor = imagecolorallocate($image,rand(0,120),rand(0,120),rand(0,120));
$data = 'qwertyuiplkjhgfdsazxcvbnm123456789';//所有数字字母组成的字符串,为用户考虑去除难辨识的o和0;
$fontcontent = substr($data,rand(0,strlen($data)),1);//从$data中随机取出一个字符
$captch_code .= $fontcontent;//字符串拼接到$captch_code

$x=($i*100/4) + rand(5,10);
$y=rand(5,10);

imagestring($image,$fontsize,$x,$y,$fontcontent,$fontcolor);
}

$_SESSION['authcode'] = $captch_code;//保存验证信息

        c.中文验证码:

        注意,中文验证码必须导入支持中文的字体文件,windows系统可以在控制面板-字体中查找。

$captch_code = '';//保存验证码,用于session验证

$fontface = 'simkai.ttf';//字体文件
//汉字库,就是可能随机出现在底图上的所有中文内容
$str = "肥哦富农卫生费呢哦肥婆飞马珀耳风光迷人惠恩或嗯哦分配热攻击内容个人哦法二夫人很愉快热望特如果以后突然语句一进门就十足的傻瓜他会放过冰女冰女并承诺纷纷热狗后台交互同意木有就如同过河去啊封闭设备覅为法国梧桐耶夫北京市的发表都被你为防备分别是的小蜜蜂内裤我放不下的尽快发呢我尽快发布弄撒的烦恼腹部欸数量";
$strdb = str_split($str,3); //把字符串切割成数组,一个汉字占用三个字节。

//四个中文验证码
for ($i=0;$i<4;$i++){
$fontcolor = imagecolorallocate($image,rand(0,120),rand(0,120),rand(0,120));

$index = rand(0,count($strdb)-1);//产生随机数,$strdb下标是从0开始的,所以count()的值-1.
$cn = $strdb[$index];//随机选取汉字
$captch_code .= $cn;//汉字拼接到$captch_code,用于验证

//imagestring()函数不支持中文,此处改用imagettftext();
imagettftext($image,mt_rand(20,24),mt_rand(-60,60),(40*$i+20),mt_rand(30,35),$fontcolor,$fontface,$cn);
}
$_SESSION['authcode'] = $captch_code;//保存验证信息

3.各色的干扰点  

验证码为防止被机器识别,还应添加干扰信息,此处添加干扰点: 

//增加干扰元素(点),干扰点不可太少也不应太多,200适中
for ($i=0;$i<200;$i++){
$pointcolor = imagecolorallocate($image,rand(50,200),rand(50,200),rand(50,200));//干扰点的颜色不应该干扰用户正常阅读验证码内容,所以随机浅色区域
imagesetpixel($image,rand(1,99),rand(1,29),$pointcolor);
}

4.长短颜色不一的干扰线段  

更进一步可添加干扰线段: 

//干扰元素(线)
for ($i=0;$i<3;$i++){
$linecolor = imagecolorallocate($image,rand(80,200),rand(80,200),rand(80,200));
imageline($image,rand(1,99),rand(1,29),rand(1,99),rand(1,29),$linecolor);
}

至此,一个验证码的四个基本组成部分我们便完成了,我们可以查看一下验证码是否正常输出: 

header('content-type:image/png');//输出前添加文件头信息
imagepng($image);

//end 资源销毁
imagedestroy($image);

我们以数字+英文验证码为例:  

 

 正常输出,每次刷新改变:


验证码的制作到此算是基本完成了。接下来就是验证表单提交的验证码是否正确:

表单form.php:

<form action="captcha_check.php" method="post">
<!-- 验证码路径添加一个随机数参数,防止路径图片被缓存-->
验证码:<img src="captcha.php?r=<?php echo rand() ?>"><br>
请输入验证码:<input type="text" name="captcha"><br>
<input type="submit" value="提交">
</form>

接收验证captcha_check.php: 

<?php
session_start();

//$_REQUEST接收用户输入的验证码
if ($_REQUEST['captcha'] == $_SESSION['authcode']){
echo '验证码正确';
}else{
echo '验证码错误';
}

结果: 




转自博主PHP中文网的博客——吾生也有涯,而知也无涯

 

  •  2019-01-01 20:42:10   924

热门文章 关于前台使用ajax后台使用PhpSpreadsheet从数据库导出excel 对于Laravel Blade模板转义html标签的记录 PHP-文件上传 去除隐藏字符—— PHP-验证码制作

tips:仅支持jpg,jpeg,png格式图片。