利用curl或者file_get_contents获取远程http的内容时,成功。但是获取https的内容时,失败。错误提示文字类似于:
SSL operation failed with code 1. OpenSSL Error messages: error:14090086: SSL routines:ssl3_get_server_certificate:certificate vertify failed
1、保证php.ini里面的openssl扩展肯定要打开。这个操作比较基础,不做赘述。
extension=openssl.so
2、查看一下openssl证书的默认位置,检测openssl的证书位置的代码:
php -r "print_r(openssl_get_cert_locations());"
default_cert_file是默认位置。
3、下载更新证书
下载网址:https://curl.haxx.se/docs/caextract.html
选择一个最新的perm证书下载即可,下载好的证书要放置在上述默认位置或者自定义好的位置,重启php后,就应该可以解决问题了。
]]>fail2ban 的优点是功能强大,可以对多种恶意行为进行处理;
缺点是配置比较繁琐,需要用户自定义规则,并且可能会误判合法访问。
Fail2ban目录结构如下:
/etc/fail2ban/action.d ----- iptables 、mail 等动作文件目录
/etc/fail2ban/fail2ban.conf ----- 定义日志级别、日志、sock文件位置等
/etc/fail2ban/filter.d ----- 条件匹配(过滤器)文件目录,过滤日志关键内容
/etc/fail2ban/jail.conf ----- 主配置文件,主要设置启用ban动作的服务及动作阀值,不建议修改
/etc/fail2ban/jail.d/ ----- fail2ban模块化子配置文件
安装fail2ban
epel_release源安装fail2ban
# 安装epel_release源
yum install -y epel-release
# 建立缓存
yum makecache
# 安装fail2ban
yum install -y fail2ban fail2ban-firewalld fail2ban-systemd
# Centos7支持tcpd,需要安装fail2ban-hostsdeny
yum install -y fail2ban-hostsdeny
# 现在启动并开机自启
systemctl enable --now fail2ban
源码安装fail2ban
版本 1.0/0.11/0.10(和旧的 0.9)将仍然基于 python2.7
版本1.01及以后以后使用python3
# 安装sqlite3
yum install -y sqlite
# 安装依赖
yum install -y python2 python3
# 下载Fail2ban源码
wget -c https://github.com/fail2ban/fail2ban/archive/refs/tags/1.0.2.tar.gz
# 解压Fail2ban
tar xvf 1.0.2.tar.gz
# 进入解压后的Fail2ban目录
cd fail2ban-1.0.2
# 安装Fail2ban
python3 setup.py install --record fail2ban_install.log
# 如果是1.0以下低版本,请使用python2安装
python2 setup.py install --record fail2ban_install.log
#复制fail2ban服务脚本
cp /root/fail2ban-1.0.2/files/redhat-initd /etc/init.d/fail2ban
#设置fail2ban服务为自启动服务
systemctl enable fail2ban
#启动fail2ban服务
systemctl start fail2ban
# 卸载Fail2ban
cat fail2ban_install.log | xargs rm -rf
全局配置白名单IP(非必须)
vim /etc/fail2ban/filter.d/jail.local
# 全局配置
[DEFAULT]
# 要忽略的 IP 地址。 IP 地址列表可以使用 CIDR 表示法
ignoreip = 10.0.0.0/24
# 封禁IP时间(以秒为单位)。负数-1为“永久”禁止
## 86400秒=1天
bantime = 86400
findtime = 300
maxretry = 5
# banaction = iptables-multiport
backend = systemd
子配置启用sshd保护策略
vim /etc/fail2ban/jail.d/sshd_jail.local
[sshd]
# 启用防护
enabled = true
# 选择过滤器
filter = sshd
# 启用抗攻击防护模式--防护策略敏感度最高
# 正常(默认)、ddos、额外或 aggressive (攻击性 全部组合)。
## normal (default), ddos, extra or aggressive (combines all).
# 有关使用示例和详细信息,请参阅“tests/files/logs/sshd”或“filter.d/sshd.conf”。
mode = aggressive
# 禁止 IP 的持续时间(以秒为单位)。负数-1为“永久”禁止。
## 86400秒为1天
bantime = 86400
## 如果在“findtime”秒内未找到匹配,则计数器设置为零。默认 600s
findtime = 300
# ssh登录失败阈值默认为 3
maxretry = 5
# 指定封禁的端口,默认为0:65535,也就是所有端口,但可以在jail中设定
port = ssh
# 使用哪个工具方法阻止IP
## firewall防火墙: firewallcmd-ipset
## iptables防火墙: iptables 或 iptables-multiport
## 拉黑到/etc/hosts.deny: hostsdeny
banaction = iptables-multiport
hostsdeny
# 日志路径
logpath = %(sshd_log)s
# 指定用于修改日志文件的后端
#backend = %(sshd_backend)s
backend = systemd
常用命令
# 启动Fail2ban
systemctl start fail2ban
# Fail2ban设置为开机自启动
systemctl enable fail2ban
# 重新加载配置或重启服务
systemctl reload-or-restart fail2ban.service
# 查看服务是否正常运行
systemctl status fail2ban.service -l
# 查看哪些IP被ban
fail2ban-client status sshd
# 将IP从黑名单中移除
fail2ban-client set sshd unbanip 8.8.8.8
# 将IP添加到黑名单中
fail2ban-client set sshd banip 8.8.8.8
# 清空黑名单
fail2ban-client unban --all
]]>var g_wakelock = null;
//允许程序后台运行
function wakeLock() {
var main = plus.android.runtimeMainActivity();
var Context = plus.android.importClass("android.content.Context");
var PowerManager = plus.android.importClass("android.os.PowerManager");
var pm = main.getSystemService(Context.POWER_SERVICE);
g_wakelock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ANY_NAME");
g_wakelock.acquire();
}
//结束程序后台运行
function releaseWakeLock() {
if(g_wakelock != null && g_wakelock.isHeld()) {
g_wakelock.release();
g_wakelock = null;
}
}
在需要允许后台运行的时候调用wakeLock(),在希望停止的时候调用releaseWakeLock()
只需要程序后台运行,放到App.vue里的onLaunch
var g_wakelock = null;
var main = plus.android.runtimeMainActivity();
var Context = plus.android.importClass("android.content.Context");
var PowerManager = plus.android.importClass("android.os.PowerManager");
var pm = main.getSystemService(Context.POWER_SERVICE);
g_wakelock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ANY_NAME");
g_wakelock.acquire();
]]>1、安装node.js地址:https://nodejs.org/zh-cn/
安装后在控制台输入:node -v
, 如果显示版本号则安装成功
2、安装npm
一般情况下nodejs安装好后自带npm
可以在控制台输入:npm -v
, 如果显示版本号则安装成功。
二、下载反编译脚本
https://gitee.com/moduo_412/wxappUnpacker
三、安装模拟器
下载夜神模拟器或其他模拟器安装RE文件管理器,使用解密工具可以不用安装模拟器,找到__APP__.wxapkg,不确定是哪个目录可以把当前目录删除,再重新打开小程序
四、在本地找到小程序源文件包
/data/data/com.tencent.mm/MicroMsg/一串32位的16进制字符串文件夹/appbrand/pkg/
小程序源文件包
这个目录下就是你的小程序源文件了,小程序格式就是wxapkg,根据时间找到源文件包压缩后发送到电脑
五、反编译解包
1、打开nodejs命令窗口
2、用cd命令进入反编译脚本根目录下
3、在node命令窗口中依次安装如下
// 安装
npm install
// 安装依赖
npm install esprima
npm install css-tree
npm install cssbeautify
npm install vm2
npm install uglify-es
npm install js-beautify
4、安装好依赖之后,就是最后一步了,反编译 .wxapkg 文件
在当前目录下输入命令:node wuWxapkg.js _163200311_32.wxapkg
_163200311_32.wxapkg是你需要反编译的源文件,输入前几个字符可以按tab键补全
在当前目录找到_163200311_32文件夹(如果不是想要的,请换一个.wxapkg文件):
5、报错处理
Cannot find module 'xxx'
模块未安装
运行命令:npm install xxx
如果这种
错误,请重新换一个.wxapkg文件
执行脚本中可能会出现以下报错
1、修改wuWxss.js文件31行
if (!importCnt[id]) importCnt[id] = 1, statistic(pureData[id]);
// 替换为
if(!importCnt[id]){
if(pureData){
importCnt[id]=1;
statistic(pureData[id]);
}
}
2、修改wuWxss.js文件243行
pureData = vm.run(code + "\n_C");
// 替换为
pureData = vm.run(code + "}");
]]>1、uni-app 打包H5空白页面或者刷新404,加入下面伪静态就可以解决了;
2、如果不想分2个域名去配置,想和后端thinkphp代码放在一起的话,可以在后端创建一个H5目录来放前端的文件,增加对应H5目录的伪静态重写规则,就可以正常访问了;
3、以下是伪静态的配置。
Nginx配置
location /h5/ {
try_files $uri $uri/ /h5/index.html;
}
Apache配置
在h5目录里增加一个.htaccess文件
<IfModule mod_rewrite.c>
Options +FollowSymlinks -Multiviews
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ /h5/index.html [L]
IfModule>
如果单独配置一个前端域名的话,域名指向是h5目录的话,重写规则不需要带/h5
]]># 代理服务器
# 设置服务器组
upstream backend {
server 111.173.115.2:80;
server 111.173.115.3:80;
server 111.173.115.4:80;
}
server {
listen 80;
server_name 111.173.115.1;
location / {
# backend 就是服务器组的名称
proxy_pass http://backend/;
}
}
2、weight加权(加权轮询)
weight=number:用来设置服务器的权重,默认为1,权重数字越大,被分配到请求的几率越大。该权重值主要是针对实际工作环境中不同的后端服务器硬件配置进行调整的,所有此策略比较适合服务器的硬件配置差别比较大的情况。
# 代理服务器
# 设置服务器组
upstream backend {
server 111.173.115.2:80 weight=10;
server 111.173.115.3:80 weight=8;
server 111.173.115.4:80 weight=6;
}
server {
listen 80;
server_name 111.173.115.1;
location / {
# backend 就是服务器组的名称
proxy_pass http://backend/;
}
}
3、ip_hash
当对后端的多台动态应用服务器做负载均衡时,ip_hash指令能够将某个客户端IP的请求通过哈希算法定位到同一台后端服务器上。这样,当来自某一个IP的用户在后端Web服务器A上登录后,再访问该站点的其他URL,能保证其访问的还是后端web服务器A。
注意:使用ip_hash指令无法保证后端服务器的负载均衡,可能导致有些后端服务器接收到的请求多,有些后端服务器接受的请求少,而且设置后端服务器权重等方法将不起作用。
# 代理服务器
# 设置服务器组
upstream backend {
ip_hash;
server 111.173.115.2:80;
server 111.173.115.3:80;
server 111.173.115.4:80;
}
server {
listen 80;
server_name 111.173.115.1;
location / {
# backend 就是服务器组的名称
proxy_pass http://backend/;
}
}
4、least_conn
least_conn:最少连接,把请求转发给连接数较少的后端服务器。轮询算法是把请求平均地转发给各个后端,使它们的负载大致相同;但是,有些请求占用的时间很长,会导致其所在的后端负载较高。这种情况下,least_conn这种方式就可以达到更好的负载均衡效果。
# 代理服务器
# 设置服务器组
upstream backend {
least_conn;
server 111.173.115.2:80;
server 111.173.115.3:80;
server 111.173.115.4:80;
}
server {
listen 80;
server_name 111.173.115.1;
location / {
# backend 就是服务器组的名称
proxy_pass http://backend/;
}
}
5、url_hash
按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器,要配合缓存命中来使用。同一个资源多次请求,可能会到达不同的服务器上,导致不必要的多次下载,缓存命中率不高,以及一些资源时间的浪费。而使用url_hash,可以使得同一个url(也就是同一个资源请求)会到达同一台服务器,一旦缓存住了资源,再次收到请求,就可以从缓存中读取。
# 代理服务器
# 设置服务器组
upstream backend {
hash $request_uri;
server 111.173.115.2:80;
server 111.173.115.3:80;
server 111.173.115.4:80;
}
server {
listen 80;
server_name 111.173.115.1;
location / {
# backend 就是服务器组的名称
proxy_pass http://backend/;
}
}
6、fair
fair采用的不是内建负载均衡使用的均衡算法,而是可以根据页面大小、加载时间长短智能地进行负载均衡。那么如何使用第三方模块的fair负载均衡策略?
# 代理服务器
# 设置服务器组
upstream backend {
fair;
server 111.173.115.2:80;
server 111.173.115.3:80;
server 111.173.115.4:80;
}
server {
listen 80;
server_name 111.173.115.1;
location / {
# backend 就是服务器组的名称
proxy_pass http://backend/;
}
}
但是如果直接使用会报错,因为fair属于第三方模块实现的负载均衡。需要添加nginx-upstream-fair,如何添加对应的模块:
1.下载nginx-upstream-fair模块。
https://github.com/gnosek/nginx-upstream-fair
2.将下载的文件上传到服务器并进行解压缩。
unzip nginx-upstream-fair-master.zip
3.重命名资源。
mv nginx-upstream-fair-master fair
4.使用./configure命令将资源添加到Nginx模块中。
./configure --add-module=/root/fair
5.编译。
make
-编译可能会出现如下错误: nginx_http_upstream_srv_conf_t结构中缺少default_port
-解决方案 在Nginx的源码中src/http/nginx_http_upstream.h,找到ngx_http_upstream_srv_conf_s,在模块中添加default_port属性:
in_port_t default_port 然后再进行make。
6.更新Nginx。
1、将sbin目录下的nginx进行备份
mv /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginxold2、将安装目录下的objs中的nginx拷贝到sbin目录
cd objs
cp nginx /usr/local/nginx/sbin3、更新
cd ../
make upgrade
7.编译测试使用Nginx。
]]>composer require phpoffice/phpspreadsheet
PhpSpreadsheet中文简介
phpexcel由于版本陈旧性能低下官方放弃维护,转而开发PhpSpreadsheet用了最新得psr标准因而对php版本不向下兼容需要注意!
PhpSpreadsheet是一个用纯PHP编写的库,提供了一组类,使您可以读取和写入不同的电子表格文件格式
PhpSpreadsheet提供了丰富的API接口,可以设置诸多单元格以及文档属性,包括样式、图片、日期、函数等等诸多应用,总之你想要什么样的Excel表格,PhpSpreadsheet都能做到
使用PhpSpreadsheet开发的PHP要求7.1或更高版本,并且支持链式操作
PhpSpreadsheet 支持的文件格式
文件路径extend/Excel.php
<?php
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
use PhpOffice\PhpSpreadsheet\IOFactory;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use think\exception\ValidateException;
class Excel
{
/**
* 导入excel表格
* @param array $file 文件路径
* @return array|string
*/
protected function importExcel($file)
{
try {
// 截取后缀
$fileExtendName = substr(strrchr($file, '.'), 1);
// 有Xls和Xlsx格式两种
if ($fileExtendName == 'xlsx') {
$objReader = IOFactory::createReader('Xlsx');
} else {
$objReader = IOFactory::createReader('Xls');
}
// 设置文件为只读
$objReader->setReadDataOnly(TRUE);
// 读取文件,tp6默认上传的文件,在runtime的相应目录下,可根据实际情况自己更改
$objPHPExcel = $objReader->load($_SERVER['DOCUMENT_ROOT'] . $file);
//excel中的第一张sheet
$sheet = $objPHPExcel->getSheet(0);
// 取得总行数
$highestRow = $sheet->getHighestRow();
// 取得总列数
$highestColumn = $sheet->getHighestColumn();
Coordinate::columnIndexFromString($highestColumn);
$lines = $highestRow - 1;
if ($lines <= 0) {
return '数据不能为空';
}
// 直接取出excle中的数据
$data = $objPHPExcel->getActiveSheet()->toArray();
// 删除第一个元素(表头)
array_shift($data);
// 返回结果
return $data;
} catch (ValidateException $e) {
return $e->getMessage();
}
}
/**
* 导出excel表格
* @param array $header 设置表头数据
* @param array $data 生成的表格数据
* @param bool $type 文件类型,true为Xlsx,false为Xls,默认为true
* @param string $fileName 文件名,默认为数据
*/
protected function export($header = [], $data = [], $type = true, $fileName = "数据")
{
// 实例化类
$preadsheet = new Spreadsheet();
// 创建sheet
$sheet = $preadsheet->getActiveSheet();
// 生成表头字母
$letter = [];
$n = 0;
for ($i = 'A'; $i <= 'Z'; $i++) {
if ($n<count($header)){
$letter[] = $i;
}else{
break;
}
$n++;
}
// 循环设置表头数据
foreach ($header as $k => $v) {
// 解决长数字自动转科学计数法
if(is_numeric($v) && strlen($v) > 11){
$sheet->setCellValueExplicit($letter[$k].'1',$v,'s');
}
$sheet->setCellValue($letter[$k].'1', $v);
}
// 生成数据
$sheet->fromArray($data, null, "A2");
// 样式设置
$sheet->getDefaultColumnDimension()->setWidth(12);
// 设置下载与后缀
if ($type) {
header("Content-Type:application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
$type = "Xlsx";
$suffix = "xlsx";
} else {
header("Content-Type:application/vnd.ms-excel");
$type = "Xls";
$suffix = "xls";
}
// 激活浏览器窗口
header("Content-Disposition:attachment;filename=$fileName.$suffix");
//缓存控制
header("Cache-Control:max-age=0");
// 调用方法执行下载
$writer = IOFactory::createWriter($preadsheet, $type);
// 数据流
$writer->save("php://output");
}
}
调用
$excel = new Excel();
// 导出
$header = ['姓名','性别'];
$data = [['小王','男'],['小李','男']];
$excel->export($header,$data);
// 导入
$data = $excel->importExcel('/storage/picture/20221222/77d80064c35db092c8124a13a7f6fcd5.xlsx');
if(is_array($data)){
print_r($data);
}else{
echo $data;
}
]]>字符 | 说明 | 字符实体名 | 实体编号 |
---|---|---|---|
" | 双引号 | \" | \" |
' | 撇号 | \'(IE不支持) | \' |
< | 小于号 | \< | \< |
> | 大于号 | \> | \> |
& | 和号 | \& | \& |
© | 版权(copyright) | \© | \© |
® | 注册商标 | \® | \® |
™ | 商标 | \™ | \™ |
× | 乘号 | \× | \× |
÷ | 除号 | \÷ | \÷ |
£ | 镑(pound) | \£ | \£ |
¥ | 元(yen) | \¥ | \¥ |
竖条 | \| | ||
§ | 小节 | \§ | \§ |
Empty space | 不间断空格 | \ | \  |
€ | 欧元(euro) | \€ | \€ |
中文全角空格 | \& | \  | |
· | 间隔符 | \· | \· |
« | 左双尖括号 | \« | \« |
» | 右双尖括号 | \» | \» |
° | 度 | \° | \° |
‰ | 千分比 | \‰ | \‰ |
浮点型
又称为精度类型,是一种可能丢失精度的数据类型,数据可能不那么准确
float 单精度类型
4字节存储,7位精度,表示数据范围比整数大得多
float 表示不指定小数位的浮点数
float(M, D)表示一共存储M个有效数字,其中小数部分占D位
double 双精度类型
8个字节存储,表示范围更大,精度有15位左右
double 表示不指定小数位的浮点数
double(M, D)表示一共存储M个有效数字,其中小数部分占D位
如何选择
当需要存储的小数对精度要求不高时,可以选择FLOAT单精度浮点型,可以节省内存空间,提高计算速度。
当需要进行高速数学计算、科学计算、卫星定位计算等对精度要求较高时,可以选择DOUBLE双精度浮点型。
当需要进行精确计算,如工资结算、转账打款等财务类型的数据,可以选择DECIMAL定点型。
Document 对象使我们可以从脚本中对 HTML 页面中的所有元素进行访问。Document 对象是 Window 对象的一部分。
我们项目中需要使用第三方支付,第三方支付文件使用了DOMDocument,如果直接使用DOMDocument的话会报错
解决方法
只需要在DOMDocument加上一个反斜杠就可以了
$dom = new \DOMDocument();
$dom->loadXML($data);
]]>