| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388 | <?phpnamespace App\libs\helpers;use app\Auth;use App\libs\cache\redis\Redis;use Illuminate\Support\Facades\Config;use Illuminate\Support\Facades\DB;class Helper{    /**     * @desc    过滤emoji表情     * @param   $str     * @return  null|string|string[]     */    public static function filterEmoji($str)    {        return preg_replace_callback('/./u', function (array $match) {            return strlen($match[0]) >= 4 ? '' : $match[0];        }, $str);    }    /**     * @desc    字节转换     * @param   int $numSize     * @return  string     */    public static function sizeConvert(int $numSize)    {        if ($numSize >= 1073741824) {            $charSize = round($numSize / pow(1024, 3) * 100) / 100 . ' GB';        } elseif ($numSize >= 1048576) {            //转成MB            $charSize = round($numSize / pow(1024, 2) * 100) / 100 . ' MB';        } elseif ($numSize >= 1024) {            //转成KB            $charSize = round($numSize / 1024 * 100) / 100 . ' KB';        } else {            //不转换直接输出            $charSize = $numSize . ' B';        }        return $charSize;    }    /**     * @desc    数字单位转换     * @param   int $number     * @return  string     */    public static function numberConvert(int $number)    {        if ($number >= 1000 && $number < 10000) {            $number = sprintf('%.1f', $number / 1000) . ' K';        } elseif ($number >= 10000) {            $number = sprintf('%.1f', $number / 10000) . ' W';        } elseif ($number >= 1000000) {            $number = sprintf('%.1f', $number / 10000) . ' M';        }        return $number;    }    /**     * @desc    生成 hash token     * @param   string $value     * @return  mixed     */    public static function hashToken(string $value)    {        $hash  = hash_hmac('sha1', $value . mt_rand() . time(), mt_rand(), true);        $token = str_replace('=', '', strtr(base64_encode($hash), '+/', '-_'));        return $token;    }    /**     * @desc    是否微信环境     * @return  bool|mixed     */    public static function isWeixin()    {        return strpos($_SERVER['HTTP_USER_AGENT'], 'MicroMessenger') !== false ? true : false;    }    /**     * @desc    ssl 加密     * @param   $str    待加密字符     * @param   string  $key    加密key     * @param   string  $iv     偏移iv     * @return  string     */    public static function encrypt($str, $key = 'cdlchdwxcdh5', $iv = 'cdlchd0123456789')    {        return bin2hex(openssl_encrypt($str, 'AES-128-CBC', $key, OPENSSL_RAW_DATA, $iv));    }    /**     * @desc    ssl 解密     * @param   $str    待解密字符     * @param   string  $key    加密key     * @param   string  $iv     偏移iv     * @return  string     */    public static function decrypt($str, $key = 'cdlchdwxcdh5', $iv = 'cdlchd0123456789')    {        return openssl_decrypt(hex2bin($str), 'AES-128-CBC', $key, OPENSSL_RAW_DATA, $iv);    }    /**     * @desc    记录日志     * @param   array $data     * @param   string $remarks     */    public static function apiLogs(array $data, string $remarks = '')    {        $request = \request();        $data = [            'token'      => $request->header('token', null),            'uid'        => Auth::$userId,            'url'        => $request->url(),            'controller' => $request->controller(),            'func'       => $request->action(),            'method'     => $request->method(),            'ip'         => $request->ip(),            'params'     => json_encode($data, 256),            'remarks'    => $remarks,            'day'        => strtotime('today'),            'create'     => time()        ];        $rdsConf = Config::get('lc.redis');        if ($rdsConf['log_open']) {            $redis = Redis::instance();            $redis->select($rdsConf['db']);            $redis->rPush(env('id') . '_apilogs', json_encode($data, 256));        } else {            Db::name('api_logs')->insert($data);        }    }    /**     * @desc 	将xml转为array     * @param 	$xml     * @return 	array     * @throws 	\Exception     */    public static function xmlToArray($xml)    {        if (!$xml) {            throw new \Exception('xml数据异常!');        }        //禁止引用外部xml实体        libxml_disable_entity_loader(true);        $data = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);        return $data;    }    /**     * @desc    输出xml字符     * @param   array $data     * @return  string     * @throws 	\Exception     */    public static function arrayToXml($data)    {        if (!is_array($data) || count($data) <= 0) {            throw new \Exception('数组数据异常!');        }        $xml = '<xml>';        foreach ($data as $key => $val) {            if (is_numeric($val)) {                $xml .= '<' . $key . '>' . $val . '</' . $key . '>';            } else {                $xml .= '<' . $key . '><![CDATA[' . $val . ']]></' . $key . '>';            }        }        $xml .= '</xml>';        return $xml;    }    /**     * @desc	按字典序生成签名     * @param 	array $data 签名数据     * @param 	string $key 前面key     * @return 	string     */    public static function makeSign(array $data, string $key)    {        // 1. 按字典序排序参数        ksort($data);        $string = self::signUrlParams($data);        // 2. 在string后加入KEY        $string = $string . '&key=' . $key;        // 3. MD5加密        $string = md5($string);        // 4. 所有字符转为大写        return strtoupper($string);    }    /**     * @desc	签名格式化成url参数     * @param 	array $params 格式化参数     * @return 	string     */    private static function signUrlParams(array $params)    {        $buff = '';        foreach ($params as $k => $v) {            if ($k != 'sign' && $v != '' && !is_array($v)) {                $buff .= $k . '=' . $v . '&';            }        }        $buff = trim($buff, '&');        return $buff;    }    /**     * @desc 获取毫秒级别的时间戳     */    public static function millisecond()    {        // 获取毫秒的时间戳        $time   = explode(' ', microtime());        $time   = $time[1] . ($time[0] * 1000);        $time2  = explode('.', $time);        $time   = $time2[0];        return $time;    }    /**     * @desc	产生随机字符串,不长于32位     * @param 	int $length     * @return 	string 产生的随机字符串     */    public static function generateNonceStr($length = 32)    {        $chars = 'abcdefghijklmnopqrstuvwxyz0123456789';        $str   = '';        for ($i = 0; $i < $length; $i++) {            $str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);        }        return $str;    }    /**     * @desc    对emoji表情转义     * @param   $str     * @return  string     */    public static function emojiEncode($str)    {        $strEncode = '';        $length = mb_strlen($str, 'utf-8');        for ($i = 0; $i < $length; $i++) {            $tmpStr = mb_substr($str, $i, 1, 'utf-8');            if (strlen($tmpStr) >= 4) {                $strEncode .= '[[EMOJI:' . rawurlencode($tmpStr) . ']]';            } else {                $strEncode .= $tmpStr;            }        }        return $strEncode;    }    /**     * @desc    对emoji表情转反义     * @param   $str     * @return  string|string[]|null     */    public static function emojiDecode($str)    {        return preg_replace_callback('|\[\[EMOJI:(.*?)\]\]|', function ($matches) {            return rawurldecode($matches[1]);        }, $str);    }    /**     * @desc    判断请求机型     * @return  string     */    public static function deviceType()    {        $agent = strtolower($_SERVER['HTTP_USER_AGENT']);        $type  = 'other';        //分别进行判断        if (strpos($agent, 'iphone') || strpos($agent, 'ipad')) {            $type = 'ios';        }        if (strpos($agent, 'android')) {            $type = 'android';        }        return $type;    }    /**     * @desc    记录日志     * @param   string      $filename   文件名     * @param   string      $log        日志内容     * @param   float|int   $fileSize   文件日志大小,默认最大2M,超过则重命名     */    public static function log(string $filename, string $log, $fileSize = 2 * 1024 * 1024)    {        $path = dirname($filename);        if (!is_dir($path)) {            mkdir($path, 0755, true);        }        if (is_file($filename) && floor($fileSize) <= filesize($filename)) {            try {                rename($filename, dirname($filename) . DIRECTORY_SEPARATOR . time() . '-' . basename($filename));            } catch (\Exception $e) {                //            }        }        error_log($log, 3, $filename);    }    /**     * 求两点之间的距离     * @param $thisLongitude 当前经度     * @param $thisLatitude 当前纬度     * @param $stayLongitude 待计算经度     * @param $stayLatitude 待计算纬度     * @param int $unit 单位,1米,2千米     * @param int $decimals 保留小数点几位     * @return string     */    public static function calculateDistance($thisLongitude, $thisLatitude, $stayLongitude, $stayLatitude, $unit = 1, $decimals = 0)    {        // 原始坐标纬度弧度 deg2rad()函数将角度转换为弧度        $oriLatRad = deg2rad($thisLatitude);        // 新坐标纬度弧度        $newLatRad = deg2rad($stayLatitude);        // 坐标纬度弧度差        $diffLatRad = deg2rad($thisLatitude) - deg2rad($stayLatitude);        // 经度弧度差        $diffLngRad = deg2rad($thisLongitude) - deg2rad($stayLongitude);        // sin 求正弦值 参数单位为弧度 sin(2) => 0.90929742682568        // cos 求余弦值 参数单位为弧度 cos(0.2) => 0.98006657784124        // sqrt 求平方根 sqrt(2) => 1.4142135623731        // asin 求反正弦 参数单位为弧度 asin(2) => 1.4142135623731        // pow 求幂 pow(2, 2) => 4        $distance = 2 * asin(sqrt(pow(sin($diffLatRad / 2), 2) + cos($oriLatRad) * cos($newLatRad) * pow(sin($diffLngRad / 2), 2))) * 6378.137 * 1000;        if ($unit == 2) {            $distance = $distance / 1000;        }        return number_format($distance, $decimals);    }    /**     * 导出csv数据     * @param $title 表名     * @param $cell 表头     * @param $data 数据     * @param null $closure     */    public static function exportCsv($title, $cell, $data, $closure = null)    {        set_time_limit(0);        ini_set('memory_limit', '1024M');        $output = fopen('php://output', 'w') or die("can't open php://output");        if (ob_get_contents()) {            ob_clean();        }        header("Content-Type: application/force-download");        header("Content-type: text/csv;charset=utf-8");        header("Content-Disposition: attachment; filename=" . $title . ".csv");        echo chr(0xEF) . chr(0xBB) . chr(0xBF);        fputcsv($output, $cell);        foreach ($data as $v) {            if ($closure instanceof \Closure) {                $v = $closure($v);            }            fputcsv($output, array_values($v));        }        fclose($output) or die("can't close php://output");        exit;    }}
 |