首页
关于
归档
朋友
壁纸
留言
API平台
告白墙
更多
休闲游戏
留言板
练字贴
Layui手册
Search
1
【PHP】PHPoffice/PHPSpreadsheet读取和写入Excel
1,339 阅读
2
【Git】No tracked branch configured for branch master or the branch doesn't exist.
1,038 阅读
3
【Layui】控制页面元素展示隐藏
858 阅读
4
【composer】composer常用命令
787 阅读
5
【PHP】PHP实现JWT生成和验证
769 阅读
默认分类
PHP
ThinkPHP
Laravel
面向对象
设计模式
算法
基础
网络安全
Web
HTML
CSS
JavaScript
jQuery
Layui
VUE
uni-app
Database
MySQL
Redis
RabbitMQ
Nginx
Git
Linux
Soft Ware
Windows
网赚
Go
登录
Search
标签搜索
PHP
函数
方法
类
MySQL
ThinkPHP
OOP
JavaScript
Layui
Web
Linux
Array
设计模式
Git
PHPSpreadsheet
PHPoffice
排序算法
基础
面试题
Windows
小破孩
累计撰写
223
篇文章
累计收到
33
条评论
首页
栏目
默认分类
PHP
ThinkPHP
Laravel
面向对象
设计模式
算法
基础
网络安全
Web
HTML
CSS
JavaScript
jQuery
Layui
VUE
uni-app
Database
MySQL
Redis
RabbitMQ
Nginx
Git
Linux
Soft Ware
Windows
网赚
Go
页面
关于
归档
朋友
壁纸
留言
API平台
告白墙
休闲游戏
留言板
练字贴
Layui手册
搜索到
28
篇与
的结果
2025-03-13
【PHP】ThinkPHP6.1 参数验证中间件
public function handle($request, \Closure $next) { try { // 获取并清理参数 $params = array_filter(array_map(function ($value) { return is_string($value) ? trim($value) : $value; }, $request->param()), function ($value) { return is_numeric($value) || !empty($value); }); unset($params['controller'], $params['function']); if (empty($params)) return $next($request); // 设置请求属性,方便后续使用 $request->checkParam = $params; // 获取应用名、控制器和操作名 $appName = app('http')->getName(); $controller = Request::instance()->controller(true); $action = Request::instance()->action(true); // 动态构建验证器路径 $controllerParts = explode('.', $controller); $validatePathParts = array_merge([$appName, 'validate'], $controllerParts); $validatePath = implode('\\', array_map('ucfirst', $validatePathParts)); // 检查验证器是否存在及场景是否定义 if (!class_exists($validatePath) || !$this->sceneExists($validatePath, $action)) { return $next($request); } // 验证数据 $validateInstance = new $validatePath; if (!$validateInstance->scene($action)->check($params)) { throw new Exception($validateInstance->getError()); } } catch (Exception $e) { return show(100, $e->getMessage()); } return $next($request); } /** * 检查指定验证场景是否存在 * * @param string $validateClass 验证类名 * @param string $scene 场景名 * @return bool */ protected function sceneExists(string $validateClass, string $scene): bool { return (new $validateClass)->hasScene($scene); }
2025年03月13日
7 阅读
0 评论
0 点赞
2025-03-13
【PHP】发送腾讯云短信
优化空间很大,先用着,能用<?php namespace app\common\lib\sms\tencent; //缓存 use think\facade\Cache; use TencentCloud\Common\Credential; use TencentCloud\Common\Profile\ClientProfile; use TencentCloud\Common\Profile\HttpProfile; use TencentCloud\Common\Exception\TencentCloudSDKException; use TencentCloud\Sms\V20210111\SmsClient; use TencentCloud\Sms\V20210111\Models\SendSmsRequest; class Sms{ public $SecretID = "......................"; public $SecretKey = "......................."; public $SmsSdkAppId = "..........."; public $TemplateId = "........."; public $SignName = "............"; public $code; public $phone; public function __construct($phone = '', $code = '', $tempID = '') { $this->phone = $phone; $this->code = $code; if(!empty($tempID)){ $this->TemplateId = $tempID; } } public function send(){ try { //控制台 >API密钥管理页面获取 SecretID 和 SecretKey $cred = new Credential($this->SecretID, $this->SecretKey); //实例化一个http选项 [可选] $httpProfile = new HttpProfile(); $httpProfile->setEndpoint("sms.tencentcloudapi.com"); //实例化一个client选项 [可选] $clientProfile = new ClientProfile(); $clientProfile->setHttpProfile($httpProfile); /** * 实例化以sms为例的client对象, [第三个参数 可选] * * 第二个参数是地域信息,可以直接填 ap-guangzhou */ $client = new SmsClient($cred, "ap-beijing", $clientProfile); // 实例化一个sms发送短信请求对象,每个接口都会对应一个request对象。 $req = new SendSmsRequest(); //生成随机验证码 // $code = rand(11111, 99999); // $params = array( // //接收方手机号,带上+86 示例:+8613711112222 // "PhoneNumberSet" => array((string)$this->phone), // //短信应用ID:在 [短信控制台] 添加应用后生成的实际SdkAppId // "SmsSdkAppId" => (string)$this->SmsSdkAppId, // //短信签名内容:[不理解可以看文章里的截图] // "SignName" => (string)$this->SignName, // //模板ID:必须填写已审核通过的模板 // "TemplateId" => (string)$this->TemplateId, // //我的模板中有两个参数 第一个是验证码参数 第二个是有效时间 若无模板参数,则设置为空 // "TemplateParamSet" => array((string)$this->code, '10'), // //SecretID // // "SenderId" => (string)$this->SecretID // ); $params = array( "PhoneNumberSet" => array( (string)$this->phone ), "SmsSdkAppId" => (string)$this->SmsSdkAppId, "SignName" => (string)$this->SignName, "TemplateId" => (string)$this->TemplateId, "TemplateParamSet" => array( (string)$this->code), // "SenderId" => (string)$this->SecretID ); $req->fromJsonString(json_encode($params)); //发出请求,返回一个实例 $resp = $client->SendSms($req); // print_r($resp);die; //如果成功,把验证码存入缓存 //成功实例中的Code值为 Ok if ($resp->SendStatusSet[0]->Code === "Ok") { return true; // Cache::set('name', $code, 600); // return json(['msg' => "发送成功", 'code' => 200]); } } catch (TencentCloudSDKException $e) { echo $e; } } }
2025年03月13日
7 阅读
0 评论
0 点赞
2025-03-13
【PHP】打印猿&蜂打打 开放平台 完整对接
基础类<?php namespace app\common\lib\printman; use think\facade\Log; class Basic { #APPID public $AppId; #密钥 public $AppSecret; #API地址 public $ApiUrl; #打印机ID public $PrinterId; public function __construct($AppId, $AppSecret, $PrinterId) { $this->AppId = $AppId; $this->AppSecret = $AppSecret; $this->ApiUrl = "https://iot-app-prod.fengdada.cn/mk/api"; $this->PrinterId = $PrinterId; } public function encode($BizData, $nonce) { // global $AppSecret; $jsonBytes = mb_convert_encoding($BizData , 'utf-8'); $bizData = strval($jsonBytes); $sign_ori = $bizData . $nonce . $this->AppSecret; $md5_hash = md5($sign_ori, true); $sign = base64_encode($md5_hash); return $sign; } public function generate_verification_code() { $verification_code = ""; for ($i = 0; $i < 6; $i++) { $verification_code .= strval(rand(0, 9)); } return $verification_code; } public function requests_post($url, $data, $headers) { $ch = curl_init(); curl_setopt($ch, CURLOPT_CAINFO, "cacert-2023-01-10.pem"); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); curl_setopt($ch, CURLOPT_POSTFIELDS, $data); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $response = curl_exec($ch); curl_close($ch); return $response; } public function DoMyPost($URL, $json_BizData) { $ts = round(microtime(true) * 1000); $nonce = $this->generate_verification_code(); $sign = $this->encode($json_BizData, $nonce); $data = array( "bizData" => $json_BizData, "nonce" => $nonce, "appId" => $this->AppId, "timestamp" => strval($ts) ); $headers = array( 'Content-Type: application/json', 'sign:'.$sign ); // $response = $this->requests_post($URL, json_encode($data), $headers); $response = $this->curlRequest($URL, "POST",json_encode($data),true,false, $headers); Log::write("打印机日志:".print_r($response,true),'printman'); if(empty($response)) { echo "Error: no response received"; }else{ return $response; } } // 云打印验证码 public function PrintCaptcha() { $URL = $this->ApiUrl."/print/captcha"; $BizData = array('printerId' => $this->PrinterId); $json_BizData = json_encode($BizData); return $this->DoMyPost($URL, $json_BizData); } // 云打印机绑定 public function PrintBind($VerificationCode) { $URL = $this->ApiUrl."/printer/bind"; $BizData = array('printerId' => $this->PrinterId, 'captcha' => $VerificationCode); $json_BizData = json_encode($BizData); return $this->DoMyPost($URL, $json_BizData); } // 云打印 public function CloudPrint( $ShareCode, $PrintDataList) { $URL = $this->ApiUrl."/print"; $BizData = array('printerId' => $this->PrinterId, 'shareCode' => $ShareCode, 'printData' => $PrintDataList); $json_BizData = json_encode($BizData); return $this->DoMyPost($URL, $json_BizData); } // 云打印状态查询 public function QueryPrintStatus($ShareCode) { $URL = $this->ApiUrl."/printer/status/query"; $BizData = array('printerId' => $this->PrinterId, 'shareCode' => $ShareCode); $json_BizData = json_encode($BizData); return $this->DoMyPost($URL, $json_BizData); } //云打印解绑//0标识解绑失败,1标识解绑成功 public function unbind($ShareCode){ $URL = $this->ApiUrl."/printer/unbind"; $BizData = array('printerId' => $this->PrinterId, 'shareCode' => $ShareCode); $json_BizData = json_encode($BizData); return $this->DoMyPost($URL, $json_BizData); } /** * @Author: 小破孩嫩 * @Email: 3584685883@qq.com * @Time: 2021/4/1 10:39 * @param string $url url地址 * @param string $method 请求方法,默认为 'GET',可选值为 'GET' 或 'POST' * @param mixed $data 要发送的数据,如果是 POST 请求则为数据内容,否则为 null * @param array $headers 自定义请求头信息 * @param int $timeout 超时时间,默认为 30 秒 * @param bool $verifySSL 是否验证 SSL 证书,默认为 true * @param bool $flbg 返回值是否转成数组,默认不转 * @param bool $headercontent 是否获取请求的header值内容,默认不获取 * @return array|bool|mixed|string * @Description:curl请求 */ protected function curlRequest($url, $method = 'GET', $data = null, $flbg = false, $verifySSL = true, $headers = [], $headerContent = false, $timeout = 30) { // 初始化 cURL 会话 $ch = curl_init(); // 设置要请求的 URL curl_setopt($ch, CURLOPT_URL, $url); // 设置获取的信息以字符串形式返回,而不是直接输出 curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // 设置超时时间 curl_setopt($ch, CURLOPT_TIMEOUT, $timeout); // 设置请求方法 if ($method === 'POST') { curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $data); } // 设置请求头 if (!empty($headers)) { curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); } // 设置是否验证 SSL 证书 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, $verifySSL); // 执行 cURL 会话并获取响应 $response = curl_exec($ch); // 获取 HTTP 响应码 $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); // 如果 cURL 执行出错 if (curl_errno($ch)) { // 输出错误信息 echo 'Curl error: ' . curl_error($ch); // 关闭 cURL 会话并返回 false curl_close($ch); return false; } // 如果 HTTP 响应码大于等于 400(表示错误) elseif ($httpCode >= 400) { // 输出错误信息 echo "HTTP error: $httpCode"; // 关闭 cURL 会话并返回 false curl_close($ch); return false; } // 处理是否获取请求头内容 if ($headerContent && $httpCode == 200) { $headerSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE); $headers = substr($response, 0, $headerSize); $body = substr($response, $headerSize); curl_close($ch); return [$headers, $body]; } // 关闭 cURL 会话 curl_close($ch); // 处理是否将响应转换为数组 if ($flbg) { $response = json_decode($response, true); } // 返回响应内容 return $response; } /** * @Author:小破孩 * @Email:3584685883@qq.com * @Time:2025/1/10 14:02 * @param $code * @return string * @Description:打印机错误码 */ public function errorCode($code){ $errorCodes = [ 200 => "success 成功", 500 => "sys fail 系统异常", 2001 => "sign check fail 签名失败", 2002 => "not find partner 查无合作伙伴", 2003 => "illegal access 非法访问", 3001 => "param check error 参数错误", 3002 => "please input params 请输入参数", 40001 => "please input APPID 请输入appid", 40002 => "biz exception 业务异常", 40003 => "printer xxx is offline 打印机离线", 40004 => "printer xxx is not auth 打印机未授权", 40005 => "shareCode is error 分享码错误", 40006 => "printer xxx after 5 minutes reprinting 请5分钟后重试", 40007 => "printer xxx captcha error 验证码错误", 40008 => "printer xxx captcha expired 验证码过期", 40009 => "printer xxx bind fail 绑定失败", 40023 => "lip not close 盖子未闭合", 40023 => "sticker 粘纸", 40023 => "sticker and lip not close 粘纸并且盖子未闭合", 40023 => "no page 缺纸", 40023 => "no page and lip not close 缺纸并且盖子未闭合", 40023 => "temperature too high 温度过高", 40023 => "temperature too high and lip not close 温度过高且盖子未闭合", 40023 => "temperature too high and sticker 温度过高且粘纸", 40023 => "temperature too high and lip not close and sticker 温度过高且粘纸,盖子未闭合", 40023 => "command error 指令错误" ]; return $errorCodes[$code]; } }模板<?php namespace app\common\lib\printman\template; use app\common\lib\printman\Template; class Temp1 implements Template { protected $id; public function __construct($id = "") { $this->id = $id; } /** * @Author:小破孩 * @Email:3584685883@qq.com * @Time:2025/1/10 10:51 * @return string * @Description:打印模板1 */ public function temp($order = ""){ if(empty($order)){ return "没有订单信息"; } $height = ceil(self::getTempHight($order)/10+50); $i = 40; $template = ""; $template .= "SIZE 72 mm, ".$height." mm\r\n"; $template .= "CODEPAGE 437\r\n"; $template .= "DENSITY 8\r\n"; $template .= "CLS \r\n"; $template .= "CODEPAGE 936\r\n"; $template .= "DIRECTION 0\r\n"; $template .= "TEXT 220,0,\"4\",0,1,1,\""."订单详情"."\"\r\n"; //小票标题 $template .= "TEXT 220,".$i.",\"4\",0,1,1,\"".""."\"\r\n"; //换行 $template .= "TEXT 40,"; $template .= $i+=30; $template .= ",\"0\",0,1,1,\"订单编号:".$order['o_uuid']."\"\r\n"; $template .= "TEXT 40,"; $template .= $i+=30; $template .= ",\"0\",0,1,1,\"打印时间:".date("Y-m-d H:i:s")."\"\r\n"; $template .= "TEXT 40,"; $template .= $i+=30; $template .= ",\"0\",0,1,1,\"申 请 人:".$order['o_address_name']."\"\r\n"; $template .= "TEXT 40,"; $template .= $i+=30; $template .= ",\"0\",0,1,1,\"联系方式:".$order['o_address_tel_default']."\"\r\n"; $template .= "TEXT 40,"; $template .= $i+=30; $template .= ",\"0\",0,1,1,\"收货地址:".mb_substr($order['o_address_info'],0,16)."\"\r\n"; if(mb_strlen($order['o_address_info']) > 16){ $template .= "TEXT 40,"; $template .= $i+=30; $template .=",\"0\",0,1,1,\" ".mb_substr($order['o_address_info'],16)."\"\r\n"; } $template .= "TEXT 40,"; $template .= $i+=30; $template .= ",\"0\",0,1,1,\"申请时间:".$order['o_create_time']."\"\r\n"; // $template .= "TEXT 40,"; // $template .= $i+=30; // $template .= ",\"0\",0,1,1,\"审核时间:".date("Y-m-d H:i:s",$order['o_pay_receipt_allow_time'])."\"\r\n"; $template .= "TEXT 40,"; $template .= $i+=30; $template .= ",\"0\",0,1,1,\"配 送 员:".$order['salesmaninfo']['sm_name']."\"\r\n"; $template .= "TEXT 40,"; $template .= $i+=30; $template .= ",\"0\",0,1,1,\"配送电话:".$order['salesmaninfo']['sm_phone']."\"\r\n"; $template .= "TEXT 40,"; $template .= $i+=30; $template .= ",\"0\",0,1,1,\"出货仓库:".$order['warehouse_name']."\"\r\n"; $template .= "TEXT 40,"; $template .= $i+=30; $template .= ",\"0\",0,1,1,\"商品总数:".$order['goods_total_num']."\"\r\n"; $template .= "TEXT 40,"; $template .= $i+=30; $template .= ",\"0\",0,1,1,\"商品总价:".$order['o_real_price']."\"\r\n"; $template .= "BAR 20,"; $template .= $i+=28; $template .= ",720,2\r\n"; $template .= "TEXT 40,"; $template .= $i+=16; $template .= ",\"0\",0,1,1,\"商品 数量 单价 金额\"\r\n"; $template .= "BAR 20,"; $template .= $i+=28; $template .= ",720,2\r\n"; foreach ($order['order_list'] as $kk => $vv){ if(!empty($vv['oi_issendgoods'])){ $firstNamaText = "赠品:"; }else{ $firstNamaText = "商品:"; } $knum = $kk+=1; $template .= "TEXT 30,"; $template .= $i+=30; $template .= ",\"0\",0,1,1,\"$knum.". mb_substr($firstNamaText.$vv['oi_sku_info']['goods_info']['withgoodsinfoinfo']['sg_name'].'('.$vv['oi_sku_info']['sgcs_name'].')',0,26)."\"\r\n"; if(mb_strlen($firstNamaText.$vv['oi_sku_info']['goods_info']['withgoodsinfoinfo']['sg_name'].'('.$vv['oi_sku_info']['sgcs_name'].')') > 26){ $template .= "TEXT 30,"; $template .= $i+=30; $template .=",\"0\",0,1,1,\" ".mb_substr($firstNamaText.$vv['oi_sku_info']['goods_info']['withgoodsinfoinfo']['sg_name'].'('.$vv['oi_sku_info']['sgcs_name'].')',26)."\"\r\n"; } $template .= "TEXT 65,"; $template .= $i+=30; if(!empty($vv['oi_issendgoods'])){ $template .=",\"0\",0,1,1,\"".$vv['oi_sku_info']['num'].'件'.' '."0.00".' '."0.00"."\"\r\n"; }else{ $template .=",\"0\",0,1,1,\"".$vv['oi_sku_info']['num'].'件'.' '.sprintf("%.2f",$vv['oi_sku_info']['sgcs_price']/$vv['oi_sku_info']['num']).' '.$vv['oi_real_price']."\"\r\n"; } } $template .= "BAR 20,"; $template .= $i+=28; $template .= ",720,2\r\n"; $template .= "TEXT 40,"; $template .= $i+=30; $template .= ",\"0\",0,1,1,\"数量总计:".$order['goods_total_num'].'件'."\"\r\n"; $template .= "PRINT 1,1"; $instacneStr = new \app\common\lib\data\Str(); $data = [ 'waybillPrinterData' => $instacneStr->gzipAndBase64Encode($template), 'printType' => 'tspl', 'id' => $this->id ]; return [$data]; } protected function getTempHight($order){ $i = 50; $template = ""; $template .= "SIZE 72 mm, 90 mm\r\n"; $template .= "CODEPAGE 437\r\n"; $template .= "DENSITY 8\r\n"; $template .= "CLS \r\n"; $template .= "CODEPAGE 936\r\n"; $template .= "DIRECTION 0\r\n"; $template .= "TEXT 220,0,\"4\",0,1,1,\""."订单详情"."\"\r\n"; //小票标题 $template .= "TEXT 220,".$i.",\"4\",0,1,1,\"".""."\"\r\n"; //换行 $template .= "TEXT 40,"; $template .= $i+=30; $template .= ",\"0\",0,1,1,\"订单编号:".$order['o_uuid']."\"\r\n"; $template .= "TEXT 40,"; $template .= $i+=30; $template .= ",\"0\",0,1,1,\"打印时间:".date("Y-m-d H:i:s")."\"\r\n"; $template .= "TEXT 40,"; $template .= $i+=30; $template .= ",\"0\",0,1,1,\"申 请 人:".$order['o_address_name']."\"\r\n"; $template .= "TEXT 40,"; $template .= $i+=30; $template .= ",\"0\",0,1,1,\"联系方式:".$order['o_address_tel_default']."\"\r\n"; $template .= "TEXT 40,"; $template .= $i+=30; $template .= ",\"0\",0,1,1,\"收货地址:".mb_substr($order['o_address_info'],0,16)."\"\r\n"; if(mb_strlen($order['o_address_info']) > 16){ $template .= "TEXT 40,"; $template .= $i+=30; $template .=",\"0\",0,1,1,\" ".mb_substr($order['o_address_info'],16)."\"\r\n"; } $template .= "TEXT 40,"; $template .= $i+=30; $template .= ",\"0\",0,1,1,\"申请时间:".$order['o_create_time']."\"\r\n"; // if(empty($order['o_help'])){ // $template .= "TEXT 40,"; // $template .= $i+=30; // $template .= ",\"0\",0,1,1,\"审核时间:".date("Y-m-d H:i:s",$order['o_pay_receipt_allow_time'])."\"\r\n"; // } $template .= "TEXT 40,"; $template .= $i+=30; $template .= ",\"0\",0,1,1,\"配送员姓名:".$order['salesmaninfo']['sm_name']."\"\r\n"; $template .= "TEXT 40,"; $template .= $i+=30; $template .= ",\"0\",0,1,1,\"配送员电话:".$order['salesmaninfo']['sm_phone']."\"\r\n"; $template .= "TEXT 40,"; $template .= $i+=30; $template .= ",\"0\",0,1,1,\"出货仓库:".$order['warehouse_name']."\"\r\n"; $template .= "TEXT 40,"; $template .= $i+=30; $template .= ",\"0\",0,1,1,\"商品总数:".$order['goods_total_num']."\"\r\n"; $template .= "TEXT 40,"; $template .= $i+=30; $template .= ",\"0\",0,1,1,\"商品总价:".$order['o_real_price']."\"\r\n"; $template .= "BAR 20,"; $template .= $i+=28; $template .= ",720,2\r\n"; $template .= "TEXT 40,"; $template .= $i+=16; $template .= ",\"0\",0,1,1,\"商品 数量 单价 金额\"\r\n"; $template .= "BAR 20,"; $template .= $i+=28; $template .= ",720,2\r\n"; // foreach ($order as $key => $val){ foreach ($order['order_list'] as $kk => $vv){ if(!empty($vv['oi_issendgoods'])){ $firstNamaText = "赠品:"; }else{ $firstNamaText = "商品:"; } $knum = $kk+=1; $template .= "TEXT 30,"; $template .= $i+=30; $template .= ",\"0\",0,1,1,\"$knum.". mb_substr($firstNamaText.$vv['oi_sku_info']['goods_info']['withgoodsinfoinfo']['sg_name'].'('.$vv['oi_sku_info']['sgcs_name'].')',0,26)."\"\r\n"; if(mb_strlen($firstNamaText.$vv['oi_sku_info']['goods_info']['withgoodsinfoinfo']['sg_name'].'('.$vv['oi_sku_info']['sgcs_name'].')') > 26){ $template .= "TEXT 30,"; $template .= $i+=30; $template .=",\"0\",0,1,1,\" ".mb_substr($firstNamaText.$vv['oi_sku_info']['goods_info']['withgoodsinfoinfo']['sg_name'].'('.$vv['oi_sku_info']['sgcs_name'].')',26)."\"\r\n"; } $template .= "TEXT 65,"; $template .= $i+=30; $template .=",\"0\",0,1,1,\"".$vv['oi_sku_info']['num'].'件'.' '.$vv['oi_sku_info']['sgcs_price'].' '.$vv['oi_sku_info']['sgcs_price']*$vv['oi_sku_info']['num']."\"\r\n"; } $template .= "BAR 20,"; $template .= $i+=28; $template .= ",720,2\r\n"; $template .= "TEXT 40,"; $template .= $i+=30; $template .= ",\"0\",0,1,1,\"数量总计:".$order['goods_total_num']."\"\r\n"; // } $template .= "PRINT 1,1"; return $i; } }
2025年03月13日
5 阅读
0 评论
0 点赞
2025-03-13
【PHP】给富文本内容的图片,视频,文件 拼接当前网址域名
/** * @Author:小破孩 * @Email:3584685883@qq.com * @Time:2024/11/18 15:20 * @param $text * @param $domain * @return string|string[]|null * @Description:给服务文本拼接当前网址域名 */ public function addDomainToPaths($text, $domain){ // 匹配图片路径 $text = preg_replace('/<img.*?src="([^"]+)"/i', '<img src="' . $domain . '$1"', $text); // 匹配视频路径 $text = preg_replace('/<video.*?src="([^"]+)"/i', '<video src="' . $domain . '$1"', $text); // 匹配文件路径(可根据具体文件类型的链接特征进行修改) $text = preg_replace('/<a.*?href="([^"]+)"/i', '<a href="' . $domain . '$1"', $text); return $text; }
2025年03月13日
9 阅读
0 评论
0 点赞
2025-03-13
【PHP】过滤富文本内容
/** * @Author:小破孩 * @Email:3584685883@qq.com * @Time:2024/10/24 13:50 * @param $text * @return string|string[]|null * @Description:过滤富文本 */ public static function filterRichText($text){ // 定义要过滤的 SQL 关键字模式 $sqlPatterns = [ '/\b(SELECT|INSERT|UPDATE|DELETE|FROM|WHERE|AND|OR|JOIN|DROP|CREATE|ALTER|TRUNCATE|GRANT|REVOKE|SET)\b/i', '/\b(AS|LIKE|NOT|IN|BETWEEN|IS|NULL|COUNT|SUM|AVG|MIN|MAX)\b/i', '/\b(UNION|ALL|ANY|EXISTS)\b/i', '/\b(ORDER\s+BY|LIMIT)\b/i' ]; // 定义要过滤的常见函数模式 $functionPatterns = [ '/\b(function\s+\w+\s*\([^)]*\))\b/i', '/\b(eval|exec|system|passthru|shell_exec|assert)\b/i' ]; // 定义要过滤的特殊字符和表达式模式 $specialPatterns = [ '/\$\{.*?\}/', // 过滤类似 ${expression} 的表达式 '/@.*?;/', // 过滤以 @ 开头并以 ; 结尾的表达式 '/\b(phpinfo|var_dump)\b/i', // 过滤特定的 PHP 函数 '/<\s*(script|iframe|object|embed|applet)[^>]*>/i' // 过滤危险的脚本标签 ]; // 定义要过滤的危险属性模式 $dangerousAttributesPatterns = [ '/on\w+\s*=/i', // 过滤以 "on" 开头的事件属性 '/javascript:[^"]*"/i' // 过滤 JavaScript 协议的链接 ]; // 先过滤 SQL 关键字 $filteredText = preg_replace($sqlPatterns, '', $text); // 再过滤函数 $filteredText = preg_replace($functionPatterns, '', $filteredText); // 然后过滤特殊字符和表达式 $filteredText = preg_replace($specialPatterns, '', $filteredText); // 接着过滤危险的属性 $filteredText = preg_replace($dangerousAttributesPatterns, '', $filteredText); // 处理可能出现的连续空格 $filteredText = preg_replace('/\s+/', ' ', $filteredText); // 去除前后的空格 $filteredText = trim($filteredText); // 转换 HTML 实体 $filteredText = htmlentities($filteredText, ENT_QUOTES, 'UTF-8'); return $filteredText; }
2025年03月13日
7 阅读
0 评论
0 点赞
2025-03-13
【PHP】获取二维数组里面最小的值
/** * @Author:小破孩 * @Email:3584685883@qq.com * @Time:2024/12/5 17:16 * @param $array * @return array * @Description:获取一个二维数组,数据最小的,并返回对应的key和value */ public function getMinValueKey($array) { $minValue = PHP_INT_MAX; $desiredKey = null; foreach ($array as $key => $subArray) { foreach ($subArray as $subKey => $value) { if ($value < $minValue) { $minValue = $value; $desiredKey = $subKey; } } } return [$desiredKey, $minValue]; } //使用场景 $inatanceMap = new \app\common\lib\map\baidu\Lnglat($this->param['ac_address']); $lnglat = $inatanceMap->addressToLngLat(); $this->param['u_lng'] = $lnglat['lng'];//经度 $this->param['u_lat'] = $lnglat['lat'];//纬度 $companyList = M("AdminCompany")::getCompanyListUseSelect(); $instanceDis = new \app\common\lib\map\Distance(); foreach ($companyList as $key => $val){ $arrAddress[$key][$val['ac_uuid']] = $instanceDis->getdistance($val['ac_lng'],$val['ac_lat'],$lnglat['lng'],$lnglat['lat']); } $instanceArr = new \app\common\lib\data\Arr(); list($minKey, $minValue) = $instanceArr->getMinValueKey($arrAddress); $this->param['u_company_uuid'] = $minKey; $this->param['u_address'] = $this->param['ac_address'];
2025年03月13日
7 阅读
0 评论
0 点赞
2025-03-13
【PHP】按照个商品金额,等比例分配优惠劵
/** * @Author:小破孩 * @Email:3584685883@qq.com * @Time:2024/11/23 11:41 * @param $products ['id' => 'price','id' => price] * @param $totalCouponAmount 优惠劵优惠金额 * @return array * @Description:按照商品比例拆分优惠劵,分配给对应的商品 */ public function getSplitCoupon($products, $totalCouponAmount) { $totalAmount = array_sum($products); $discounts = []; $allocatedDiscount = 0; foreach ($products as $id => $amount) { $ratio = $amount / $totalAmount; $discount = $ratio * $totalCouponAmount; $roundedDiscount = round($discount, 2); $discounts[$id] = $roundedDiscount; $allocatedDiscount += $roundedDiscount; } // 调整以使总和为指定的优惠券总额 $diff = $totalCouponAmount - $allocatedDiscount; if ($diff!= 0) { $sortedDiscounts = $discounts; arsort($sortedDiscounts); $i = 0; foreach ($sortedDiscounts as $id => $discount) { if ($i < abs($diff)) { $discounts[$id] += ($diff > 0)? 0.01 : -0.01; } $i++; } } return $discounts; }
2025年03月13日
5 阅读
0 评论
0 点赞
2024-10-26
【ThinkPHP】最新版本上传文件的类
<?php namespace app\common\lib\file; use think\Exception; use think\exception\ValidateException; class Uploads { private $domain; protected $name; protected $type; protected $module; protected $image; public function __construct($name = '',$image = []) { $this->name = $name; $this->module = app('http')->getName(); $this->image = $image; $this->domain = Request()->domain(); } protected $config = [ 'image' => [ 'validate' => [ 'size' => 10*1024*1024, 'ext' => 'jpg,png,gif,jpeg', ], 'path' => '/images', ], 'audio' => [ 'validate' => [ 'size' => 100*1024*1024, 'ext' => 'mp3,wav,cd,ogg,wma,asf,rm,real,ape,midi', ], 'path' => '/audios', ], 'video' => [ 'validate' => [ 'size' => 100*1024*1024, 'ext' => 'mp4,avi,rmvb,rm,mpg,mpeg,wmv,mkv,flv', ], 'path' => '/videos', ], 'file' => [ 'validate' => [ 'size' => 5*1024*1024, 'ext' => 'doc,docx,xls,xlsx,pdf,ppt,pptx,txt,rar,zip,pem,p12', ], 'path' => '/files', ], ]; private function determineFileType($file) { $mime = $file->getMime(); if (strpos($mime, 'image/') === 0) { $this->type = 'image'; } elseif (strpos($mime, 'video/') === 0) { $this->type = 'video'; } elseif (strpos($mime, 'audio/') === 0) { $this->type = 'audio'; } else { $this->type = 'file'; } if (!in_array($this->type, array_keys($this->config))) { throw new ValidateException("the file type does not exist"); } validate(['file' => self::validateFile()])->check(['file' => $file]); } public function upfile($infoSwitch = false,$savelocal = 'local'){ try{ $file = request()->file($this->name); //检测文件 if($file == null) throw new ValidateException("the file cannot be empty"); //验证文件 $this->determineFileType($file); //上传文件 switch ($savelocal){ case 'aliyun': $savename = \think\facade\Filesystem::disk('aliyun')->putFile( $this->module.$this->config[$this->type]['path'], $file); break; case 'qiniu': $savename = \think\facade\Filesystem::disk('qiniu')->putFile( $this->module.$this->config[$this->type]['path'], $file); break; case 'qcloud': $savename = \think\facade\Filesystem::disk('qcloud')->putFile( $this->module.$this->config[$this->type]['path'], $file); break; case 'local': $savename = \think\facade\Filesystem::disk('public')->putFile( $this->module.$this->config[$this->type]['path'], $file); break; default : $savename = \think\facade\Filesystem::disk('public')->putFile( $this->module.$this->config[$this->type]['path'], $file); break; } // $savename = \think\facade\Filesystem::disk('public')->putFile( $this->module.$this->config[$this->type]['path'], $file); // $savename = \think\facade\Filesystem::disk('aliyun')->putFile( 'topic', $file); //返回文件详情和文件地址 if($infoSwitch){ return self::getFileInfo($file,$savename); } return $this->domain.config('filesystem.disks.public.url').'/'.str_replace('\\','/',$savename); }catch (\think\exception\ValidateException $e){ return show(100,self::languageChange($e->getMessage())); } } private function validateFile(){ if(empty($this->image)){ $validataType = [ 'fileSize' => $this->config[$this->type]['validate']['size'], 'fileExt' => $this->config[$this->type]['validate']['ext'], ]; }else{ if(is_array($this->image)) throw new ValidateException(""); $validataType = [ 'fileSize' => $this->config[$this->type]['validate']['size'], 'fileExt' => $this->config[$this->type]['validate']['ext'], 'image' => $this->image //示例值 [200,200] ]; } return $validataType; } private function languageChange($msg){ $data = [ 'the file type does not exist' => '文件类型不存在!', 'the file cannot be empty' => '文件不能为空!', 'unknown upload error' => '未知上传错误!', 'file write error' => '文件写入失败!', 'upload temp dir not found' => '找不到临时文件夹!', 'no file to uploaded' => '没有文件被上传!', 'only the portion of file is uploaded' => '文件只有部分被上传!', 'upload File size exceeds the maximum value' => '上传文件大小超过了最大值!', 'upload write error' => '文件上传保存错误!', ]; return $data[$msg] ?? $msg; } private function getFileInfo($file,$savename){ $info = [ 'path' => config('filesystem.disks.public.url').'/'.str_replace('\\','/',$savename), 'url' => $this->domain.config('filesystem.disks.public.url').'/'.str_replace('\\','/',$savename), 'size' => $file->getSize(), 'name' => $file->getOriginalName(), 'mime' => $file->getMime(), 'ext' => $file->extension(), 'type' => $this->type ]; return $info; } public function __clone() { throw new Exception("Cloning operation is not allowed"); // TODO: Implement __clone() method. } // 使用方法 : // $instanceUpload = new Uploads($fileName); // $info = $instanceUpload->upfile(true); } 如果要用建议封装一下,使用interface定义个规范,这里更像一个方法函数
2024年10月26日
54 阅读
0 评论
0 点赞
2024-06-23
【PHP】H5微信网页自定义分享功能实现
<?php namespace app\index\lib\wechat; header("Access-Control-Allow-Origin:*"); class share { public $appid; public $secret; // 步骤1.appid和secret //header("Access-Control-Allow-Origin:*"); //$appid = "appid"; //$secret = "secret"; public function __construct($appid,$secret) { $this->appid = $appid; $this->secret = $secret; } // 步骤2.生成签名的随机串 public function nonceStr($length){ $str = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJK1NGJBQRSTUVWXYZ';//随即串,62个字符 $strlen = 62; while($length > $strlen){ $str .= $str; $strlen += 62; } $str = str_shuffle($str); return substr($str,0,$length); } // 步骤3.获取access_token public function http_get($url){ $oCurl = curl_init(); if(stripos($url,"https://")!==FALSE){ curl_setopt($oCurl, CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt($oCurl, CURLOPT_SSL_VERIFYHOST, FALSE); curl_setopt($oCurl, CURLOPT_SSLVERSION, 1); //CURL_SSLVERSION_TLSv1 } curl_setopt($oCurl, CURLOPT_URL, $url); curl_setopt($oCurl, CURLOPT_RETURNTRANSFER, 1 ); $sContent = curl_exec($oCurl); $aStatus = curl_getinfo($oCurl); curl_close($oCurl); if(intval($aStatus["http_code"])==200){ return $sContent; }else{ return false; } } // 步骤4.获取ticket public function getTicket(){ $result = $this->http_get('https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid='.$this->appid.'&secret='.$this->secret); $json = json_decode($result,true); $access_token = $json['access_token']; $url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=jsapi&access_token=$access_token"; $res = json_decode ( $this->http_get ( $url ) ); return $res->ticket; } // 步骤5.生成wx.config需要的参数 //$surl = 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']; //$ws = getWxConfig( $ticket,$surl,time(),nonceStr(16) ); // public function getWxConfig($jsapiTicket,$url,$timestamp,$nonceStr) { public function getWxConfig() { $jsapiTicket=$this->getTicket(); $url = 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']; $timestamp = time(); $nonceStr = $this->nonceStr(rand(8,15)); $string = "jsapi_ticket=".$jsapiTicket."&noncestr=".$nonceStr."×tamp=".$timestamp."&url=".$url; $signature = sha1 ($string); $WxConfig["appId"] = $this->appid; $WxConfig["nonceStr"] = $nonceStr; $WxConfig["timestamp"] = $timestamp; $WxConfig["url"] = $url; $WxConfig["signature"] = $signature; $WxConfig["rawString"] = $string; return $WxConfig; } } public function getWxShareConfig(){ $instanceWxShare = new \app\index\lib\wechat\share('appid','secret'); return $instanceWxShare->getWxConfig(); } <script src="https://res.wx.qq.com/open/js/jweixin-1.6.0.js"></script> <script> // console.log(timestamp); wx.config({ debug: false, appId: '{$wxsc.appId}', timestamp: '{$wxsc.timestamp}', nonceStr: '{$wxsc.nonceStr}', signature: '{$wxsc.signature}', jsApiList: ['updateAppMessageShareData','updateTimelineShareData'] }); wx.ready(function () { //需在用户可能点击分享按钮前就先调用 wx.updateAppMessageShareData({ title: '医博:', // 分享标题 desc: '专业肛肠、胃肠、中医交流平台,为业界名专家们搭建教学、学术平台,为专业医生提供手术直播、科普交流基地,为学者提供学习、沟通、上升平台。', // 分享描述 link: 'https://wx.kmyebo.com', // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致 imgUrl: 'https://wx.kmyebo.com/yb_share_icon.jpg', // 分享图标 success: function () { // 设置成功 } }) }); wx.ready(function () { //需在用户可能点击分享按钮前就先调用 wx.updateTimelineShareData({ title: '医博:', // 分享标题 link: 'https://wx.kmyebo.com', // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致 imgUrl: 'https://wx.kmyebo.com', // 分享图标 success: function () { // 设置成功 } }) }); </script>http://www.xmyfw.com.cn/pc/show.php?id=55
2024年06月23日
103 阅读
0 评论
0 点赞
2023-07-10
【PHP】基于thinkPHP使用easywechat发送统一下发消息
好的,您可以按照以下步骤使用thinkPHP和easywechat发送下发统一消息:首先,确保您已经安装了thinkPHP和easywechat。您可以使用Composer来安装它们:composer require topthink/thinkcomposer require overtrue/wechat在thinkPHP项目中创建一个控制器(例如MessageController),并在其中添加一个方法(例如sendUnifiedMessage)来处理发送下发统一消息的逻辑。<?php namespace app\controller; use think\Controller; use EasyWeChat\Factory; class MessageController extends Controller { public function sendUnifiedMessage() { // 创建 EasyWeChat 实例 $config = [ 'app_id' => 'your_app_id', 'secret' => 'your_app_secret', // 其他配置项... ]; $app = Factory::officialAccount($config); // 发送下发统一消息 $result = $app->broadcasting->send([ 'touser' => 'openid1,openid2', // 接收消息的用户openid列表 'msgtype' => 'text', 'text' => [ 'content' => '这是一条测试消息' ] ]); // 处理发送结果 if ($result['errcode'] === 0) { return '消息发送成功'; } else { return '消息发送失败:' . $result['errmsg']; } } } 请注意,上述代码中的your_app_id和your_app_secret应替换为您自己的微信公众号的AppID和AppSecret。在路由中定义一个访问该方法的路由。您可以在route/route.php文件中添加以下代码:<?php use think\facade\Route; Route::get('message/send', 'MessageController/sendUnifiedMessage'); 现在,您可以通过访问/message/send来触发发送下发统一消息的逻辑。请注意,上述代码仅为示例,您可能需要根据您的实际需求进行修改和调整。另外,确保您已正确配置微信公众号的相关信息,并且您的服务器能够正常访问到微信服务器。
2023年07月10日
128 阅读
0 评论
0 点赞
2022-12-26
【ThinkPHP】ThinkPHP6处理接口版本问题
'domain_bind' => [ 'api' => 'api', // blog子域名绑定到blog应用 'admin.tp.com' => 'admin', // 完整域名绑定 '*' => 'home', // 二级泛域名绑定到home应用 ], // url版本路由,在url地址上带版本号 Route::rule(':version/:controller/:function', ':version.:controller/:function') ->allowCrossDomain([ 'Access-Control-Allow-Origin' => '*', // //解决跨域问题 'Access-Control-Allow-Methods' => '*', 'Access-Control-Allow-Headers' => '*', 'Access-Control-Request-Headers' => '*' ]); // 头部模式(请求头部带版本号) $version = request()->header('version'); //默认跳转到v1版本 if ($version == null) $version = "v1"; Route::rule(':controller/:function', $version . '.:controller/:function');
2022年12月26日
185 阅读
0 评论
0 点赞
2022-11-03
【ThinkPHP】tp6获取应用名
protected $filter = ['htmlspecialchars']; public function app_name() { return App('http')->getName(); }
2022年11月03日
226 阅读
0 评论
0 点赞
2022-08-16
【PHP】PHPEmail的使用
第一步:使用composer安装phpmailercomposer require phpmailer/phpmailer第二步:common.php写个发送邮件的函数(腾讯邮箱的为例)/** * 系统邮件发送函数 * @param string $tomail 接收邮件者邮箱 * @param string $name 接收邮件者名称 * @param string $subject 邮件主题 * @param string $body 邮件内容 * @param string $attachment 附件列表 * @return boolean * @author static7 <static7@qq.com> */ function send_mail($tomail, $name, $subject = '', $body = '', $attachment = null) { $mail = new \PHPMailer(); //实例化PHPMailer对象 $mail->CharSet = 'UTF-8'; //设定邮件编码,默认ISO-8859-1,如果发中文此项必须设置,否则乱码 $mail->IsSMTP(); // 设定使用SMTP服务 $mail->SMTPDebug = 0; // SMTP调试功能 0=关闭 1 = 错误和消息 2 = 消息 $mail->SMTPAuth = true; // 启用 SMTP 验证功能 $mail->SMTPSecure = 'ssl'; // 使用安全协议 $mail->Host = "smtp.exmail.qq.com"; // SMTP 服务器 $mail->Port = 465; // SMTP服务器的端口号 $mail->Username = "static7@qq.com"; // SMTP服务器用户名 $mail->Password = ""; // SMTP服务器密码 $mail->SetFrom('static7@qq.com', 'static7'); $replyEmail = ''; //留空则为发件人EMAIL $replyName = ''; //回复名称(留空则为发件人名称) $mail->AddReplyTo($replyEmail, $replyName); $mail->Subject = $subject; $mail->MsgHTML($body); $mail->AddAddress($tomail, $name); if (is_array($attachment)) { // 添加附件 foreach ($attachment as $file) { is_file($file) && $mail->AddAttachment($file); } } return $mail->Send() ? true : $mail->ErrorInfo; }第三步:控制器方法里写发送的内容/** * tp5邮件 * @param * @author staitc7 <static7@qq.com> * @return mixed */ public function email() { $toemail='static7@qq.com'; $name='static7'; $subject='QQ邮件发送测试'; $content='恭喜你,邮件测试成功。'; dump(send_mail($toemail,$name,$subject,$content)); }第4步:测试发送请自行测试转发:https://www.thinkphp.cn/topic/44477.html
2022年08月16日
244 阅读
0 评论
0 点赞
2022-06-27
【PHP】TP6.0验证码接口
安装验证码扩展:composer require topthink/think-captcha创建验证码接口: public function setYzm(){ $captcha_img = Captcha_src(); $src = $_SERVER['REQUEST_SCHEME'].'://'.$_SERVER['SERVER_NAME'].'/api'.captcha_src(); ob_clean(); //清除缓冲区,防止出现“图像因其本身有错无法显示'的问题 $type = getimagesize($src)['mime']; //获取图片类型 header("Content-Type:{$type}"); $imgData = file_get_contents($src); //获取图片二进制流 $base64String = 'data:' . $type . ';base64,' . base64_encode($imgData); return show(200,'请求成功',$base64String); } 可以不用base64处理直接返回验证码地址 public function checkYzm($yzm){ if(!Captcha::checkApi($yzm)) throw new Exception('验证码验证失败~'); return true; }修改底层配置路径:vendor/topthink/think-captcha/src/Captcha.php/** * 创建验证码 * @return array * @throws Exception */ protected function generate(): array { $bag = ''; if ($this->math) { $this->useZh = false; $this->length = 5; $x = random_int(10, 30); $y = random_int(1, 9); $bag = "{$x} + {$y} = "; $key = $x + $y; $key .= ''; } else { if ($this->useZh) { $characters = preg_split('/(?<!^)(?!$)/u', $this->zhSet); } else { $characters = str_split($this->codeSet); } for ($i = 0; $i < $this->length; $i++) { $bag .= $characters[rand(0, count($characters) - 1)]; } $key = mb_strtolower($bag, 'UTF-8'); } $hash = password_hash($key, PASSWORD_BCRYPT, ['cost' => 10]); $this->session->set('captcha', [ 'key' => $hash, ]); //加上这行代码,便于后续校验验证码 if(empty(cache($key))){ cache($key, $hash, 5*60); }else{ return $this->generate(); } //加上这行代码,便于后续校验验证码 return [ 'value' => $bag, 'key' => $hash, ]; } /** * 验证验证码是否正确 * @access public * @param string $code 用户验证码 * @return bool 用户验证码是否正确 */ public function checkApi(string $code): bool { if (!cache($code)) { return false; } $key = cache($code); $code = mb_strtolower($code, 'UTF-8'); $res = password_verify($code, $key); if ($res) { cache($code,NULL); } return $res; }
2022年06月27日
242 阅读
0 评论
0 点赞
2022-06-23
【PHP】ThinkPHP6 公共 上传到本地的方法 附带使用方法
<?php namespace app\common\lib\files; use think\Exception; use think\exception\ValidateException; class upload { private $domain; protected $name; protected $type; protected $module; protected $image; public function __construct($name = '',$type = 'image',$image = []) { $this->name = $name; $this->type = $this->checkUpload($type); $this->module = request()->app_name(); $this->image = $image; $this->domain = Request()->domain(); } protected $config = [ 'image' => [ 'validate' => [ 'size' => 10*1024*1024, 'ext' => 'jpg,png,gif,jpeg', ], 'path' => '/images', ], 'audio' => [ 'validate' => [ 'size' => 100*1024*1024, 'ext' => 'mp3,wav,cd,ogg,wma,asf,rm,real,ape,midi', ], 'path' => '/audios', ], 'video' => [ 'validate' => [ 'size' => 100*1024*1024, 'ext' => 'mp4,avi,rmvb,rm,mpg,mpeg,wmv,mkv,flv', ], 'path' => '/videos', ], 'file' => [ 'validate' => [ 'size' => 5*1024*1024, 'ext' => 'doc,docx,xls,xlsx,pdf,ppt,txt,rar,zip,pem,p12', ], 'path' => '/files', ], ]; private function checkUpload($type){ try{ if(empty($_FILES) || empty($_FILES[$this->name])) throw new Exception("未上传文件!"); if(!in_array($type,array_keys($this->config))) throw new Exception("文件类型不存在!"); return $type; }catch (Exception $e){ return \app\common\controller\Base::show(100,$e->getMessage()); } } public function upfile($infoSwitch = false){ $file = request()->file($this->name); try{ if($file == null) throw new ValidateException("the file cannot be empty"); validate(['file' => self::validateFile()])->check(['file' => $file]); $savename = \think\facade\Filesystem::disk('public')->putFile( $this->module.$this->config[$this->type]['path'], $file); if($infoSwitch){ return self::getFileInfo($file,$savename); } return $savename; }catch (\think\exception\ValidateException $e){ return \app\common\controller\Base::show(100,self::languageChange($e->getMessage())); } } private function validateFile(){ if(empty($this->image)){ $validataType = [ 'fileSize' => $this->config[$this->type]['validate']['size'], 'fileExt' => $this->config[$this->type]['validate']['ext'], ]; }else{ if(is_array($this->image)) throw new ValidateException(""); $validataType = [ 'fileSize' => $this->config[$this->type]['validate']['size'], 'fileExt' => $this->config[$this->type]['validate']['ext'], 'image' => $this->image //示例值 [200,200] ]; } return $validataType; } private function languageChange($msg){ $data = [ 'the file cannot be empty' => '文件不能为空!', 'unknown upload error' => '未知上传错误!', 'file write error' => '文件写入失败!', 'upload temp dir not found' => '找不到临时文件夹!', 'no file to uploaded' => '没有文件被上传!', 'only the portion of file is uploaded' => '文件只有部分被上传!', 'upload File size exceeds the maximum value' => '上传文件大小超过了最大值!', 'upload write error' => '文件上传保存错误!', ]; return $data[$msg] ?? $msg; } private function getFileInfo($file,$savename){ $info = [ 'path' => config('filesystem.disks.public.url').'/'.str_replace('\\','/',$savename), 'url' => $this->domain.config('filesystem.disks.public.url').'/'.str_replace('\\','/',$savename), 'size' => $file->getSize(), 'name' => $file->getOriginalName(), 'mime' => $file->getMime(), 'ext' => $file->extension() ]; return $info; } } > 使用方法 : > > $instanceUpload = new upload($fileName,$fileType); > $info = $instanceUpload->upfile(true);
2022年06月23日
145 阅读
0 评论
0 点赞
2022-06-23
【PHP】ThinkPHP 5.1公共上传类
<?php namespace app\extra; /* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ //适配移动设备图片上传 use think\Exception; use think\facade\Request; class ExtraUpload{ /** * 默认上传配置 * @var array */ private $config = [ 'image' => [ 'validate' => [ 'size' => 10*1024*1024, 'ext' => 'jpg,png,gif,jpeg', ], 'rootPath' => './Uploads/images/', //保存根路径 ], 'audio' => [ 'validate' => [ 'size' => 100*1024*1024, 'ext' => 'mp3,wav,cd,ogg,wma,asf,rm,real,ape,midi', ], 'rootPath' => './Uploads/audios/', //保存根路径 ], 'video' => [ 'validate' => [ 'size' => 100*1024*1024, 'ext' => 'mp4,avi,rmvb,rm,mpg,mpeg,wmv,mkv,flv', ], 'rootPath' => './Uploads/videos/', //保存根路径 ], 'file' => [ 'validate' => [ 'size' => 5*1024*1024, 'ext' => 'doc,docx,xls,xlsx,pdf,ppt,txt,rar', ], 'rootPath' => './Uploads/files/', //保存根路径 ], ]; private $domain; function __construct() { //获取当前域名 $this->domain = Request::instance()->domain(); } public function upload($fileName){ if(empty($_FILES) || empty($_FILES[$fileName])){ // return ''; returnResponse(100,'文件为空'); } try{ $file = request()->file($fileName); if (is_array($file)){ $path = []; foreach ($file as $item){ $path[] = $this->save($item); } } else { $path = $this->save($file); } return $path; } catch (\Exception $e){ $arr = [ 'status' => 0, 'message' => $e->getMessage(), ]; header('Content-Type: application/json; charset=UTF-8'); exit(json_encode($arr)); } } public function uploadDetail($fileName){ if(empty($_FILES) || empty($_FILES[$fileName])){ // return []; returnResponse(100,'文件为空'); } try{ $file = request()->file($fileName); if (is_array($file)){ $path = []; foreach ($file as $item){ $detail = $item->getInfo(); $returnData['name'] = $detail['name']; $returnData['type'] = $detail['type']; $returnData['size'] = $detail['size']; $returnData['filePath'] = $this->save($item); $returnData['fullPath'] = $this->domain.$returnData['filePath']; $path[] = $returnData; } } else { $detail = $file->getInfo(); $returnData['name'] = $detail['name']; $returnData['type'] = $detail['type']; $returnData['size'] = $detail['size']; $returnData['filePath'] = $this->save($file); $returnData['fullPath'] = $this->domain.$returnData['filePath']; $path = $returnData; } return $path; } catch (\Exception $e){ $arr = [ 'status' => 0, 'message' => $e->getMessage(), ]; header('Content-Type: application/json; charset=UTF-8'); exit(json_encode($arr)); } } private function getConfig($file){ $name = pathinfo($file['name']); $end = $name['extension']; foreach ($this->config as $key=>$item){ if ($item['validate']['ext'] && strpos($item['validate']['ext'], $end) !== false){ return $this->config[$key]; } } return null; } private function save(&$file){ $config = $this->getConfig($file->getInfo()); if (empty($config)){ throw new Exception('上传文件类型不被允许!'); } // 移动到框架应用根目录/uploads/ 目录下 if ($config['validate']) { $file->validate($config['validate']); $result = $file->move($config['rootPath']); } else { $result = $file->move($config['rootPath']); } if($result){ $path = $config['rootPath']; if (strstr($path,'.') !== false){ $path = str_replace('.', '', $path); } return $path.$result->getSaveName(); }else{ // 上传失败获取错误信息 throw new Exception($file->getError()); } } } 使用方法: $p = new \app\extra\ExtraUpload(); return $p->uploadDetail('file');
2022年06月23日
256 阅读
0 评论
0 点赞
2022-06-23
【PHP】thinkphp5.1清除缓存 包括缓存日志 编译文件
/** * 清除缓存 */ public function clearCache(){ \think\facade\Cache::clear(); return ZHTReturn('清除成功',1); } /** * 清除模版缓存但不删除temp目录 */ public function clearTemp() { $path = env('RUNTIME_PATH'); // $path = env(); // dump($path); // die; array_map('unlink',glob($path.'temp\*.php')); return ZHTReturn('清除成功',1); } /** * 清除日志缓存并删出log空目录 */ public function clearLog() { $path = env('RUNTIME_PATH'); $path_log = glob($path.'log\*'); foreach ($path_log as $val) { array_map('unlink', glob($val . '\*.log')); rmdir($val); } return ZHTReturn('清除成功',1); } /** * 清除所有缓存 */ public function clearAll() { \think\facade\Cache::clear(); $path = env('RUNTIME_PATH'); array_map('unlink',glob($path.'temp\*.php')); $path_log = glob($path.'log\*'); foreach ($path_log as $val) { array_map('unlink', glob($val . '\*.log')); rmdir($val); } return ZHTReturn('清除成功',1); }
2022年06月23日
189 阅读
0 评论
0 点赞
2022-06-23
【PHP】TP6分页
->paginate(['list_rows'=>$page, 'query'=>request()->param()], false)
2022年06月23日
224 阅读
0 评论
0 点赞
2022-06-23
【PHP】TP6 initialize方法里面重定向
class MyBase extends BaseController { public function initialize() { parent::initialize(); // TODO: Change the autogenerated stub if(input('is_intercept') == true){ return $this->redirect('http://www.slong.ink', 302); } } // 重定向 public function redirect(...$arg) { throw new \think\exception\HttpResponseException(redirect(...$arg)); } }
2022年06月23日
160 阅读
0 评论
0 点赞
2022-06-23
【PHP】 使用PHPoffice实现普通的导出功能(二)
第二版 使用PHPoffice实现普通的导出功能<?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{ private $sheet_filename; private $sheet_name; private $sheet_firstline = []; private $sheet_info = []; private $imgSwitch; private $switch; private $path = "uploads/excel/"; /** * Importsheet constructor. * @param $filename 文件名 * @param $name sheet名 * @param $firstline 表头 * @param $info 表内容 * @param $imgSwitch 图片开关 * @param $switch 返回下载地址还是直接返回文件 */ public function __construct($filename='Default',$name='sheet1',$firstline = [],$info = [],$imgSwitch = false, $switch = false) { parent::__construct(); $this->sheet_filename = $filename; $this->sheet_name = $name; $this->sheet_firstline = $firstline; $this->sheet_info = $info; $this->imgSwitch = $imgSwitch; $this->switch = $switch; } /** * @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){ if($column_num > $info_field_num){ $better_column_info = '表头多'; }else{ $better_column_info = '数据列多'; } throw new Exception('结果集列数和表头列数不一致~'.$better_column_info); } //生成表头上方的字母(最大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); if($this->imgSwitch){ /*写入图片*/ $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)){ $str_thumb = str_replace($this->request->domain(),'',$getvalbykey[$b]); $thumb = '/home/wwwroot/xphbk/public'.$str_thumb; if($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++; } }else{ $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'); if($this->switch == false){ $path = self::createPath($this->path); $writer->save($path.$file_name); // $url = 'http://'.$_SERVER['SERVER_NAME'].'/public/'.$path.$filename; $url = 'http://'.$_SERVER['SERVER_NAME'].'/'.$path.$file_name; }else{ return $writer->save('php://output'); } return $url; }catch (Exception $e){ returnResponse(100,$e->getMessage()); } } /** * @Author: 小破孩嫩 * @Email: 3584685883@qq.com * @Time: 2021/4/12 13:36 * @param $path * @Description:设置路径判断是否存在,不存在创建 */ private function createPath($path){ $Month = date('Ym',time()); $Day = date('d',time()); $path = $this->path.$Month.'/'.$Day.'/'; if(!is_dir($path)){ header("Content-type:text/html;charset=utf-8"); $res = mkdir(iconv("UTF-8", "GBK", $path),0777,true); if(!$res){ throw new Exception("创建目录失败"); } } return $path; } }使用图片导出的时候注意限制条数,图片导出比较费时间,在我自己的项目中,每次导出大概有五百条数据,是没有问题,具体的还要各位使用者再测使用方法:复制粘贴+稍微改改,就能用了
2022年06月23日
187 阅读
0 评论
0 点赞
1
2