php常用函数

<?php
/**
 * 通用函数库
 */
class Func {

    static function random($length, $numeric = 0) {
        $seed = base_convert(md5(microtime().$_SERVER['DOCUMENT_ROOT']), 16, $numeric ? 10 : 35);
        $seed = $numeric ? (str_replace('0', '', $seed).'012340567890') : ($seed.'zZ'.strtoupper($seed));
        $hash = '';
        $max = strlen($seed) - 1;
        for($i = 0; $i < $length; $i++) {
            $hash .= $seed{mt_rand(0, $max)};
        }
        return $hash;
    }

    static function implode_field_value($array, $glue = ',') {
        $sql = $comma = '';
        foreach ($array as $k => $v) {
            $sql .= $comma."`$k`='$v'";
            $comma = $glue;
        }
        return $sql;
    }

    static function getIp() {
        if(getenv('HTTP_CLIENT_IP')) {
            $ip = getenv('HTTP_CLIENT_IP');
        } elseif(getenv('HTTP_X_FORWARDED_FOR')) {
            $ip = getenv('HTTP_X_FORWARDED_FOR');
        } elseif(getenv('REMOTE_ADDR')) {
            $ip = getenv('REMOTE_ADDR');
        } elseif (isset($_SERVER['REMOTE_ADDR'])) {
            $ip = $_SERVER['REMOTE_ADDR'];
        } else {
            $ip = '';
        }
        return $ip;
    }

    /**
     * 获取ip
     * @return string
     */
    static function get_client_ip($type = 0) {

    	if(isset($_GET['ip'])){
    		$ipget=trim($_GET['ip']);
    	}else{
    		$ipget="";
    	}
    	$type       =  $type ? 1 : 0;
    	static $ip  =   NULL;
    	if ($ip !== NULL) return $ip[$type];
    	if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
    		$arr    =   explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
    		$pos    =   array_search('unknown',$arr);
    		if(false !== $pos) unset($arr[$pos]);
    		$ip     =   trim($arr[0]);
    	}elseif (isset($_SERVER['HTTP_CLIENT_IP'])) {
    		$ip     =   $_SERVER['HTTP_CLIENT_IP'];
    	}elseif (isset($_SERVER['REMOTE_ADDR'])) {
    		$ip     =   $_SERVER['REMOTE_ADDR'];
    	}
    	$ip=!empty($ipget)?$ipget:$ip;
    	// IP地址合法验证
    	$long = sprintf("%u",ip2long($ip));
    	$ip   = $long ? array($ip, $long) : array('0.0.0.0', 0);


    	//修复多ipbug  过滤内部地址 取一个外网地址
    	$arr=explode(',',$ip[$type]);
    	$arr2=array();
    	foreach($arr as $key => $v){
    		if (!preg_match('#^(10|172\.1[6-9]|172\.2[0-9]|172\.31|192\.168)\.#', $v)) {
    			$arr2[]=$v;
    		}else{
    			$arr2[0]="";
    		}
    	}
    	return $arr2[0];
    }

    /*
     * @todo 通过IP地址获取归属地信息
     * @return Array()
     *      -ip 请求ip地址
     *      -supplier 供应商
     *      -country 国家
     *      -area 区域
     *      -province 省份
     *      -city 城市
     */
    static function getIpInfo($ip) {
        if ($ip) {
            $url = 'http://ip.taobao.com/service/getIpInfo.php?ip=' . $ip;
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL , $url);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
            $result = curl_exec($ch);
            if (!empty($result)) {
                $result = json_decode($result, true);
                return array(
                    'ip'       => !empty($result['data']['ip']) ? $result['data']['ip'] : '',
                    'supplier' => !empty($result['data']['isp']) ? $result['data']['isp'] : '',
                    'country'  => !empty($result['data']['country']) ? $result['data']['country'] : '',
                    'area'     => !empty($result['data']['area']) ? $result['data']['area'] : '',
                    'province' => !empty($result['data']['region']) ? $result['data']['region'] : '',
                    'city'     => !empty($result['data']['city']) ? $result['data']['city'] : '',
                );
            }
        }
        return array();
    }

    /*
     * @todo 通过手机号码获取归属地信息
     * @return Array()
     *      -phone 请求手机号码
     *      -prefix 前缀
     *      -supplier 供应商
     *      -province 省份
     *      -city 城市
     *      -suit 卡类
     */
    static function getMobileInfo($mobile){
        if ($mobile) {
            $url = 'http://apis.baidu.com/apistore/mobilenumber/mobilenumber?phone=' . $mobile;
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL , $url);
            curl_setopt($ch, CURLOPT_HTTPHEADER, array('apikey: af653c87f1497f06e98c3b84ccac1576'));
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
            $result = curl_exec($ch);
            if (!empty($result)) {
                $result = json_decode($result, true);
                return array(
                    'phone'    => !empty($result['retData']['phone']) ? $result['retData']['phone'] : '',
                    'prefix'   => !empty($result['retData']['prefix']) ? $result['retData']['prefix'] : '',
                    'supplier' => !empty($result['retData']['prefix']) ? $result['retData']['prefix'] : '',
                    'province' => !empty($result['retData']['province']) ? $result['retData']['province'] : '',
                    'city'     => !empty($result['retData']['city']) ? $result['retData']['city'] : '',
                    'suit'     => !empty($result['retData']['suit']) ? $result['retData']['suit'] : '',
                );
            }
        }
        return array();
    }

    /**
     *
     * Generate v4 UUID
     *
     * Version 4 UUIDs are pseudo-random.
     */
    public static function uuid_v4() {
        return sprintf('%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
            // 32 bits for "time_low"
            mt_rand(0, 0xffff), mt_rand(0, 0xffff),
            // 16 bits for "time_mid"
            mt_rand(0, 0xffff),
            // 16 bits for "time_hi_and_version",
            // four most significant bits holds version number 4
            mt_rand(0, 0x0fff) | 0x4000,
            // 16 bits, 8 bits for "clk_seq_hi_res",
            // 8 bits for "clk_seq_low",
            // two most significant bits holds zero and one for variant DCE1.1
            mt_rand(0, 0x3fff) | 0x8000,
            // 48 bits for "node"
            mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0xffff)
        );
    }

    static function checkmobile() {
        $mobilebrowser_list =array('iOS','meego','iphone', 'android', 'phone', 'ipad', 'ipod', 'mobile', 'wap', 'netfront', 'java', 'opera mobi', 'opera mini',
                    'ucweb', 'windows ce', 'symbian', 'series', 'webos', 'sony', 'blackberry', 'dopod', 'nokia', 'samsung',
                    'palmsource', 'xda', 'pieplus', 'meizu', 'midp', 'cldc', 'motorola', 'foma', 'docomo', 'up.browser',
                    'up.link', 'blazer', 'helio', 'hosin', 'huawei', 'novarra', 'coolpad', 'webos', 'techfaith', 'palmsource',
                    'alcatel', 'amoi', 'ktouch', 'nexian', 'ericsson', 'philips', 'sagem', 'wellcom', 'bunjalloo', 'maui', 'smartphone',
                    'iemobile', 'spice', 'bird', 'zte-', 'longcos', 'pantech', 'gionee', 'portalmmm', 'jig browser', 'hiptop',
                    'benq', 'haier', '^lct', '320x320', '240x320', '176x220');
        $useragent = empty($_SERVER['HTTP_USER_AGENT']) ? '' : strtolower($_SERVER['HTTP_USER_AGENT']);

        foreach ($mobilebrowser_list as $key => $value) {
            if(strpos($useragent, $value) !== false) {
                return true;
            }
        }
        return false;
    }

    /**
     * 添加队列
     *
     * @param array $data $data = array( 'Name'  => $name, 'Args'  => $data);
     * @param string $exchangeName 默认交换机,默认不需要修改
     * @param string $keyRouter 默认路由,默认不需要修改
     * @return string
     */
    public static function addMQ($data,$exchangeName='BozhongExecPHP',$keyRouter='BozhongExecPHP'){
        //配置信息
        $conn_args = array(
            'host'  => RABBITMQ_HOST_WEB002,
            'port'  => RABBITMQ_PORT_WEB002,
            'login' => RABBITMQ_LOGIN_WEB002,
            'password' =>RABBITMQ_PSSSWORD_WEB002,
            'vhost' =>RABBITMQ_VHOST_WEB002
        );
        if(empty($conn_args['host'])) {
            return false;
        }
        /*处理参数*/
        $ex_name = $exchangeName;
        //交换机名
        $key_route = $keyRouter;       	//路由key
        /*处理参数*/

        //修改连接mq处理,连接不上时发送一个警告
        try{
            //创建连接
            $conn = new AMQPConnection($conn_args);
            //设置500毫秒连接超时
            $conn->setReadTimeout(500);
            $conn->connect();
        } catch(AMQPException $exception) {
            trigger_error("AMQP connect is false.host:".RABBITMQ_HOST_WEB002,E_USER_WARNING);
            return false;
        }
        // Open Channel
        $channel    = new AMQPChannel($conn);
        // Declare exchange
        $exchange   = new AMQPExchange($channel);
        $exchange->setName($ex_name);
        // delivery_mode 2 -> 1 从持久到不持久保存
        $message = $exchange->publish(json_encode($data),  $key_route, AMQP_NOPARAM, array('delivery_mode' => '1'));
        if (!$message) {
            return false;
        }else{
            return true;
        }
    }

    /**
     * 播种异步
     * @param array $data
     * @param string $class_name  library的类名,全称:如 LabLib_Test_Hello
     * @param string $fun_name  注意:不需要添加callback_,如回调名称是:callback_abc,fun_name='abc' 就好
     * @return bool
     */
    public static function callback($method,$data=array(),$fun_name='',$class_name=''){
        // $gmclient = new GearmanClient();
        // $gmclient->addServer(CONFIG_GEARMAN_SERVER,CONFIG_GEARMAN_PORT);
        $cli_path = ROOT_PATH .'cli/request.php';
        // IndexController::jsonAction
        // lib: LabLib_Test_Hello::sync_lab
        $str_method = strval($method);
        if($class_name!=""){
            if($fun_name==""){
                $_method = explode('::',$str_method);
                $fun_name= $_method[1];
            }
            $str_json_data = urlencode(json_encode($data));
            $uri = sprintf('/index/index/callback/class_name/%s/func/callback_%s/data/%s', $class_name, $fun_name,$str_json_data);
        }elseif($fun_name!=""){
            if($class_name==""){
                $_method = explode('::',$str_method);
                $class_name= $_method[0];
            }
            $str_json_data = urlencode(json_encode($data));
            $uri = sprintf('/index/index/callback/class_name/%s/func/callback_%s/data/%s', $class_name, $fun_name,$str_json_data);
        }elseif(Seedit_Func::endsWith($str_method,'Action')) {
            // 是在action使用
            $args = '';
            foreach($data as $k=>$v){
                $args .= sprintf('%s/%s/',$k,urlencode($v));
            }
            $uri = sprintf('/%s/%s/callback_%s/%s', __M__, __C__, __A__, $args);
        }else{
            // request_uri=/index/index/callback/class_name/LabLib_Test_Hello/func/callback_sync_lab/param/test_msg
            $_method = explode('::',$str_method);
            $class_name= $_method[0];
            $fun_name= $_method[1];
            $str_json_data = urlencode(json_encode($data));
            $uri = sprintf('/index/index/callback/class_name/%s/func/callback_%s/data/%s', $class_name, $fun_name,$str_json_data);
        }
        $data = array(
            'Name'  => 'bz_rsync_callback',
            'Args'  => array($cli_path,$uri)
        );

        return Seedit_Func::addMQ($data);
        /*
        $job_handle = $gmclient->doBackground("execphp", json_encode($data));
        if ($gmclient->returnCode() == GEARMAN_SUCCESS){
            return true;
        }else{
            // todo: add logging..
            return false;
        }
        */
    }

    public static function startsWith($haystack, $needle) {
        // search backwards starting from haystack length characters from the end
        return $needle === "" || strrpos($haystack, $needle, -strlen($haystack)) !== false;
    }

    public static function endsWith($haystack, $needle) {
        // search forward starting from end minus needle length characters
        return $needle === "" || (($temp = strlen($haystack) - strlen($needle)) >= 0 && strpos($haystack, $needle, $temp) !== false);
    }

    /*
     * 截取中文
     */
    static function mb_cutstr($string, $length, $dot = '...', $charset = 'utf-8') {
        if(strlen($string) <= $length) {
            return $string;
        }

        $strcut = '';
        if(strtolower($charset) == 'utf-8') {
            $n = $tn = $noc = 0;
            while ($n < strlen($string)) {
                $t = ord($string[$n]);
                if ($t == 9 || $t == 10 || (32 <= $t && $t <= 126)) {
                    $tn = 1; $n++; $noc++;
                } elseif (194 <= $t && $t <= 223) {
                    $tn = 2; $n += 2; $noc += 2;
                } elseif (224 <= $t && $t <= 239) {
                    $tn = 3; $n += 3; $noc += 2;
                } elseif (240 <= $t && $t <= 247) {
                    $tn = 4; $n += 4; $noc += 2;
                } elseif (248 <= $t && $t <= 251) {
                    $tn = 5; $n += 5; $noc += 2;
                } elseif ($t == 252 || $t == 253) {
                    $tn = 6; $n += 6; $noc += 2;
                } else {
                    $n++;
                }
                if($noc >= $length) {
                    break;
                }
            }
            if($noc > $length) {
                $n -= $tn;
            }
            $strcut = substr($string, 0, $n);
        } else {
            for($i = 0; $i < $length; $i++) {
                $strcut .= ord($string[$i]) > 127 ? $string[$i] . $string[++$i] : $string[$i];
            }
        }

        $pos = strrpos($strcut, chr(1));
        if($pos !== false) {
            $strcut = substr($strcut,0,$pos);
        }
        return $strcut . $dot;
    }

    // 格式化输出的数据的类型
    static public function formatDataTypeToString($data) {
        foreach ($data as &$val) {
            if (is_array($val)) {
                $val = self::formatDataTypeToString($val);
            } elseif (is_numeric($val)) {
                $val = (string)$val;
            }
        }
        unset($val);
        return $data;
    }

    // 获取用户的头像
    static function getBbsUserAvatar($uid, $size = 'middle') {
        $size = in_array($size, array('big', 'middle', 'small')) ? $size : 'middle';
        //***** modify 2018-01-15 统一获取头像方法 start
//        $uid = sprintf("%09d", $uid);
//        $dir1 = substr($uid, 0, 3);
//        $dir2 = substr($uid, 3, 2);
//        $dir3 = substr($uid, 5, 2);
//        $file = UC_SEEDIT_COM . '/data/avatar/' . $dir1 . '/' . $dir2 . '/' . $dir3 . '/' . substr($uid, -2) . (false ? '_real' : '') . '_avatar_' . $size . '.jpg';

        $MemberModle = new Module_Bbs_Modles_Common_Member();
        $file = $MemberModle->getavatar($uid, $size);
        //***** modify 2018-01-15 统一获取头像方法 end

        return $file;
    }

    //code by json 2016-10-09 +
    static function arrSearch($array, $key, $value){
    	$results = array ();
    	if (is_array ( $array )) {
    		foreach ( $array as $subarray ) {
    			if ($subarray [$key] == $value)
    				$results [] = $subarray;
    		}
    	}
    	return $results;
    }
    static function arrFindOne($array, $key, $value){
    	$results = null;
    	if (is_array ( $array )) {
    		foreach ( $array as $subarray ) {
    			if ($subarray [$key] == $value) {
    				$results = $subarray;
    				break;
    			}
    		}
    	}
    	return $results;
    }
    //code by json 2016-10-09 -

    /**
     * App推送||透传
     * @param  array $text   标题和内容  title  content
     * @param  array $option 推送配置   uid:用户id  category:分类  url:跳转地址   send_time:定时  transfer_id:透传 notify_type:效果
     * @return
     */
    public static function appPush($text, $option){
            $push = new Seedit_Push();
            $push->app_id = isset($option['app_id']) ? (int)$option['app_id'] : Seedit_Push_AppId::Crazy;
            $push->receiver_type = Seedit_Push_ReceiverType::Single;
            $push->receiver_id   = $option['uid'];
            $push->title         = $text['title'];
            $push->content       = $text['content'];
            $push->category      = $option['category'];
            //$push->ios_content   = $text['title'].'-'.$text['content'];  //IOS推送默认拼接标题和内容->调整由randy那边控制自动合并标题和内容
            //推送 || 透传
            if(isset($option['url'])){
                $push->push_type = Seedit_Push_PushType::URL;
                $push->url = $option['url'];
            }elseif(isset($option['transfer_id']) && isset($option['push_notify'])){
                $push->push_type    = isset($option['push_type']) ? (int)$option['push_type'] : Seedit_Push_PushType::Through;
                $push->transfer_id  = $option['transfer_id'];
                $push->pass_through = isset($option['pass_through']) ? (int)$option['pass_through'] : Seedit_Push_PassThrough::Through;
                $push->push_notify = $option['push_notify'] == 1 ? true : false;  //false-推送 true-推送+透传
            }elseif(isset($option['transfer_id'])){  //纯透传
                $push->push_type    = isset($option['push_type']) ? (int)$option['push_type'] : Seedit_Push_PushType::Through;
                $push->transfer_id  = $option['transfer_id'];
                $push->pass_through = isset($option['pass_through']) ? (int)$option['pass_through'] : Seedit_Push_PassThrough::Through;
            }else{
                isset($option['push_type']) && $push->push_type = $option['push_type'];
            }
            ##帖子||动态
            //版块id
            if(isset($option['fid'])){
                $push->fid = (int)$option['fid'];
            }
            //帖子或动态tid
            if(isset($option['tid'])){
                $push->tid = (int)$option['tid'];
            }
            //回复id
            if(isset($option['pid'])){
                $push->pid = (int)$option['pid'];
            }
            //扩展字段-标识isDynamic 0-帖子 1-动态 (孕迹4.0.0)
            if(isset($option['ex_data'])){
                $push->ex_data = $option['ex_data'];
            }

            //定时推送
            if(isset($option['send_time'])){
                $push->send_time = $option['send_time'];
            }
            //notify_type 1: 提示音提示 2: 震动提示 4: led灯光提示 3:提示音提示+震动提示 5:提示音提示+led灯光提示 6:震动提示+led灯光提示 -1: 默认所有
            if(isset($option['notify_type'])){
                $push->config = array("notify_type"=>$option['notify_type']);
            }

            return $push->send();
    }

    /**
     * 新版APP推送-2018-12-20
     * @param array $text   推送内容  e.g. array('title'=>标题,'content'=>内容)
     * @param array $option 推送配置
     *        e.g.  array(
     *                  'app_id',           //APP ID
     *                  'receiver_type',    //0全部 1单人 2安卓 3IOS  4 批量用户 5 tag
     *                  'receiver_id',      //receiver_type=1是uid; receiver_type=5, receiver_id是tag_id
     *                  'url',              //跳转链接
     *                  'category',         //分类,参考 Seedit_Push_Category
     *                  'pass_through',     //0:通知,1:透传
     *                  'sendtime'          //设置推送时间
     *              )
     */
    public static function appPushSend($text, $option){
        $error = true;
        $message = '';
        switch (true) {
            case (!isset($option['app_id']) || $option['app_id'] <= 0):
                $message = '推送应用有误';
                break;
            case (!$text['title'] || !$text['content']):
                $message = '推送标题和内容不能为空';
                break;
            case (!isset($option['receiver_id']) || !$option['receiver_id']):
                $message = '推送接收id有误';
                break;
            case (!isset($option['url']) || !$option['url']):
                $message = '推送跳转地址有误';
                break;
            case (!isset($option['category']) || $option['category'] < 0):
                $message = '推送分类有误';
                break;
            case (!isset($option['pass_through']) || $option['pass_through'] < 0):
                $message = '推送类型有误';
                break;
        }
        if(empty($message)){
            $error = false;
        }
        if($error){
            return array('result' => false, 'message' => $message);
        }
        $data = array(
            'action' => 'add_push',
            'data' => array(
                'app_id'        => $option['app_id'],
                'push_type'     => 3,                           //新版统一推送URL
                'url'           => $option['url'],
                'title'         => $text['title'],
                'ios_title'     => $text['title'],
                'content'       => $text['content'],
                'ios_content'   => $text['content'],
                'receiver_type' => isset($option['receiver_type']) ? $option['receiver_type'] : 0,
                'receiver_id'   => $option['receiver_id'],
                'category'      => $option['category'],
                'pass_through'  => $option['pass_through'],
                'status'        => 0,
                'remark'        => '',
                'ex_data'       => isset($option['ex_data']) ? $option['ex_data'] : '',
                'dateline'      => $_SERVER['REQUEST_TIME'],
                'sendtime'      => isset($option['sendtime']) ? $option['sendtime'] : $_SERVER['REQUEST_TIME']
            )
        );
        $push_result = self::addMQ($data, 'push_v2', 'push_v2');
        if($push_result){
            return array('result' => true, 'message' => '推送成功');
        }else{
            return array('result' => false, 'message' => '推送失败');
        }
    }

    /**
     * 发起HTTP请求
     * @param  string $api   请求地址
     * @param  int $type  请求类型   0:GET   1:POST   默认为GET
     * @param  array $param 请求参数
     * @return
     */
    public static function httpReq($url, $param=array(), $type=0, $json=1){
        $ch = curl_init();
        if(false !== stripos($url, "https://")){
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
            curl_setopt($ch, CURLOPT_SSLVERSION, 1);
        }
        //区分类型
        switch ($type) {
            case 0:
                $arr = array();
                foreach ($param as $k => $val) {
                    $arr[] = $k . '=' . $val;
                }
                $query = implode('&', $arr);
                $url = $url . '?' . $query;
                curl_setopt($ch, CURLOPT_ENCODING, '');
                break;
            case 1:

                if(($json > 0)){
                    $param = json_encode($param);
                    curl_setopt(
                        $ch,
                        CURLOPT_HTTPHEADER,
                        array('Content-Type: application/json; charset=utf-8','Content-Length:'.strlen($param))
                    );
                }
                curl_setopt($ch, CURLOPT_POST, true);
                curl_setopt($ch, CURLOPT_POSTFIELDS, $param);
                break;
            default:
                return false;
        }

        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

        $res = curl_exec($ch);
        curl_close($ch);

        return json_decode($res, true) ? json_decode($res, true) : $res;
    }

  /**
     * 去掉url的协议
     * 将 http://abc.com 变成 //abc.com
     * https://edf.com 变成 //edf.com
     * ftp://123.com 变成 //123.com
     * @param string $url
     * @return mixed|string
     */
    static function rm_scheme($url='') {
        $res = preg_replace('#^.+?://#', '', $url);
        $res = "//".$res;
        return $res;
    }

    public static function get_image_size($url, $cache_time = null)
    {
        $url = trim($url);
        if (empty($url)){
            return array(0,0);
        }

        if (empty($cache_time)){
            $cache_time = 3600*24*365;
        }

        $url_key = md5($url);
        $Cache = new Seedit_Redis();
        $cache_key = "Seedit_Func:get_image_size:url_key:{$url_key}";

        if (!$size = $Cache->get($cache_key)){
            $img_arr = @getimagesize($url);
            $size = "{$img_arr[0]},$img_arr[1]";
            $Cache->setEx($cache_key, $cache_time, $size);
        }
        return array_map('intval', explode(',', $size));
    }

    public static function html_filter($post_message){
        $patterns = array(
            '/\[quote\].*?\[\/quote\]/',
            '/\[img\].*?\[\/img\]/',
            '/\[i.*?\].*?\[\/i\]/',
            '/\[attch\].*?\[\/attch\]/',
            '/\[attach\].*?\[\/attach\]/',
            '/\[url.*?\].*?\[\/attch\]/',
            '/\[.*?\]/',
        );
        $replacements = array(
            '',
            '',
            '',
            '',
            '',
            '',
            ''
        );

        $post_message = strip_tags($post_message);                //去除html标签
        $post_message = htmlspecialchars($post_message);          //转义特殊字符
        $post_message = str_replace(' ', ' ', $post_message);
        $post_message = str_replace('nbsp;', '', $post_message);
        $post_message = str_replace('&', '', $post_message);
        $post_message = str_replace("\r", "", $post_message);
        $post_message = str_replace("\n", "", $post_message);
        $post_message = str_replace(" ", "", $post_message);      //去除空
        $post_message = preg_replace($patterns, $replacements, $post_message);
        return $post_message;
    }

    /**
     * Create By XiaoMing
     * 默认疯狂造人APP/可传入appid 推送||透传 批量用户方式(所有用户推送的消息内容相同)
     * @param $text  array('title'=>标题,'content'=>内容)
     * @param $option  array(
     *                      uids => 所有用户id (必填)用逗号分开,如:1,2,34,432,534
     *                      category => 分类 (必填) 详见文档:http://wiki.bozhong.com/%E6%8A%80%E6%9C%AF/app_push
     *                      send_time => 定时发送时间 (必填) 时间戳  目的是预留给服务后台添加任务的时间(定时脚本时间 <= 定时发送时间 - 10min)
     *                      push_type => 推送动作 (必填) 详见文档:http://wiki.bozhong.com/%E9%A1%B9%E7%9B%AE/%E7%96%AF%E7%8B%82%E9%80%A0%E4%BA%BA/push_type
     *                      url => 跳转地址 (选填 , URL模式必填)
     *                      transfer_id => 透传 (选填) 同上,见文档
     *                      notify_type => 效果 (选填)1: 提示音提示 2: 震动提示 4: led灯光提示 3:提示音提示+震动提示 5:提示音提示+led灯光提示 6:震动提示+led灯光提示 -1: 默认所有
     *                 )
     * @return bool|array
     */
    public static function appBatchPush($text, $option) {

        //需要批量发送的用户
        if(empty($option['uids'])){
            return false;//uids不能为空
        }

        if(!isset($text['title']) || !isset($text['content']) || !isset($option['category']) || !isset($option['push_type']) || !isset($option['send_time'])){
            return false;//必填配置参数不全
        }

        //默认必填配置
        $push = new Seedit_Push();
        $push->app_id = isset($option['appid']) ? $option['appid'] : Seedit_Push_AppId::Crazy; //推送应用 默认疯狂造人
        $push->receiver_type = Seedit_Push_ReceiverType::Batch; //收件人类型
        $push->title = $text['title']; //标题
        $push->content = $text['content']; //内容
        $push->category = $option['category'];
        //$push->ios_content = $text['title'] . '-' . $text['content'];                     //IOS推送默认拼接标题和内容
        $push->ios_title     = $text['title'];
        $push->ios_content   = $text['content'];
        $push->push_type = $option['push_type'];
        $push->send_time = $option['send_time']; //定时发送时间 预留给服务后台添加任务的时间(定时脚本时间 <= 定时发送时间 - 10min)
        $push->job_id = md5(Seedit_Func::uuid_v4() . time());

        /**
         * 根据推送动作 设置必填选项(数量有限 其它类型请自行书写)
         */
        if(Seedit_Push_PushType::URL == $push->push_type) {
            if(!isset($option['url'])) {
                return false;//推送URL必须填写url地址
            }
            $push->url = $option['url'];
        }
        if(Seedit_Push_PushType::Other == $push->push_type) {
            if(!isset($option['transfer_id'])) {
                return false;//必须设置透传类型
            }
            $push->transfer_id = $option['transfer_id'];
        }

        /**
         * 选填项
         */
        if(isset($option['notify_type'])) {
            $push->config["notify_type"] = $option['notify_type'];
        }

        /**
         * 发送推送,send() 和 add_batch_uid() 方法不能调转
         */
        $result = $push->send();
        if(false === $result['result']){
            return false;
        }else{
            return $push->add_batch_uid($push->job_id, $option['uids']);
        }
    }

    /**
     * 获取远程图片的宽高和体积大小
     * by xiaoming
     * @param string $url 远程图片的链接
     * @param string $type 获取远程图片资源的方式, 默认为 curl 可选 fread
     * @param boolean $isGetFilesize 是否获取远程图片的体积大小, 默认false不获取, 设置为 true 时 $type 将强制为 fread
     * @return false|array
     */
    public static function getImageSize($url, $type = 'curl', $isGetFilesize = false, $length = 168) {
        // 若需要获取图片体积大小则默认使用 fread 方式
        $type = $isGetFilesize ? 'fread' : $type;
        if($type == 'fread') {
            // 或者使用 socket 二进制方式读取, 需要获取图片体积大小最好使用此方法
            $handle = fopen($url, 'rb');
            if(!$handle) return false;
            // 只取头部固定长度168字节数据
            $dataBlock = fread($handle, $length);
        } else {
            // 据说 CURL 能缓存DNS 效率比 socket 高
            $ch = curl_init($url);
            // 超时设置
            curl_setopt($ch, CURLOPT_TIMEOUT, 20);
            // 取前面 168 个字符 通过四张测试图读取宽高结果都没有问题,若获取不到数据可适当加大数值
            curl_setopt($ch, CURLOPT_RANGE, "0-{$length}");
            // 跟踪301跳转
            curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
            // 返回结果
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
            $dataBlock = curl_exec($ch);
            curl_close($ch);
            if(!$dataBlock) return false;
        }

        // 将读取的图片信息转化为图片路径并获取图片信息,经测试,这里的转化设置 jpeg 对获取png,gif的信息没有影响,无须分别设置
        // 有些图片虽然可以在浏览器查看但实际已被损坏可能无法解析信息
        $size = getimagesize('data://image/jpeg;base64,' . base64_encode($dataBlock));
        if(empty($size)) {
            return false;
        }
        $result['width'] = $size[0];
        $result['height'] = $size[1];
        // 是否获取图片体积大小
        if($isGetFilesize) {
            // 获取文件数据流信息
            $meta = stream_get_meta_data($handle);
            // nginx 的信息保存在 headers 里,apache 则直接在 wrapper_data
            $dataInfo = isset($meta['wrapper_data']['headers']) ? $meta['wrapper_data']['headers'] : $meta['wrapper_data'];

            foreach($dataInfo as $va) {
                if(preg_match('/length/iU', $va)) {
                    $ts = explode(':', $va);
                    $result['size'] = trim(array_pop($ts));
                    break;
                }
            }
        }
        if($type == 'fread') fclose($handle);
        return $result;
    }

    /**
     * 创建 mongoid
     * createMongoDbLikeId($timestamp, $hostname, $processId, $id)
     *
     * Creating MongoDB like ObjectIDs.
     * Using current timestamp, hostname, processId and a incremting id.
     * @author Julius Beckmann
     */
    public static function createMongoDbLikeId()
    {
        // Building binary data.
        $timestamp = time();
        $hostname  = "bozhong.com";
        $processId = rand(1,100);
        $id        = rand(1,100);

        // Building binary data.
        $bin = sprintf(
            "%s%s%s%s",
            pack('N', $timestamp),
            substr(md5($hostname), 0, 3),
            pack('n', $processId),
            substr(pack('N', $id), 1, 3)
        );
        // Convert binary to hex.
        $result = '';
        for ($i = 0; $i < 12; $i++) {
            $result .= sprintf("%02x", ord($bin[$i]));
        }
        return $result;
    }
}

  

posted @ 2020-05-12 18:40  kakasaber  阅读(183)  评论(0)    收藏  举报