$elementsToAdd, 'delete' => $elementsToDelete ); } /** * 取多维数组中的一列作为键,另外一列作为值(如省略,则将整行作为值),转换为键值数组 * @param array $result 多维数组 * @param string $kk 要作为键名的列名 * @param string $vk 要作为键值的列名 * @return array 键值数组 */ public static function array_point($result, $kk = 'id', $vk = NULL) { $array = array(); foreach ($result as $row) { if ($vk) { $array[$row[$kk]] = $row[$vk]; } else { $array[$row[$kk]] = $row; } } return $array; } // 检查是否大于四位汉字 public static function checkChineseChars($str) { // 使用 mb_strlen 函数获取字符串长度(考虑到多字节字符) $length = mb_strlen($str, 'utf-8'); // 使用正则表达式匹配汉字,并计算匹配到的数量 preg_match_all('/[\x{4e00}-\x{9fa5}]/u', $str, $matches); $chineseCharsCount = count($matches[0]); // 返回汉字数量是否大于四 return $chineseCharsCount < 4; } //检测表情 public static function haveEmojiChar($str) { $mbLen = mb_strlen($str); $strArr = []; for ($i = 0; $i < $mbLen; $i++) { $strArr[] = mb_substr($str, $i, 1, 'utf-8'); if (strlen($strArr[$i]) >= 4) { return true; } } return false; } //移除表情 public static function removeEmojiChar($str) { $mbLen = mb_strlen($str); $strArr = []; for ($i = 0; $i < $mbLen; $i++) { $mbSubstr = mb_substr($str, $i, 1, 'utf-8'); if (strlen($mbSubstr) >= 4) { continue; } $strArr[] = $mbSubstr; } return implode('', $strArr); } //匹配除标准ASCII字符之外的字符 public static function containsSpecialCharacters($str) { return preg_match('/[^\x20-\x7E]/', $str); } // 图片压缩 function compressImage($file, $destPath = '', $maxWidth = 800, $maxHeight = 600, $maxFileSize = 2 * 1024 * 1024) { // 获取图片文件信息 $fileSize = $file->getSize(); $fileType = $file->getMimeType(); $tmpFilePath = $file->getPathname(); // 如果文件大小小于最大文件大小,直接保存 if ($fileSize <= $maxFileSize) { return 0; } // 创建图像对象 $sourceImage = null; // 根据图像类型创建图像对象 if ($fileType == 'image/jpeg' || $fileType == 'image/pjpeg') { $sourceImage = imagecreatefromjpeg($tmpFilePath); } elseif ($fileType == 'image/png') { $sourceImage = imagecreatefrompng($tmpFilePath); } elseif ($fileType == 'image/gif') { $sourceImage = imagecreatefromgif($tmpFilePath); } if ($sourceImage === null) { return 2; } // 获取源图片的宽度和高度 $sourceWidth = imagesx($sourceImage); $sourceHeight = imagesy($sourceImage); // 计算等比例压缩后的宽度和高度 $aspectRatio = $sourceWidth / $sourceHeight; if ($maxWidth / $maxHeight > $aspectRatio) { $destHeight = $maxHeight; $destWidth = $maxHeight * $aspectRatio; } else { $destWidth = $maxWidth; $destHeight = $maxWidth / $aspectRatio; } // 创建目标图片对象 $destImage = imagecreatetruecolor($destWidth, $destHeight); // 保持 PNG 和 GIF 的透明度 if ($fileType == 'image/png' || $fileType == 'image/gif') { imagecolortransparent($destImage, imagecolorallocatealpha($destImage, 0, 0, 0, 127)); imagealphablending($destImage, false); imagesavealpha($destImage, true); } // 进行图片压缩和重采样 imagecopyresampled($destImage, $sourceImage, 0, 0, 0, 0, $destWidth, $destHeight, $sourceWidth, $sourceHeight); // 尝试不同的压缩质量,直到图片大小小于 2MB $quality = 90; do { ob_start(); // 开启输出缓冲区 imagejpeg($destImage, null, $quality); $compressedImageData = ob_get_contents(); ob_end_clean(); // 清空输出缓冲区 $compressedFileSize = strlen($compressedImageData); $quality -= 10; } while ($compressedFileSize > $maxFileSize && $quality > 10); // 保存最终压缩的图片 file_put_contents(public_path() . '/' . $destPath, $compressedImageData); // 释放内存 imagedestroy($sourceImage); imagedestroy($destImage); // return [ // 'message' => '图片压缩成功', // 'size' => round($compressedFileSize / 1024, 2) . ' KB', // 'path' => $destPath // ]; return 1; } // 数据加密 public static function encryptData($data) { return Crypt::encrypt($data); } // 数据解密 public static function decryptData($data) { return Crypt::decrypt($data); } // 自然流 合伙人id public static function natureId() { return 1; // return 832; } // 生成32位随机字符串 public static function uuid4() { return str_replace('-', '', Uuid::uuid4()->toString()); //唯一随机值 } // 生成随机码 public static function generateRandomString($length = 6) { $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; $charactersLength = strlen($characters); $randomString = ''; for ($i = 0; $i < $length; $i++) { $randomString .= $characters[rand(0, $charactersLength - 1)]; } return $randomString; } // 生成RSA密钥对 public static function generateRSAKeys() { // 设置密钥配置 $config = [ "private_key_bits" => 2048, // RSA-2048 密钥长度 "private_key_type" => OPENSSL_KEYTYPE_RSA, ]; // 生成密钥对 $res = openssl_pkey_new($config); // 从密钥对中提取私钥 openssl_pkey_export($res, $privateKey); // 从密钥对中提取公钥 $details = openssl_pkey_get_details($res); $publicKey = $details["key"]; // 去除私钥中的标识符 $privateKey = preg_replace('/-----BEGIN (.*)-----(.*)-----END (.*)-----/s', '$2', $privateKey); $privateKey = str_replace(["\r", "\n"], '', $privateKey); // 去除公钥中的标识符 $publicKey = preg_replace('/-----BEGIN (.*)-----(.*)-----END (.*)-----/s', '$2', $publicKey); $publicKey = str_replace(["\r", "\n"], '', $publicKey); // 返回公钥和私钥 return [ "privateKey" => $privateKey, "publicKey" => $publicKey, ]; } // RSA解密 public static function rsaDecrypt($encryptedData = null) { if (empty($encryptedData)) { return false; } $private = env('RSA_PRIVATE_KEY'); // 解密数据 openssl_private_decrypt(base64_decode($encryptedData), $decryptedData, $private); return json_decode($decryptedData, true); } // 数据aes rsa解密 public static function aesRsaDecrypt($encryptedData, $encryptedKey, $iv) { if (empty($encryptedData) || empty($encryptedKey) || empty($iv)) { return false; } // 1. 获取私钥 $privateKey = env('RSA_PRIVATE_KEY'); $res = openssl_private_decrypt(base64_decode($encryptedKey), $symmetricKey, $privateKey); // 2. 用 RSA 私钥解密对称密钥 if ($res) { // 3. 使用对称密钥解密数据 $decryptedData = openssl_decrypt($encryptedData, 'AES-128-CBC', base64_decode($symmetricKey), 0, $iv); $arrData = json_decode($decryptedData, true); // 返回解密后的数据 if (!$arrData) { Log::error("解密失败密文:" . $decryptedData); } return $arrData; } else { return false; } } //腾讯云获取用户ip信息 public static function getIpInfo($ip = null) { $url = "https://apis.map.qq.com/ws/location/v1/ip"; $data = [ 'key' => "", 'ip' => $ip ]; $res = self::sendRequest($url, $data, false); Log::info('腾讯地图ip信息:' . json_encode($res, JSON_UNESCAPED_UNICODE)); if ($res['status'] == 0) { return $res['result']; } else { return false; } } // 判断base64是否合法 public static function isValidBase64($base64, $maxSizeInMB = 3) { // 检查Base64编码字符串的长度是否为4的倍数 if (strlen($base64) % 4 !== 0) { Log::info("Base64异常:检查Base64编码字符串的长度是否为4的倍数"); return false; } // 尝试解码Base64字符串 $decodedData = base64_decode($base64, true); // 检查解码是否成功并且验证是否是有效的Base64字符串 if ($decodedData === false || base64_encode($decodedData) !== $base64) { Log::info("Base64异常:检查解码是否成功并且验证是否是有效的Base64字符串"); return false; } // 计算解码后的数据大小 $imageSizeInBytes = strlen($decodedData); // 将大小转换为MB $imageSizeInMB = $imageSizeInBytes / (1024 * 1024); // 检查图片大小是否超过指定的最大值 if ($imageSizeInMB > $maxSizeInMB) { Log::info("Base64异常:图片尺寸 ".$imageSizeInMB); return false; } // 如果需要获取图片信息,例如尺寸,可以在这里获取 $imageInfo = getimagesizefromstring($decodedData); if ($imageInfo === false) { Log::info("Base64异常:获取图片信息失败"); return false; } // 返回解码后的图片数据 return $decodedData; } // 获取每月一号的日期 public static function generateMonthlyDates($months) { $dates = []; // 获取当前时间 $currentDate = Carbon::now(); // 从下个月的1号开始 $currentDate->addMonth()->startOfMonth()->setTime(0, 0); // 生成每个月1号的日期 for ($i = 0; $i < $months; $i++) { $dates[] = $currentDate->format('Y-m-d H:i:s'); // 移动到下个月的1号 $currentDate->addMonth()->startOfMonth(); } return $dates; } // 下载图片 public static function downloadImage($url, $savePath) { try { // 使用 Guzzle 通过 HTTP 请求下载图片 $response = Http::timeout(10)->get($url); // 设置超时为10秒 // 检查请求是否成功 if ($response->successful()) { // 保存图片到本地 file_put_contents($savePath, $response->body()); return true; } else { return false; } } catch (\Exception $e) { // 捕获错误 Log::info("下载图片失败:" . $e); return false; } } // 打印请求信息 public static function printRequestInfo($request, $msg = "") { Log::info("{$msg}【" . $request->ip() . "】:" . json_encode($request->all())); } /* 函数:remoteFileExists 功能:判断远程文件是否存在 参数: $url_file -远程文件URL 返回:存在返回true,不存在或者其他原因返回false */ public static function remoteFileExists($url) { $curl = curl_init($url); curl_setopt($curl, CURLOPT_NOBODY, true); // 不取回数据 curl_setopt($curl, CURLOPT_TIMEOUT, 10); // 设置超时为10秒 curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 5); // 连接超时5秒 // 发送请求并检查响应码 $result = curl_exec($curl); if ($result !== false) { $statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE); curl_close($curl); return $statusCode == 200; } curl_close($curl); return false; } // 邀请码------------------------------------------ // 检查是否为镜像号 private function isPalindrome($number) { return $number == strrev($number); } // 检查数字是否包含重复次数的字符 private function isRepeating($number, $repeatCount) { $number_str = (string) $number; for ($i = 0; $i <= 10 - $repeatCount; $i++) { if (substr_count($number_str, str_repeat(strval($i), $repeatCount)) > 0) { return true; } } return false; } // 检查是否为顺序号 private function isSequential($number) { $sequences = ['012345', '123456', '234567', '345678', '456789', '567890', '678901', '789012', '890123', '901234']; return in_array($number, $sequences) || in_array(strrev($number), $sequences); } // 检查是否为循环号 private function isCircular($number) { $segments = str_split($number, 2); return count($segments) == 2 && $segments[0] == $segments[1]; } // 检查是否为斜角号 private function isGradient($number) { $diff = (int) $number[1] - (int) $number[0]; for ($i = 1; $i < strlen($number) - 1; $i++) { if ((int)$number[$i + 1] - (int)$number[$i] != $diff) { return false; } } return true; } // 检查是否为好数字 private function isGoodNumber($number) { return $this->isPalindrome($number) || $this->isRepeating($number, 5) || $this->isRepeating($number, 4) || $this->isRepeating($number, 3) || $this->isSequential($number) || $this->isCircular($number) || $this->isGradient($number); } // 获取下一个有效编号 private function getNextCode($current) { do { $currentNumber = (int)substr($current, 1); $currentLetter = $current[0]; $currentNumber++; if ($currentNumber > 99999) { $currentNumber = 0; $currentLetter++; } $numbers = sprintf('%05d', $currentNumber); $current = $currentLetter . $numbers; } while ($this->isGoodNumber($numbers)); return $current; } // 生成并返回下一个有效编号 public function generateNextCode() { $current = Redis::get('current_code') ? Redis::get('current_code') : 'B00000'; $newCode = $this->getNextCode($current); Redis::set('current_code', $newCode); return $newCode; } // 图片圆角 public static function z_image2circle($src, $dst) { //获取原图尺寸,并设置新图片的宽度和高度 list($w, $h) = getimagesize($src); if ($w > $h) { $w = $h; } else { $h = $w; } $oimgSrc = imagecreatefromstring(file_get_contents($src)); $oimgDst = imagecreatetruecolor($w, $h); imagealphablending($oimgDst, false); $transparent = imagecolorallocatealpha($oimgDst, 0, 0, 0, 127); $r = $w / 2; for ($x = 0; $x < $w; $x++) { for ($y = 0; $y < $h; $y++) { $c = imagecolorat($oimgSrc, $x, $y); $_x = $x - $w / 2; $_y = $y - $h / 2; if ((($_x * $_x) + ($_y * $_y)) < ($r * $r)) { imagesetpixel($oimgDst, $x, $y, $c); } else { imagesetpixel($oimgDst, $x, $y, $transparent); } } } imagesavealpha($oimgDst, true); imagepng($oimgDst, $dst); imagedestroy($oimgDst); imagedestroy($oimgSrc); } // 字符串省略 public static function truncateString($string, $length = 30, $ellipsis = '...') { if (mb_strlen($string, 'UTF-8') > $length) { return mb_substr($string, 0, $length, 'UTF-8') . $ellipsis; } else { return $string; } } }