首页
关于小站
朋友
壁纸
留言
时光之书
笔顺字帖
LayUI手册
Search
1
【PHP】PHPoffice/PHPSpreadsheet读取和写入Excel
1,786 阅读
2
【Layui】控制页面元素展示隐藏
1,602 阅读
3
【Git】No tracked branch configured for branch master or the branch doesn't exist.
1,561 阅读
4
【PHP】PHP实现JWT生成和验证
1,483 阅读
5
【composer】composer常用命令
1,357 阅读
默认分类
PHP
ThinkPHP
Laravel
面向对象
设计模式
算法
基础
网络安全
webman
Web
HTML
CSS
JavaScript
jQuery
Layui
VUE
uni-app
Database
MySQL
Redis
RabbitMQ
Nginx
Git
Linux
Soft Ware
Windows
网赚
Go
Docker
Elasticsearch
登录
Search
标签搜索
PHP
函数
方法
类
MySQL
ThinkPHP
JavaScript
OOP
Layui
Web
Server
Docker
PHPSpreadsheet
PHPoffice
Array
设计模式
Nginx
Git
排序算法
基础
小破孩
累计撰写
256
篇文章
累计收到
13
条评论
首页
栏目
默认分类
PHP
ThinkPHP
Laravel
面向对象
设计模式
算法
基础
网络安全
webman
Web
HTML
CSS
JavaScript
jQuery
Layui
VUE
uni-app
Database
MySQL
Redis
RabbitMQ
Nginx
Git
Linux
Soft Ware
Windows
网赚
Go
Docker
Elasticsearch
页面
关于小站
朋友
壁纸
留言
时光之书
笔顺字帖
LayUI手册
搜索到
252
篇与
的结果
2022-06-23
【Layui】x-admin后台页面使用layer.msg提示失败解决办法
form.on 监听提交,所包含的代码最后要加上 return false; layui.use(['form', 'layer'], function() { $ = layui.jquery; var form = layui.form, layer = layui.layer; //自定义验证规则 form.verify({ pass: [/(.+){6,12}$/, '密码必须6到12位'], repass: function(value) { if ($('#L_pass').val() != $('#L_repass').val()) { return '两次密码不一致'; } }, phonesms:function(value){ if(!value.match('^[0-9]*$')){ return '验证码是数字'; } if(value.length != 6){ return '验证码长度是6位数字'; } } }); //监听提交 form.on('submit(add)', function(data) { //发异步,把数据提交给php layer.confirm('是否确定进行下一步',{ icon: 3, //问号的表情 btn: ['下一步','取消'] ,//按钮 },function () { var result = data.field, info = $('.layui-form').serialize(); $.ajax({ url:"{:url('page/registOne')}", type:'get', dataType: "json", data:$('.layui-form').serialize(), success:function(res){ // console.log(res); // return false; if(res.code == 200){ layer.msg(res.message, { icon: 6,//成功的表情 time: 3000 //3秒关闭(如果不配置,默认是3秒) }, function(){ // location.reload(); location.href="{:url('page/registTwo')}"; }); }else{ layer.msg(res.message,{icon: 5});//失败的表情 return; } }, }); }); return false; }) });
2022年06月23日
267 阅读
0 评论
0 点赞
2022-06-21
【PHP】根据身份证号码获取 性别,年龄,出生日期 的信息
//18位身份证取性别,倒数第二位奇数是男,偶数是女; $sex = substr($idcard, (strlen($idcard)==18 ? -2 : -1), 1) % 2 ? '1' : '2'; //取身份证年月日; $birthday = strlen($idcard)==15 ? ('19' . substr($idcard, 6, 6)) : substr($idcard, 6, 8); //身份证年月日转换成时间戳 $birthdays = strtotime(strlen($idcard)==15 ? ('19' . substr($idcard, 6, 6)) : substr($idcard, 6, 8)); //取当天日期; $today = strtotime('today'); //用时间戳相减算出年龄; $diff = floor(($today-$birthdays)/86400/365); //取出年龄值; $age = strtotime(substr($idcard,6,8).'+'.$diff.'years')>$today?($diff+1):$diff;
2022年06月21日
502 阅读
0 评论
0 点赞
2022-06-21
【PHP】CURL调用https请求的接口
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); 加上这两行,完美解决
2022年06月21日
332 阅读
0 评论
0 点赞
2022-06-21
【PHP】GET和POST传输方式的区别
Get方式是从服务器上获取数据,在数据查询时,建议用Get方式;如商品信息接口、搜索接口等Post方式是向服务器传送数据,做数据添加、修改或删除时,建议用Post方式,如登录注册接口等。1、GET是用来从服务器上获取数据,而POST是用来向服务器上传递数据。2、GET将表单中数据按照variable=value的形式,添加到action所指向的URL后面,并且两者使用“?”连接;而各个变量之间用“&”连接。POST是将表单中的数据放在FORM数据体中,按照变量和值相对应的方式,传递到Action指向的URL中。3、GET是不安全的,因为在传输过程,数据被放在请求的URL中,而如今很多服务器或代理服务器会把请求的URL放到日志文件中,这样会有一些隐私信息会被第三方看到。另外,用户也可以在浏览器上直接看到提交的数据,一些系统内部消息会一同显示在用户面前。POST的所有操作对用户来说是不可见的。4、GET传输的数据量小,主要是受URL长度限制,而POST可以传输大量数据,所以上传文件只能使用POST。5、GET限制FORM表的数据集的值必须为ASCII字符,而POST支持整个ISO10646字符集。Post和Get的区别:1)Get请求只是简单的获取数据,不修改请求的资源;而POST请求会修改请求的资源。导致的后果说相同的GET请求能获取相同的资源,而POST不能保证获取相同的资源。2)GET请求的参数在HTTP中是通过URL传递的,而POST请求的数据是通过requestbody传递的。3)GET请求资源在服务器上能够缓存,POST请求就不能够了。4)GET请求的参数的数据长度是有限制的,而POST请求的数据长度没有限制。5)GET请求无法传递二进制数据到服务器上,而POST可以。1、GET参数通过URL传递,POST放在REQUEST BODY中。2、GET请求在URL中传递是有长度限制的,而POST没有。3、GET比POST更不安全,因为参数直接暴露在URL中,所以不能传递敏感信息。4、GET请求只能进行URL编码,而POST支持多种编码方式。5、GET请求参数会完整保留在浏览器历史记录中,而POST中的参数不会被保留。Get和POST请求有什么区别?1、get比post更不安全2、get传输的数据长度比post小3、get通过在URL后拼接字符串的形式传递参数,post将参数放在RequestBody中4、get产生一个TCP数据包;post产生两个TCP数据包。(get会把 httpheader 和 data 一起发送给服务器,服务器会响应200,post会先把httpheader发送给服务端,服务端响应100,提示客户端继续发送。浏览器接着发送data给服务端。最终服务端响应200)5、get请求可以被缓存起来,post不行
2022年06月21日
317 阅读
0 评论
0 点赞
2022-06-21
【MySQL】MyISAM与InnoDB区别
在MySQL数据库中,有四种存储引擎:MEMORY存储引擎、MERGE存储引擎、MyIASM存储引擎、Innodb存储引擎。常用的引擎主要就是2个:Innodb和MyIASM。这里就只讨论Innodb和MyIASM的区别。1、 构造上的区别MyISAM在磁盘上存储成三个文件,其中.frm文件存储表定义;.MYD (MYData)为数据文件;.MYI (MYIndex)为索引文件。innodb是由.frm文件、表空间(分为独立表空间或者共享表空间)和日志文件(redo log)组成。2、事务上的区别myisam不支持事务;而innodb支持事务3、锁上的区别myisam使用的是表锁;而innodb使用的行锁(当然innodb也支持表锁)。表级锁:直接锁定整张表,在锁定期间,其他进程无法对该表进行写操作,如果设置的是写锁,那么其他进程读也不允许,因此myisam支持的并发量低,但myisam不会出现死锁;行级锁:只对指定的行进行锁定,其他进程还是可以对表中的其他行进行操作的。因此行锁能大大的减少数据库操作的冲突,但有时会导致死锁。4、是否支持外键的区别myisam不支持外键,innodb支持外键5、表的具体行数的区别MyISAM:保存有表的总行数,如果select count(*) from table;会直接取出出该值。InnoDB:没有保存表的总行数,如果使用select count(*) from table;就会遍历整个表,消耗相当大,但是在加了wehre条件后,myisam和innodb处理的方式都一样。6、 存储空间上的区别MyISAM:可被压缩,存储空间较小。支持三种不同的存储格式:静态表(默认,但是注意数据末尾不能有空格,会被去掉)、动态表、压缩表。InnoDB:需要更多的内存和存储,它会在主内存中建立其专用的缓冲池用于高速缓冲数据和索引。
2022年06月21日
327 阅读
0 评论
0 点赞
2022-06-21
【PHP】基于thinkphp5的数据库备份与还原扩展
使用composer安装:`composer require tp5er/tp5-databackup dev-master` 引入 `use \tp5er\Backup;` **基本配置信息,默认传入下面参数** $config=array( 'path' => './Data/',//数据库备份路径 'part' => 20971520,//数据库备份卷大小 'compress' => 0,//数据库备份文件是否启用压缩 0不压缩 1 压缩 'level' => 9 //数据库备份文件压缩级别 1普通 4 一般 9最高 ); **实例化** $db= new Backup($config); **数据类表列表** return $this->fetch('index',['list'=>$db->dataList()]); **备份文件列表** return $this->fetch('importlist',['list'=>$db->fileList()]); **备份表** $start= $db->setFile($file)->backup($tables[$id], $start); **导入表** $start= $db->setFile($file)->import($start); **删除备份文件** $db->delFile($time); **修复表** $db->repair($tables) **优化表** $db->optimize($tables)
2022年06月21日
333 阅读
0 评论
0 点赞
2022-06-21
【PHP】使用PHPoffice实现普通的导出功能
> 使用composer安装: composer require phpoffice/phpspreadsheet <?php namespace app\index\controller; use app\index\controller\Comm; use PhpOffice\PhpSpreadsheet\Spreadsheet; use PhpOffice\PhpSpreadsheet\Writer\Xlsx; use think\Exception; use think\Request; class Importsheet extends comm{ /** * @var Excel文件名字 */ private $sheet_filename; /** * @var Excel中的sheet的名字 */ private $sheet_name; /** * @var array 输出Excel的表头 */ private $sheet_firstline = []; /** * @var array 表的内容 */ private $sheet_info = []; /** * Importsheet constructor. * @param $filename 文件名 * @param $name sheet名 * @param $firstline 表头 * @param $info 表内容 */ public function __construct($filename,$name,$firstline = [],$info = []) { parent::__construct(); $this->sheet_filename = $filename; $this->sheet_name = $name; $this->sheet_firstline = $firstline; $this->sheet_info = $info; } /** * @Author: 小破孩嫩 * @Email: 3584685883@qq.com * @Time: 2020/12/23 16:08 * @param int $column_num * @return mixed * @Description:获取表格列数的字母 */ public function getMaxColumn(int $column_num) { try{ if(empty($column_num)){ throw new Exception('column_num:列数为空~'); } if(!is_int($column_num)){ throw new Exception('column_num:参数类型错误~'); } if($column_num > 26*26 || $column_num < 0){ throw new Exception('最大列数:676列,最小列数:1列'); } $column_word = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']; //生成循环次数 $num = ceil($column_num/26); for($c = 0; $c < $num; $c++) { $first_word = $column_word[$c-1]; foreach($column_word as $key => $val){ if($c >= 1){ $word = $first_word.$column_word[$key]; }else{ $word = $column_word[$key]; } $column[] = $word; } } for($a = 0; $a < $column_num; $a++){ $new_column[] = $column[$a]; } return $new_column; }catch (Exception $e){ returnResponse(100,$e->getMessage()); } } /** * @Author: 小破孩嫩 * @Email: 3584685883@qq.com * @Time: 2020/12/23 17:54 * @Description:输出表 */ public function outputSheet() { try{ $spreadsheet = new Spreadsheet(); $sheet = $spreadsheet->getActiveSheet(); //设置sheet的名字 $sheet->setTitle($this->sheet_name); //默认表头第一行 $k = 1; //生成列的个数,根据表头个数来定 $column_num = count($this->sheet_firstline); $info_field_num = count($this->sheet_info[0]); if($column_num != $info_field_num){ throw new Exception('结果集列数和表头列数不一致~'); } //生成表头上方的字母(最大676,最小1) $column_word = $this->getMaxColumn($column_num); //设置表头 for($i=0;$i<$column_num;$i++){ $sheet->setCellValue($column_word[$i].$k, $this->sheet_firstline[$i]); } //第二行开始插入数据 $k = 2; //插入表格数据 foreach ($this->sheet_info as $key => $value) { $b = 0; for($a = 0; $a < $column_num; $a++){ $getvalbykey = array_values($value); $sheet->setCellValue($column_word[$a].$k, $getvalbykey[$b]); $b++; } $k++; } //文件名 $file_name = date('Y-m-d H:i:s', time()).'-'.rand(1000, 9999).'_'. $this->sheet_filename . ".xlsx"; //下载 header('Content-Type: application/vnd.ms-excel'); header('Content-Disposition: attachment;filename="'.$file_name.'"'); header('Cache-Control: max-age=0'); $writer = \PhpOffice\PhpSpreadsheet\IOFactory::createWriter($spreadsheet, 'Xlsx'); $writer->save('php://output'); }catch (Exception $e){ returnResponse(100,$e->getMessage()); } } } 使用方法TP框架为例: $res = Db('company')->field('id,companys,business_remark,img1,img2,img3')->select();//查询的数据 $first_line = ['ID','公司','备注','图片一','图片二','图片三']; $sheet = new Importsheet('下载的excel名','excel里面sheet名','表头','查询的结果集'); $sheet->outputSheet(); > 改变部分地方的语法,可以适用于任意框架; > phpoffice使用介绍:http://www.honeyrh.com/index.php/archives/100/ $writer->save('文件路径');//设置文件保存路径,自己拼接路由地址 如果有更好的解决方法,欢迎留言指导。 补充:导出需要导出图片的处理方法 for($a = 0; $a < $column_num; $a++){ $getvalbykey = array_values($value); /*写入图片*/ $files_arr = explode('.', $getvalbykey[$b]); if(!empty($files_arr)){ $file_suffix = array_pop($files_arr); strtolower($file_suffix); $suffix = ['jpg', 'jpeg', 'gif', 'bmp', 'png','pdf','doc','docx','xlsx','xls']; if(in_array($file_suffix,$suffix)){ $thumb_str = str_replace(request()->domain(),'',$getvalbykey[$b]); $thumb = '/home/wwwroot/crm.sddjieshui.com/public'.$thumb_str; if(file_exists($thumb)){ $drawing = new \PhpOffice\PhpSpreadsheet\Worksheet\Drawing(); $drawing ->setName('图片'); $drawing ->setDescription('图片'); $drawing ->setPath($thumb); $drawing ->setWidth(80); $drawing ->setHeight(80); $drawing ->setCoordinates($column_word[$a].$k); $drawing ->setOffsetX(0); $drawing ->setOffsetY(0); $drawing ->setWorksheet($spreadsheet->getActiveSheet()); } }else{ $sheet->setCellValue($column_word[$a].$k, $getvalbykey[$b]); } $b++; }// $sheet->setCellValue($column_word[$a].$k, $getvalbykey[$b]);// $b++;导出图片替换上面方法,也可以做成开关的形式或者自动选择的形式,根据业务场景来定,后期有时间再重新更新一版可以灵活控制应用的,开箱即用,无需修改,相当nice
2022年06月21日
456 阅读
0 评论
1 点赞
2022-06-21
【PHP】PHP导出Excel所需要的表头上方的字母超过26位的解决方法
/** * @Author: 小破孩嫩 * @Email: 3584685883@qq.com * @Time: 2020/12/23 16:08 * @param int $column_num * @return mixed * @Description:获取表格列数的字母 */ public function getMaxColumn(int $column_num) { try{ if(empty($column_num)){ throw new Exception('column_num:列数为空~'); } if(!is_int($column_num)){ throw new Exception('column_num:参数类型错误~'); } if($column_num > 26*26 || $column_num < 0){ throw new Exception('最大列数:676列,最小列数:1列'); } $column_word = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']; //生成循环次数 $num = ceil($column_num/26); for($c = 0; $c < $num; $c++) { $first_word = $column_word[$c-1]; foreach($column_word as $key => $val){ if($c >= 1){ $word = $first_word.$column_word[$key]; }else{ $word = $column_word[$key]; } $column[] = $word; } } for($a = 0; $a < $column_num; $a++){ $new_column[] = $column[$a]; } return $new_column; }catch (Exception $e){ returnResponse(100,$e->getMessage()); } }
2022年06月21日
315 阅读
0 评论
0 点赞
2022-06-21
【PHP】PHP获取数组中重复value的key值
/** * @Author:小破孩 * @Time: 2020/8/7 17:14 * @param $array * @return array * @Description:获取数组重复value的key值 */ function getKeyByArrayValue($array){ $keyarr= []; $resultkey = []; foreach ($array as $k => $v) { if (in_array($v, $keyarr)) { //在数组中搜索键值$v,并返回它的键名 $resultkey[] = array_search($v,$keyarr); $resultkey[] = $k; }else{ $keyarr[] = $v; } } return $resultkey; }
2022年06月21日
269 阅读
0 评论
0 点赞
2022-06-21
【PHP】PHP实现网页转PDF - MPDF扩展
**PHP版本和扩展** mPDF >=7.0支持PHP^5.6 || ~7.0.0 || ~7.1.0 || ~7.2.0 PHP 7.3支持,因为mPDF v7.1.7 PHP 7.4支持,因为mPDF v8.0.4 PHPmbstring和gd必须加载扩展程序。 > 一些高级功能可能需要额外的扩展,例如zlib对于输出和嵌入式资源(如字体)的压缩,bcmath用于生成条形码或xml用于字符集转换和SVG处理。 **安装** composer require mpdf/mpdf **使用:** /** * @Author:小破孩 * @Time: 2020/8/10 19:04 * @param $url 网页地址 * @param $hetongming pdf存表的原名 * @return mixed|string * @throws \Mpdf\MpdfException * @Description:网页转PDF */ function htmlTopdf($url,$hetongming){ $mpdf = new \Mpdf\Mpdf(['mode'=>'utf-8','format'=>'A4','useSubstitutions'=>true,'useAdobeCJK'=>true,'autoScriptToLang'=>true,'autoLangToFont'=>true,'mgl'=>15,'mgr'=>15,'mgt'=>16,'mgb'=>16,'mgh'=>9,'mgf'=>9, 'orientation'=>'P']); $page = file_get_contents($url); $pwd = 'PDF_TY'.setCode();//修改文档的密码 // $pwds = setPwd($pwd); //查看密码 $mpdf->SetProtection(array(),'',$pwd,128); $mpdf->WriteHTML($page); $pdf_name = setNumber(); $name = "./Uploads/pdf/".$pdf_name.".pdf"; $mpdf->Output( $name ,'F'); $urls = "/Uploads/pdf/".$pdf_name.".pdf"; $pdf_filesize = filesize($name); $img_number = savePdf($hetongming,$pwd,$pdf_filesize,$urls); return $img_number; } 参考资料: > github:https://github.com/mpdf/mpdf > manual:https://mpdf.github.io/
2022年06月21日
293 阅读
0 评论
0 点赞
2022-06-21
【MySQL】配置MySQL主从数据库
MySQL的主从复制是通过binlog日志来实现的,主从复制中的“主”指的是MySQL主服务器上的数据库,“从”指的是MySQL从服务器上的数据库,且这种复制是基于数据库级别的,为此从服务器中的数据库名称必须和主服务器中的数据库名称保持一致,那么,要想实现主从复制,我们至少要有两个MySQL服务器(最好是两个MySQL服务器分别位于不同的主机上,或者在一个主机上安装两个MySQL,端口不同即可)。这里我们只介绍 一主一从 的操作方法。 我的电脑已经安装了 phpStudy 集成环境(同wamp/xampp安装包类似),可以把它里面的MySQL服务作为MySQL的主服务器。那么,我们还需要在这台电脑上再安装一个MySQL,作为数据库的从服务器。 我的电脑phpStudy 中已安装的MySQL版本为 5.6.20,端口为3306。我这里又新建了一个mysql 服务(注意:这个要一个免安装版,而且要比住数据库版本要低才好!) 下载mysql的windows安装包 到mysql的官网:http://dev.mysql.com/downloads/mysql/5.6.html#downloads 进行下载 注意:官网给出的安装包有两种格式(msi格式和 zip格式),如果下载的是msi格式的,则直接双击安装即可,这里我们下载zip格式的。 数据库服务器的参数:主服务器(master): IP为127.0.0.1,端口为3306从服务器(slave): IP为127.0.0.1,端口为3307主服务器配置:修改主服务器的数据库配置文件(E:\xampp\mysql\bin\my.ini),在 [mysqld] 标签的最下面,添加如下代码: 需要备份的数据库 `binlog-do-db=test` 不需要备份的数据库 `binlog-ignore-db=mysql` 开启二进制日志 `log-bin=mysql-bin` 服务器id `server-id=1` 保存退出,重启MySQL主服务器。 binlog-do-db用于指定需要同步的数据库,binlog-ignore-db指定不需要同步的数据库,如果这两个参数都不设置,则从服务器会复制主服务器的所有数据库。一般不用root账号作同步账号,为此,我们需要在主服务器上创建一个新的用户(如 user01,密码为123456)。 这里我们用命令行的方式创建,方法如下:打开cmd,切换至 E:\xampp\mysql\bin,用 root 账户连接MySQL主服务器: `mysql -uroot -p -P3306 ` 创建新用户: `create user ‘user01’@’127.0.0.1’ identified by ‘123456’; ` (@后面的ip地址为允许连接的客户端的ip地址。) 然后,给新用户配置主从复制的权限: `grant replication slave on . to ‘user01’@’127.0.0.1’ identified by ‘123456’; ` (@后面的ip地址为允许连接的客户端的ip地址,如果改为 ‘%’,就表示客户端没有ip地址的限制)如果主服务器的数据库(test)中,已经有数据,我们需要先手动把主服务器中的数据复制到从服务器。方法如下: 在本案例中,我们只备份一个数据库(test),test中有一个表basic_user,表中也已经有了数据。为了防止我们复制数据的时候,数据库test中的数据发生更新,我们需要先锁定数据库,命令如下: `flush tables with read lock; ` 这个命令是全局读锁定,它会给主服务器中的所有数据库都加上读锁,这里顺便说一下读锁和写锁的区别:read lock(读锁):也叫共享锁,允许所有的读操作,但阻塞写操作,即所有连接只可以读数据,但不允许写数据。write lock(写锁):也叫排它锁、独占锁,只允许当前连接的读和写,不允许其他并发的读操作和写操作。锁定主服务器的数据库后,我们在从服务器中,也创建一个数据库test,并将所有的表(包括表结构和表数据)都导入。 然后,我们执行下面的命令,解锁:unlock tables; 查看主服务器的 master 状态: mysql> show master status; +——————+———-+————–+——————+——————-+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | +——————+———-+————–+——————+——————-+ | mysql-bin.000008 | 498 | test | mysql | | +——————+———-+————–+——————+——————-+从服务器配置:修改从服务器的数据库配置文件(E:\mysql\my.ini),在 [mysqld] 标签的最下面,添加如下代码: 端口 port = 3307 服务器id server_id = 2 开启二进制日志(从服务器不是必须要开启二进制日志) log-bin=mysql-bin 保存退出,重启MySQL服务。 连接MySQL从服务器: mysql -uroot -p -P3307 配置复制的参数: change master to master_host='127.0.0.1',master_user='root',master_password='root',master_log_file='binlog.000009',master_log_pos=154;参数详解:master_host: 主服务器的IP master_user: 主服务器上新创建的用户名 master_password:用户的密码 master_port: 主服务器的端口,如果未曾修改,默认即可。 master_log_file:主服务器二进制日志文件的名称,填写查看主服务器的master状态时显示的File的值 master_log_pos:日志的位置,填写查看主服务器的master状态时显示的Position的值启动从服务器的slave复制功能:start slave; 查看从服务器的slave状态: mysql> show slave status \G ***************** 1. row ***************** Slave_IO_State: Waiting for master to send event Master_Host: 127.0.0.1 Master_User: user01 Master_Port: 3306 Connect_Retry: 60 Master_Log_File: mysql-bin.000009 Read_Master_Log_Pos: 120 Relay_Log_File: hp-PC-relay-bin.000004 Relay_Log_Pos: 283 Relay_Master_Log_File: mysql-bin.000009 Slave_IO_Running: Yes Slave_SQL_Running: Yes如果 Slave_IO_Running 和 Slave_SQL_Running 的值都为 Yes,则说明主从复制的所有配置已成功,即从服务器已经可以自动与主服务器的数据库数据实现同步了。此后,只要主服务器的数据有更新(比如:在 test数据库中新建了一张表或者表中的数据发生了变化),从服务器都会自动与主服务器保持一致。但如果有人刻意改变了从服务器的数据,主服务器中的数据并不会同步更新,除非我们把这两个MySQL服务器设置为互为主从。
2022年06月21日
332 阅读
0 评论
1 点赞
2022-06-21
【PHP】PHP生成随机 数,字符串
/** * @Author:小破孩 * @Time: 2020/7/15 17:39 * @param string $length 默认10 * @return string * @Description:生成数字和字母混合的邀请码 */ function setCode($length='10'){ $key=''; $pattern = ['1','2','3','4','5','6','7','8','9','0','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z']; for($i=0;$i<$length;$i++) { $key .= $pattern[mt_rand(0,35)]; //生成php随机数 } return $key; } // 生成随机字符串 private function randomString($len = 32) { $string = ''; $char = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'; for ($i = 0; $i < $len; $i++) { $string .= $char[mt_rand(0, strlen($char) - 1)]; } return $string; } const MINIWORD = ['a','b','c','d','e','f','g','h','k','m','n','p','q','r','t','w','x','y','z'];//'l',,'i','j','s','o','u','v' const NUMS = ['2', '3', '5', '6', '7', '8', '9'];//'4', '1','0', /** * Author: 小破孩 * Email: 3584685883@qq.com * Time: 2021/12/29 10:26 * @param int $length * @return string * Description:核销码 */ public function setVerificationCode(int $length = 4):string { $dictionary =array_merge(self::MINIWORD,self::NUMS); shuffle($dictionary); $codeArrKey = array_rand($dictionary,$length); $code = ''; for($i = 0; $i < count($codeArrKey); $i++){ $code .= $dictionary[$i]; } return $code; } /** * Author: 小破孩 * Email: 3584685883@qq.com * Time: 2021/12/29 10:16 * @param int $length default 6 * @return int * Description:设置验证码 */ public function setSmsCode(int $length = 6):int { if($length == 6){ return mt_rand(100000,999999); } return mt_rand(1000,9999); }
2022年06月21日
251 阅读
0 评论
0 点赞
2022-06-21
【PHP】扩展 qrcode 二维码生成
**一、执行命令安装** composer require dh2y/think-qrcode **二、require安装** thinkphp5.0 安装 "require": { "dh2y/think-qrcode":"1.*" }, thinkphp5.1 安装 "require": { "dh2y/think-qrcode":"2.*" }, **三、autoload psr-4标准安装** a) 进入vendor/dh2y目录 (没有dh2y目录 mkdir dh2y) b) git clone c) 修改 git clone下来的项目名称为think-qrcode d) 添加下面配置 "autoload": { "psr-4": { "dh2y\\qrcode\\": "vendor/dh2y/think-qrcode/src" } }, e) php composer.phar update **添加配置文件** return [ 'cache_dir' => 'uploads'.DS.'qrcode', //缓存地址 'background'=> 'static/image/icon_cover.png' //背景图 ]; **使用方法** $code = new QRcode(); $code_path = $code->png($register_url) //生成二维码 ->logo('static/image/avatar-m.jpg') //生成logo二维码 ->background(180,500) //给二维码加上背景 ->text($role,20,['center',740],'#ff4351') //添加文字水印 ->text($nick_name,20,['center',780],'#000000') ->getPath(); //获取二维码生成的地址
2022年06月21日
247 阅读
0 评论
0 点赞
2022-06-21
【PHP】PHPMailer发送邮件
/** * @Author:小破孩 * @Time: 2020/7/10 13:13 * @param $title 邮件标题 * @param $content 内容 * @param $toemail 收件人邮箱 * @Description:发送邮件 */ function sendEmail($title, $content, $toemail, $usernumber, $type){ try{ $mail = new \PHPMailer\PHPMailer\PHPMailer(); $mail->isSMTP();// 使用SMTP服务 $mail->CharSet = "utf8";// 编码格式为utf8,不设置编码的话,中文会出现乱码 $mail->Host = "smtp.163.com";// 发送方的SMTP服务器地址 $mail->SMTPAuth = true;// 是否使用身份验证 $mail->Username = Config('app.email_name');// 发送方的163邮箱用户名,就是你申请163的SMTP服务使用的163邮箱 $mail->Password = Config('app.email_allow');// 发送方的邮箱密码,注意用163邮箱这里填写的是“客户端授权密码”而不是邮箱的登录密码! $mail->SMTPSecure = "ssl";// 使用ssl协议方式 $mail->Port = config('app.email_port');// 163邮箱的ssl协议方式端口号是465/994 $mail->setFrom(config('app.email_address'),config('app.email_sendpeopleinfo'));// 设置发件人信息,如邮件格式说明中的发件人,这里会显示为Mailer(xxxx@163.com),Mailer是当做名字显示 $mail->addAddress($toemail,'小破孩回复消息');// 设置收件人信息,如邮件格式说明中的收件人,这里会显示为Liang(yyyy@163.com) $mail->addReplyTo(config('app.email_receive'),'小破孩');// 设置回复人信息,指的是收件人收到邮件后,如果要回复,回复邮件将发送到的邮箱地址 $mail->Subject = $title;// 邮件标题 $mail->Body = $content/*."点击可以查看文章地址:".$desc_url*/;// 邮件正文 if(!$mail->send()){// 发送邮件 returnResponse(100,$mail->ErrorInfo);// 输出错误信息 echo "Mailer Error: ".$mail->ErrorInfo; } //信息入库 $data['e_user_number'] = $usernumber; $data['e_title'] = $title; $data['e_content'] = $content; $data['e_emali_receive'] = $toemail; $data['e_type'] = $type; $res = Db::name('email')->insert($data); if($res){ return $res; } }catch (\Exception $e){ returnResponse(100,$e->getMessage()); } }
2022年06月21日
271 阅读
0 评论
0 点赞
2022-06-21
【MySQL】MySQL触发器应用场景和使用方法
触发器是一种特殊的存储过程,它在插入,删除或改动特定表中的数据时触发运行,它比数据库本身标准的功能有更精细和更复杂的数据控制能力。数据库触发器有下面的作用:1.安全性。能够基于数据库的值使用户具有操作数据库的某种权利。# 能够基于时间限制用户的操作,比如不同意下班后和节假日改动数据库数据。# 能够基于数据库中的数据限制用户的操作,比如不同意股票的价格的升幅一次超过10%。2.审计。能够跟踪用户对数据库的操作。 # 审计用户操作数据库的语句。# 把用户对数据库的更新写入审计表。3.实现复杂的数据完整性规则# 实现非标准的数据完整性检查和约束。触发器可产生比规则更为复杂的限制。与规则不同,触发器能够引用列或数据库对象。比如,触发器可回退不论什么企图吃进超过自己保证金的期货。# 提供可变的缺省值。4.实现复杂的非标准的数据库相关完整性规则。触发器能够对数据库中相关的表进行连环更新。比如,在auths表author_code列上的删除触发器可导致对应删除在其他表中的与之匹配的行。# 在改动或删除时级联改动或删除其他表中的与之匹配的行。# 在改动或删除时把其他表中的与之匹配的行设成NULL值。# 在改动或删除时把其他表中的与之匹配的行级联设成缺省值。# 触发器可以拒绝或回退那些破坏相关完整性的变化,取消试图进行数据更新的事务。当插入一个与其主健不匹配的外部键时,这样的触发器会起作用。比如,可以在books.author_code 列上生成一个插入触发器,假设新值与auths.author_code列中的某值不匹配时,插入被回退。5.同步实时地复制表中的数据。6.自己主动计算数据值,假设数据的值达到了一定的要求,则进行特定的处理。比如,假设公司的帐号上的资金低于5万元则马上给財务人员发送警告数据。mysql创建触发器1、老版本mysql语法:CREATE TRIGGER <触发器名称> --触发器必须有名字,最多64个字符,可能后面会附有分隔符.它和MySQL中其他对象的命名方式基本相象.{ BEFORE | AFTER } --触发器有执行的时间设置:可以设置为事件发生前或后。{ INSERT | UPDATE | DELETE } --同样也能设定触发的事件:它们可以在执行insert、update或delete的过程中触发。ON <表名称> --触发器是属于某一个表的:当在这个表上执行插入、 更新或删除操作的时候就导致触发器的激活. 我们不能给同一张表的同一个事件安排两个触发器。FOR EACH ROW --触发器的执行间隔:FOR EACH ROW子句通知触发器 每隔一行执行一次动作,而不是对整个表执行一次。<触发器SQL语句> --触发器包含所要触发的SQL语句:这里的语句可以是任何合法的语句, 包括复合语句,但是这里的语句受的限制和函数的一样。2、新版本mysql语法: CREATE [DEFINER = { user | CURRENT_USER }] TRIGGER trigger_name trigger_time trigger_event ON tbl_name FOR EACH ROW [trigger_order] trigger_body trigger_time: { BEFORE | AFTER } trigger_event: { INSERT | UPDATE | DELETE } trigger_order: { FOLLOWS | PRECEDES } other_trigger_name注意:或许你必须拥有相当大的权限才能创建触发器(CREATE TRIGGER),如果你已经是Root用户,那么就足够了。这跟SQL的标准有所不同。mysql5.7新版本语法发生了一些小小的变化,同时也可以自定义用户,语法相对来说简单了很多,原理和老版本还是一样的;准备工作:1、创建表tab1sql命令: DROP TABLE IF EXISTS tab1; CREATE TABLE tab1( tab1_id varchar(11) );2、创建表tab2sql命令: DROP TABLE IF EXISTS tab2; CREATE TABLE tab2( tab2_id varchar(11) );实例1:1、创建触发器:t_afterinsert_on_tab1作用:增加tab1表记录后自动将记录增加到tab2表中老版本sql命令: DROP TRIGGER IF EXISTS t_afterinsert_on_tab1; CREATE TRIGGER t_afterinsert_on_tab1 AFTER INSERT ON tab1 FOR EACH ROW BEGIN insert into tab2(tab2_id) values(new.tab1_id); END;新版本sql命令: DROP TRIGGER IF EXISTS t_afterinsert_on_tab1; CREATE TRIGGER t_afterinsert_on_tab1 AFTER INSERT ON tab1 FOR EACH ROW insert into tab2(tab2_id) values(new.tab1_id);2、向tab1表插入一条数据做测试;sql命令: INSERT INTO tab1(tab1_id) values('0001'); 3、查看tab1表和tab2表的结果;sql命令: SELECT * FROM tab1; SELECT * FROM tab2;实例2:1、创建触发器:t_afterdelete_on_tab1作用:删除tab1表记录后自动将tab2表中对应的记录删去老版本sql命令: DROP TRIGGER IF EXISTS t_afterdelete_on_tab1; CREATE TRIGGER t_afterdelete_on_tab1 AFTER DELETE ON tab1 FOR EACH ROW BEGIN delete from tab2 where tab2_id=old.tab1_id; END;新版本sql命令: DROP TRIGGER IF EXISTS t_afterdelete_on_tab1; CREATE TRIGGER t_afterdelete_on_tab1 AFTER DELETE ON tab1 FOR EACH ROW delete from tab2 where tab2_id=old.tab1_id;2、删除tab1表一条数据sql命令: `DELETE FROM tab1 WHERE tab1_id='0001';` 3、查看tab1表和tab2表的结果sql命令: SELECT * FROM tab1; SELECT * FROM tab2;三、mysql查看触发器和查看数据库(show databases;)查看表格(show tables;)一样,查看触发器的语法如下: `SHOW TRIGGERS [FROM schema_name];` 其中,schema_name 即 Schema 的名称,在 MySQL 中 Schema 和 Database 是一样的,也就是说,可以指定数据库名,这样就不必先“USE database_name;”了。 实例:1、查看tab1表下面所有的触发器:sql命令: `SHOW TRIGGERS` 2、查看test数据库下面的触发器,tabl表属于test数据库:sql命令: `SHOW TRIGGERS FROM test` 四、mysql删除触发器和删除数据库、删除表格一样,删除触发器的语法如下: `DROP TRIGGER [IF EXISTS] [schema_name.]trigger_name` 实例:1、删除触发器‘t_afterdelete_on_tab1’sql命令: `DROP TRIGGER IF EXISTS t_afterdelete_on_tab1` 参考:付杰博客 https://www.fujieace.com/mysql/trigger.html
2022年06月21日
1,297 阅读
1 评论
1 点赞
2022-06-21
【MySQL】MySQL 事务
MySQL 事务MySQL事务主要用于处理操作量大,复杂度高的数据。比如说,在人员管理系统中,你删除一个人员,你既需要删除人员的基本资料,也要删除和该人员相关的信息,如信箱,文章等等,这样,这些数据库操作语句就构成一个事务!在 MySQL 中只有使用了 Innodb 数据库引擎的数据库或表才支持事务。事务处理可以用来维护数据库的完整性,保证成批的 SQL 语句要么全部执行,要么全部不执行。事务用来管理 insert,update,delete 语句一般来说,事务是必须满足4个条件(ACID)::原子性(Atomicity,或称不可分割性)、一致性(Consistency)、隔离性(Isolation,又称独立性)、持久性(Durability)。原子性:一个事务(transaction)中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。一致性:在事务开始之前和事务结束以后,数据库的完整性没有被破坏。这表示写入的资料必须完全符合所有的预设规则,这包含资料的精确度、串联性以及后续数据库可以自发性地完成预定的工作。隔离性:数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。事务隔离分为不同级别,包括读未提交(Read uncommitted)、读提交(read committed)、可重复读(repeatable read)和串行化(Serializable)。持久性:事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。在 MySQL 命令行的默认设置下,事务都是自动提交的,即执行 SQL 语句后就会马上执行 COMMIT操作。因此要显式地开启一个事务务须使用命令 BEGIN 或 START TRANSACTION,或者执行命令 SET AUTOCOMMIT=0,用来禁止使用当前会话的自动提交。事务控制语句:BEGIN 或 START TRANSACTION 显式地开启一个事务;COMMIT 也可以使用 COMMIT WORK,不过二者是等价的。COMMIT 会提交事务,并使已对数据库进行的所有修改成为永久性的;ROLLBACK 也可以使用 ROLLBACK WORK,不过二者是等价的。回滚会结束用户的事务,并撤销正在进行的所有未提交的修改;SAVEPOINT identifier,SAVEPOINT 允许在事务中创建一个保存点,一个事务中可以有多个 SAVEPOINT;RELEASE SAVEPOINT identifier 删除一个事务的保存点,当没有指定的保存点时,执行该语句会抛出一个异常;ROLLBACK TO identifier 把事务回滚到标记点;SET TRANSACTION 用来设置事务的隔离级别。InnoDB 存储引擎提供事务的隔离级别有READ UNCOMMITTED、READ COMMITTED、REPEATABLE READ 和 SERIALIZABLE。MYSQL 事务处理主要有两种方法:1、用 BEGIN, ROLLBACK, COMMIT来实现BEGIN 开始一个事务ROLLBACK 事务回滚COMMIT 事务确认2、直接用 SET 来改变 MySQL 的自动提交模式:SET AUTOCOMMIT=0 禁止自动提交SET AUTOCOMMIT=1 开启自动提交事务测试mysql> use RUNOOB; Database changed mysql> CREATE TABLE runoob_transaction_test( id int(5)) engine=innodb; # 创建数据表 Query OK, 0 rows affected (0.04 sec) mysql> select * from runoob_transaction_test; Empty set (0.01 sec) mysql> begin; # 开始事务 Query OK, 0 rows affected (0.00 sec) mysql> insert into runoob_transaction_test value(5); Query OK, 1 rows affected (0.01 sec) mysql> insert into runoob_transaction_test value(6); Query OK, 1 rows affected (0.00 sec) mysql> commit; # 提交事务 Query OK, 0 rows affected (0.01 sec) mysql> select * from runoob_transaction_test; +------+ | id | +------+ | 5 | | 6 | +------+ 2 rows in set (0.01 sec) mysql> begin; # 开始事务 Query OK, 0 rows affected (0.00 sec) mysql> insert into runoob_transaction_test values(7); Query OK, 1 rows affected (0.00 sec) mysql> rollback; # 回滚 Query OK, 0 rows affected (0.00 sec) mysql> select * from runoob_transaction_test; # 因为回滚所以数据没有插入 +------+ | id | +------+ | 5 | | 6 | +------+ 2 rows in set (0.01 sec) mysql>PHP中使用事务实例MySQL ORDER BY 测试:<?php $dbhost = 'localhost'; // mysql服务器主机地址 $dbuser = 'root'; // mysql用户名 $dbpass = '123456'; // mysql用户名密码 $conn = mysqli_connect($dbhost, $dbuser, $dbpass); if(! $conn ) { die('连接失败: ' . mysqli_error($conn)); } // 设置编码,防止中文乱码 mysqli_query($conn, "set names utf8"); mysqli_select_db( $conn, 'RUNOOB' ); mysqli_query($conn, "SET AUTOCOMMIT=0"); // 设置为不自动提交,因为MYSQL默认立即执行 mysqli_begin_transaction($conn); // 开始事务定义 if(!mysqli_query($conn, "insert into runoob_transaction_test (id) values(8)")) { mysqli_query($conn, "ROLLBACK"); // 判断当执行失败时回滚 } if(!mysqli_query($conn, "insert into runoob_transaction_test (id) values(9)")) { mysqli_query($conn, "ROLLBACK"); // 判断执行失败时回滚 } mysqli_commit($conn); //执行事务 mysqli_close($conn); ?>
2022年06月21日
277 阅读
0 评论
0 点赞
2022-06-21
【PHP】PHPoffice/PHPSpreadsheet读取和写入Excel
安装现在开始,创建项目目录/PHPExcel,进入项目目录。使用composer安装:composer require phpoffice/phpspreadsheet使用在项目目录下新建/public目录,在public目录下创建示例文件test.php,编辑test.php,用以下代码。<?php require '../vendor/autoload.php'; use PhpOffice\PhpSpreadsheet\Spreadsheet; use PhpOffice\PhpSpreadsheet\Writer\Xlsx; $spreadsheet = new Spreadsheet(); $sheet = $spreadsheet->getActiveSheet(); $sheet->setCellValue('A1', 'Welcome to Helloweba.'); $writer = new Xlsx($spreadsheet); $writer->save('hello.xlsx');运行代码,你会发现在目录下生成一个hello.xlsx文件,打开Excel文件,你会看到Excel中的单元格A1中有“Welcome to Helloweba.”内容。当然你可以对单元格样式诸如颜色、背景、宽度、字体等等进行设置,这些会在接下来的几节中讲到。PhpSpreadsheet特性支持读取.xls,.xlsx,.html,.csv等格式文件支持,写入导出.xls,.xlsx,.html,.csv,.pdf格式文件。提供丰富的API,提供单元格样式设置、Excel表格属性设置、图表设置等等诸多功能。使用PhpSpreadsheet完全可以生成一个外观结构都满足你的Excel表格文件。卓越的性能,尤其在PHP7上表现优异,比PHPExcel强大很多。2. 使用PhpSpreadsheet将Excel导入到MySQL数据库导入Excel思路:使用PhpSpreadsheet读取Excel表格中的有用信息,然后组装成sql语句,最后批量插入到MySQL表中。require_once 'vendor/autoload.php'; include('conn.php'); //连接数据库 $reader = \PhpOffice\PhpSpreadsheet\IOFactory::createReader('Xlsx'); $reader->setReadDataOnly(TRUE); $spreadsheet = $reader->load('students.xlsx'); //载入excel表格 $worksheet = $spreadsheet->getActiveSheet(); $highestRow = $worksheet->getHighestRow(); // 总行数 $highestColumn = $worksheet->getHighestColumn(); // 总列数 $highestColumnIndex = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::columnIndexFromString($highestColumn); // e.g. 5 $lines = $highestRow - 2; if ($lines <= 0) { exit('Excel表格中没有数据'); } $sql = "INSERT INTO `t_student` (`name`, `chinese`, `maths`, `english`) VALUES "; for ($row = 3; $row <= $highestRow; ++$row) { $name = $worksheet->getCellByColumnAndRow(1, $row)->getValue(); //姓名 $chinese = $worksheet->getCellByColumnAndRow(2, $row)->getValue(); //语文 $maths = $worksheet->getCellByColumnAndRow(3, $row)->getValue(); //数学 $english = $worksheet->getCellByColumnAndRow(4, $row)->getValue(); //外语 $sql .= "('$name','$chinese','$maths','$english'),"; } $sql = rtrim($sql, ","); //去掉最后一个,号 try { $db->query($sql); echo 'OK'; } catch (Exception $e) { echo $e->getMessage(); }$worksheet->getCellByColumnAndRow(col,row)->getValue(); //可以获取表格中任意单元格数据内容. col表示单元格所在的列,以数字表示,A列表示第一列,row表示所在的行。3. 使用PhpSpreadsheet将数据导出为Excel文件一、设置表头首先我们引入自动加载PhpSpreadsheet库,然后实例化,设置工作表标题名称为:学生成绩表,接着设置表头内容。表头分为两行,第一行是表格的名称,第二行数表格列名称。最后我们将第一行单元格进行合并,并设置表头内容样式:字体、对齐方式等。require 'vendor/autoload.php'; use PhpOffice\PhpSpreadsheet\Spreadsheet; use PhpOffice\PhpSpreadsheet\Writer\Xlsx; include('conn.php'); //连接数据库 $spreadsheet = new Spreadsheet(); $worksheet = $spreadsheet->getActiveSheet(); //设置工作表标题名称 $worksheet->setTitle('学生成绩表'); //表头 //设置单元格内容 $worksheet->setCellValueByColumnAndRow(1, 1, '学生成绩表'); $worksheet->setCellValueByColumnAndRow(1, 2, '姓名'); $worksheet->setCellValueByColumnAndRow(2, 2, '语文'); $worksheet->setCellValueByColumnAndRow(3, 2, '数学'); $worksheet->setCellValueByColumnAndRow(4, 2, '外语'); $worksheet->setCellValueByColumnAndRow(5, 2, '总分'); //合并单元格 $worksheet->mergeCells('A1:E1'); $styleArray = [ 'font' => [ 'bold' => true ], 'alignment' => [ 'horizontal' => \PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER, ], ]; //设置单元格样式 $worksheet->getStyle('A1')->applyFromArray($styleArray)->getFont()->setSize(28); $worksheet->getStyle('A2:E2')->applyFromArray($styleArray)->getFont()->setSize(14);二、读取数据我们连接数据库后,直接读取学生成绩表t_student,然后for循环,设置每个单元格对应的内容,计算总成绩。注意的是表格中的数据是从第3行开始,因为第1,2行是表头占用了。然后,我们设置整个表格样式,给表格加上边框,并且居中对齐。$sql = "SELECT id,name,chinese,maths,english FROM `t_student`"; $stmt = $db->query($sql); $rows = $stmt->fetchAll(PDO::FETCH_ASSOC); $len = count($rows); $j = 0; for ($i=0; $i < $len; $i++) { $j = $i + 3; //从表格第3行开始 $worksheet->setCellValueByColumnAndRow(1, $j, $rows[$i]['name']); $worksheet->setCellValueByColumnAndRow(2, $j, $rows[$i]['chinese']); $worksheet->setCellValueByColumnAndRow(3, $j, $rows[$i]['maths']); $worksheet->setCellValueByColumnAndRow(4, $j, $rows[$i]['english']); $worksheet->setCellValueByColumnAndRow(5, $j, $rows[$i]['chinese'] + $rows[$i]['maths'] + $rows[$i]['english']); } $styleArrayBody = [ 'borders' => [ 'allBorders' => [ 'borderStyle' => \PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THIN, 'color' => ['argb' => '666666'], ], ], 'alignment' => [ 'horizontal' => \PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER, ], ]; $total_rows = $len + 2; //添加所有边框/居中 $worksheet->getStyle('A1:E'.$total_rows)->applyFromArray($styleArrayBody);三、下载保存强制浏览器下载数据并保存为Excel文件。$filename = '成绩表.xlsx'; header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'); header('Content-Disposition: attachment;filename="'.$filename.'"'); header('Cache-Control: max-age=0'); $writer = \PhpOffice\PhpSpreadsheet\IOFactory::createWriter($spreadsheet, 'Xlsx'); $writer->save('php://output');如想要保存为.xls文件格式的话,可以改下header代码:$filename = '成绩表.xls'; header('Content-Type: application/vnd.ms-excel'); header('Content-Disposition: attachment;filename="'.$filename.'"'); header('Cache-Control: max-age=0'); $writer = \PhpOffice\PhpSpreadsheet\IOFactory::createWriter($spreadsheet, 'Xls'); $writer->save('php://output');4. 详解PhpSpreadsheet设置单元格PhpSpreadsheet提供了丰富的API接口,可以设置诸多单元格以及文档属性,包括样式、图片、日期、函数等等诸多应用,总之你想要什么样的Excel表格,PhpSpreadsheet都能做到。引入了正确的文件并实例化use PhpOffice\PhpSpreadsheet\Spreadsheet; $spreadsheet = new Spreadsheet(); $worksheet = $spreadsheet->getActiveSheet();字体//第1行代码将A7至B7两单元格设置为粗体字,Arial字体,10号字 $spreadsheet->getActiveSheet()->getStyle('A7:B7')->getFont()->setBold(true)->setName('Arial')->setSize(10); //第2行代码将B1单元格设置为粗体字 $spreadsheet->getActiveSheet()->getStyle('B1')->getFont()->setBold(true);颜色//将文字颜色设置为红色 $spreadsheet->getActiveSheet()->getStyle('A4')->getFont()->getColor()->setARGB(\PhpOffice\PhpSpreadsheet\Style\Color::COLOR_RED);图片//可以将图片加载到Excel中 $drawing = new \PhpOffice\PhpSpreadsheet\Worksheet\Drawing(); $drawing->setName('Logo'); $drawing->setDescription('Logo'); $drawing->setPath('./images/officelogo.jpg'); $drawing->setHeight(36);列宽//将A列宽度设置为30(字符) $spreadsheet->getActiveSheet()->getColumnDimension('A')->setWidth(30); //如果需要自动计算列宽,可以这样: $spreadsheet->getActiveSheet()->getColumnDimension('B')->setAutoSize(true); //设置默认列宽为12 $spreadsheet->getActiveSheet()->getDefaultColumnDimension()->setWidth(12);行高//设置第10行行高为100pt $spreadsheet->getActiveSheet()->getRowDimension('10')->setRowHeight(100); //设置默认行高 $spreadsheet->getActiveSheet()->getDefaultRowDimension()->setRowHeight(15);对齐//将A1单元格设置为水平居中对齐 $styleArray = [ 'alignment' => [ 'horizontal' => \PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER, ], ]; $worksheet->getStyle('A1')->applyFromArray($styleArray);合并//将A18到E22合并为一个单元格 $spreadsheet->getActiveSheet()->mergeCells('A18:E22');拆分//将合并后的单元格拆分 $spreadsheet->getActiveSheet()->unmergeCells('A18:E22');边框//将B2至G8的区域添加红色边框 $styleArray = [ 'borders' => [ 'outline' => [ 'borderStyle' => \PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THICK, 'color' => ['argb' => 'FFFF0000'], ], ], ]; $worksheet->getStyle('B2:G8')->applyFromArray($styleArray);工作表标题//设置当前工作表标题 $spreadsheet->getActiveSheet()->setTitle('Hello');日期时间//设置日期格式 $spreadsheet->getActiveSheet() ->setCellValue('D1', '2018-06-15'); $spreadsheet->getActiveSheet()->getStyle('D1') ->getNumberFormat() ->setFormatCode(\PhpOffice\PhpSpreadsheet\Style\NumberFormat::FORMAT_DATE_YYYYMMDD2);换行//使用\n进行单元格内换行,相当于(ALT+"Enter") $spreadsheet->getActiveSheet()->getCell('A4')->setValue("hello\nworld"); $spreadsheet->getActiveSheet()->getStyle('A4')->getAlignment()->setWrapText(true);超链接//将单元格设置为超链接形式 $spreadsheet->getActiveSheet()->setCellValue('E6', 'www.helloweba.net'); $spreadsheet->getActiveSheet()->getCell('E6')->getHyperlink()->setUrl('https://www.helloweba.net');使用函数//使用SUM计算B5到C5之间单元格的总和。其他函数同理:最大数(MAX),最小数(MIN),平均值(AVERAGE) $spreadsheet->getActiveSheet() ->setCellValue('B7', '=SUM(B5:C5)');设置文档属性//可以设置Excel文档属性 $spreadsheet->getProperties() ->setCreator("Helloweba") //作者 ->setLastModifiedBy("Yuegg") //最后修改者 ->setTitle("Office 2007 XLSX Test Document") //标题 ->setSubject("Office 2007 XLSX Test Document") //副标题 ->setDescription("Test document for Office 2007 XLSX, generated using PHP classes.") //描述 ->setKeywords("office 2007 openxml php") //关键字 ->setCategory("Test result file"); //分类此外,除了提供丰富的Excel文件处理接口外,PhpSpreadsheet还提供了CSV,PDF,HTML以及XML等文件处理接口。
2022年06月21日
1,786 阅读
0 评论
1 点赞
2022-06-21
【Git】Git 文件删除、恢复及高频面试考点整理
Git 文件删除、恢复及高频面试考点整理本文聚焦 Git 中文件删除、恢复的核心命令,明确不同场景下的用法差异,并提炼面试高频考点,便于理解和记忆。一、Git 删除文件:3种核心场景1. 彻底删除(工作区+暂存区+仓库)适用场景:需要从 Git 版本控制中永久移除文件(本地和仓库都不再保留)。 步骤:# 1. 从工作区(本地物理文件)和暂存区同时删除文件 git rm <文件名> # 例:git rm test.log # 2. 提交删除操作到仓库,完成版本记录更新 git commit -m "删除无用文件 test.log"关键:git rm 会同时记录“删除动作”,提交后仓库中该文件的历史记录仍存在,但最新版本中已移除。2. 仅从暂存区删除(本地保留文件)适用场景:不小心将不需要跟踪的文件(如日志、缓存、IDE 配置)添加到暂存区(git add 后),想取消跟踪但本地保留文件。 命令:git rm --cached <文件名> # 例:git rm --cached .idea/关键:本地工作区的文件不会被删除,仅从 Git 暂存区和跟踪列表中移除;后续需在 .gitignore 中添加该文件/目录,避免再次被 git add 跟踪。3. 本地物理删除(不影响 Git 跟踪)命令:直接用系统命令删除本地文件(如 Linux rm <文件>、Windows del <文件>)。 区别:仅删除本地物理文件,未将“删除动作”告知 Git(暂存区和仓库仍记录该文件);需后续执行 git rm <文件> + git commit,才能将删除动作同步到仓库。二、误删文件恢复:工作区文件误删补救适用场景本地工作区不小心删除了已被 Git 跟踪的文件(即该文件之前已提交到仓库/暂存区),想恢复文件。命令(2种方式)# 方式1:Git 老版本兼容(经典写法) git checkout -- <文件名> # 例:git checkout -- app/Controller/Test.php # 方式2:Git 2.23+ 推荐(语义更清晰) git restore <文件名>关键注意事项:仅能恢复“已被 Git 跟踪”的文件(未 git add 过的未跟踪文件,误删后无法通过 Git 恢复);命令会用暂存区/仓库中的最新版本覆盖工作区,未提交的改动会丢失。三、核心命令对比(面试高频)1. git rm vs rm(删除文件)命令作用范围是否记录 Git 操作适用场景git rm工作区 + 暂存区(可选 --cached 仅暂存区)是(记录删除动作)需同步删除动作到仓库rm(系统)仅本地工作区(物理文件)否(无 Git 记录)仅临时删除本地文件,不影响 Git2. git add vs git rm(记录操作)命令能记录的动作不能记录的动作git add文件新增、文件修改文件删除(需 git rm)git rm文件删除文件新增、修改(需 git add)四、补充实用命令:git commit --amend(重写最近提交)作用修改最近一次的 commit message(提交说明),或补充少量未提交的文件到最近一次提交(避免多一条冗余提交)。用法# 1. 仅修改最近一次的 commit message git commit --amend # 执行后进入编辑器,修改后保存退出 # 2. 补充文件到最近一次提交(先 add 未提交的文件) git add 遗漏的文件.txt git commit --amend # 保持原 message 或修改后提交面试注意事项:仅适用于本地未推送(push) 的提交(已推送到远程仓库的提交,禁止使用 --amend,会修改 Git 历史,导致协作冲突)。五、面试高频考点提炼(必背)Q:git rm <文件> 和 rm <文件> 的核心区别是什么? A:git rm 会同时删除工作区+暂存区文件,并记录删除动作,需 commit 同步到仓库;rm 仅删除本地物理文件,不记录 Git 操作,仓库仍保留该文件。Q:如何仅从 Git 跟踪中移除文件,本地工作区保留该文件? A:使用 git rm --cached <文件>,后续需在 .gitignore 中添加该文件,避免再次被跟踪。Q:工作区不小心误删了已跟踪的文件,如何恢复? A:用 git checkout -- <文件> 或 Git 2.23+ 的 git restore <文件>,用暂存区/仓库的最新版本覆盖工作区。Q:git commit --amend 的作用和使用限制是什么? A:作用是重写最近一次的 commit message 或补充文件到最近一次提交;限制是仅能用于本地未推送的提交,已推送的提交不可用(会修改历史)。Q:git add 能记录文件删除的动作吗? A:不能。git add 仅记录文件新增和修改,文件删除需通过 git rm 记录。
2022年06月21日
328 阅读
0 评论
0 点赞
2022-06-21
【PHP】生成avatar头像
/** * @Author: 小破孩嫩 * @Email: 3584685883@qq.com * @Time: 2020/12/10 20:00 * @param string $email 邮箱 * @param int $s 大小 * @param string $d * @param string $g * @return string * @Description:生成avatar头像 */ function getAvatar($email='', $s=40, $d='mm', $g='g') { $hash = md5($email); $avatar = "http://www.gravatar.com/avatar/$hash?s=$s&d=$d&r=$g"; return $avatar; }
2022年06月21日
262 阅读
0 评论
0 点赞
2022-06-21
【Git】Git基本命令
以下是优化并完善后的 Git 常用命令笔记,补充了细节说明、操作场景及扩展用法,结构更清晰,实用性更强:一、初始配置(首次使用 Git 必做)# 配置全局用户名(所有仓库生效) git config --global user.name "xiaopohai" # 配置全局邮箱(与 Git 服务器注册邮箱一致) git config --global user.email "3584685883@qq.com" # 查看当前配置 git config --list 若需为单个仓库单独配置(覆盖全局),进入仓库目录后去掉 --global 即可。二、版本库操作1. 创建本地版本库# 进入目标目录(Windows 示例) cd E:/project # 创建文件夹(可选,也可直接在已有目录操作) mkdir test # 进入文件夹 cd test # 初始化 Git 仓库(生成 .git 隐藏目录,存储版本信息) git init 注意:.git 目录是版本控制核心,不要手动删除或修改。2. 从远程仓库克隆(初始化已有项目)# 克隆远程仓库到本地(会自动创建与仓库同名的文件夹) git clone <远程仓库地址> # 示例:克隆 GitHub 仓库 git clone https://gitee.com/honeyrh/8688web.git 三、文件操作(工作区 → 暂存区 → 版本库)1. 查看文件状态# 详细显示工作区/暂存区文件状态(新增、修改、删除等) git status # 简化输出(短格式,适合快速查看) git status -s 2. 添加文件到暂存区# 添加当前目录所有文件(包括新增、修改,不包括删除) git add . # 添加指定文件(支持通配符,如 *.php) git add 文件名 # 添加所有变化(包括新增、修改、删除的文件) git add -A # 或 git add --all 3. 提交到版本库# 提交暂存区文件到版本库,-m 后跟提交说明(必填,清晰描述改动) git commit -m "初始化项目:添加首页、配置文件" # 若已跟踪的文件修改后,可跳过暂存区直接提交(不推荐新手使用) git commit -am "修改登录逻辑" 4. 删除文件# 从版本库和工作区同时删除文件(彻底删除) git rm 文件名 # 仅从版本库删除(保留工作区文件,不再跟踪) git rm --cached 文件名 # 提交删除操作 git commit -m "删除无用的测试文件" 四、远程仓库交互(推送/拉取)1. 关联远程仓库# 为本地仓库添加远程地址(别名建议用 origin,默认约定) git remote add 别名 <远程仓库地址> # 示例:关联名为 origin 的远程仓库 git remote add origin https://gitee.com/honeyrh/8688web.git 2. 查看/修改远程仓库# 查看已关联的远程仓库(别名和地址) git remote -v # 修改远程仓库地址 git remote set-url 别名 <新地址> # 删除远程仓库关联 git remote remove 别名 3. 推送本地代码到远程# 推送指定分支到远程(首次推送建议关联分支) git push -u 远程别名 本地分支名 # 示例:推送 master 分支到 origin 远程(-u 关联后,后续可直接 git push) git push -u origin master # 推送其他分支(如 dev 分支) git push origin dev 4. 拉取远程代码到本地# 拉取远程指定分支并合并到当前本地分支 git pull 远程别名 远程分支名 # 示例:拉取 origin 远程的 dev 分支 git pull origin dev # 拉取时用变基(rebase)代替合并(减少冗余提交,推荐协作场景) git pull --rebase origin dev 解决特殊合并问题: 当本地与远程仓库无共同历史(如首次合并),拉取时可能报错,需允许无关历史合并:git pull origin master --allow-unrelated-histories 五、版本控制(查看日志/切换版本)1. 查看提交日志# 查看完整提交日志(按时间倒序,最新的在最前) git log # 简化日志(只显示一行,包含提交哈希和说明) git log --pretty=oneline # 查看最近 N 条日志 git log -n 3 # 显示分支合并图(直观查看分支关系) git log --graph --pretty=oneline 2. 查看所有操作记录(包括已删除的提交)git reflog 用于:切换到旧版本后,想再切回新版本(通过此命令获取新版本的哈希值)。3. 切换版本(回退/前进)# 回退到上一个版本(HEAD 是当前版本,^^ 表示上上个,~3 表示前3个) git reset --hard HEAD^ # 等价于 git reset --hard HEAD~1 # 回退到指定版本(通过 git log 或 git reflog 获取哈希值) git reset --hard <提交哈希> # 示例:git reset --hard a1b2c3d --hard:强制覆盖工作区和暂存区,谨慎使用(未提交的改动会丢失)。六、分支管理1. 分支基础操作# 查看所有分支(* 表示当前分支) git branch # 创建新分支 git branch 分支名 # 切换到指定分支 git checkout 分支名 # 创建并立即切换到新分支(推荐,一步到位) git checkout -b 分支名 # 示例:创建并切换到 feature/pay 分支 git checkout -b feature/pay 2. 分支合并与删除# 切换到目标分支(如合并到 master,先切到 master) git checkout master # 合并指定分支到当前分支 git merge 分支名 # 示例:合并 feature/pay 到 master git merge feature/pay # 删除已合并的分支(安全删除) git branch -d 分支名 # 强制删除未合并的分支(谨慎,可能丢失代码) git branch -D 分支名 解决合并冲突: 合并时若出现冲突(同一文件同一位置修改),Git 会提示冲突文件,需:打开冲突文件,找到 <<<<<<< HEAD(当前分支内容)、=======(待合并分支内容)、>>>>>>> 分支名 标记;手动编辑保留正确内容,删除标记;执行 git add 冲突文件 和 git commit -m "解决合并冲突" 完成合并。七、SSH 密钥配置(免密码推送拉取)# 生成 SSH 密钥(-t 指定加密类型,-C 关联邮箱) ssh-keygen -t rsa -C "3584685883@qq.com" 执行后一路回车(默认路径和空密码即可),生成的密钥在:Linux/Mac:~/.ssh/id_rsa(私钥,保密)和 id_rsa.pub(公钥);Windows:C:\Users\用户名\.ssh\id_rsa.pub。配置步骤:打开 id_rsa.pub,复制全部内容;登录 Git 服务器(如 Gitea/GitHub),进入「个人设置 → SSH 密钥」,添加复制的公钥;之后可用 SSH 地址(如 git@https://gitee.com/honeyrh/8688web.git)操作远程仓库,无需输入密码。八、其他实用命令1. 清理未跟踪文件/目录(谨慎使用)# 预览要删除的未跟踪文件/目录(安全,先看再删) git clean -nfd # 强制删除未跟踪文件(-f)和目录(-d) git clean -fd 用途:删除工作区中未被 Git 跟踪的临时文件、编译产物等,避免提交无关文件。2. 暂存工作区改动(临时切换分支时用)# 暂存当前工作区所有未提交的改动 git stash # 查看暂存列表 git stash list # 恢复最近一次暂存的改动(并删除暂存记录) git stash pop # 恢复指定暂存(通过 git stash list 查看索引,如 stash@{0}) git stash apply stash@{0} 3. 丢弃工作区修改# 丢弃指定文件的工作区修改(未 add 到暂存区的改动) git checkout -- 文件名 # Git 2.23+ 推荐用 restore(更清晰) git restore 文件名 通过以上整理,覆盖了 Git 日常使用的核心场景,命令更规范,补充了注意事项和扩展用法,便于新手快速上手和日常参考。
2022年06月21日
318 阅读
0 评论
0 点赞
1
...
8
9
10
...
13