PHP微信小程序获取access_token

上代码再说:

<?php

$path = dirname(dirname(__FILE__));
defined('WY_ROOT') or define('WY_ROOT', dirname($path) . '/SaleCard');
require_once $path . '/ALLClass.php';

class Wxxcx {

    private $appId;
    private $appSecret;
    public $pub;
    private $token_path='/access_token_xcx.json';
    private $file_path_log='get_scan_xcx.log';
    private $jsapi_ticket_path='/jsapi_ticket_xcx.json';

    public function __construct($appId, $appSecret) {
        $this->appId = $appId;
        $this->appSecret = $appSecret;
        $this->pub = new ALLClass();
    }

    public function getSignPackage() {
        $this->pub->data_log('getSignPackage_start', $this->file_path_log);
        $jsapiTicket = $this->getJsApiTicket();
        $url = 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
        $timestamp = time();
        $nonceStr = $this->createNonceStr();

        $string = "jsapi_ticket=$jsapiTicket&noncestr=$nonceStr&timestamp=$timestamp&url=$url";

        $signature = sha1($string);

        $signPackage = array(
            "appId" => $this->appId,
            "nonceStr" => $nonceStr,
            "timestamp" => $timestamp,
            "url" => $url,
            "signature" => $signature,
            "rawString" => $string
        );
        $this->pub->data_log($signPackage, $this->file_path_log);
        $this->pub->data_log('getSignPackage_End', $this->file_path_log);
        return $signPackage;
    }

    private function createNonceStr($length = 16) {
        $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        $str = "";
        for ($i = 0; $i < $length; $i++) {
            $str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
        }
        return $str;
    }

    private function getJsApiTicket() {
        $data = json_decode(file_get_contents(dirname(WY_ROOT) .$this->jsapi_ticket_path));
        $this->pub->data_log('getJsApiTicket_start',$this->file_path_log);
        if ($data->expire_time < time()) {
            $accessToken = $this->getAccessToken();
            $url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=jsapi&access_token=$accessToken";
            $res = json_decode($this->pub->httpRequest($url));
            $ticket = $res->ticket;
            $this->pub->data_log('getAccessToken',$this->file_path_log);
            $this->pub->data_log($res, $this->file_path_log);
            if ($ticket) {
                $data->expire_time = time() + 7000;
                $data->jsapi_ticket = $ticket;
                $this->pub->data_log($data);
                $fp = @fopen(dirname(WY_ROOT) . $this->jsapi_ticket_path, "w");
                @flock($fp, LOCK_EX | LOCK_NB); //文件上锁
                @fwrite($fp, json_encode($data));
                @flock($fp, LOCK_UN); //解锁
                @fclose($fp);
            }
        } else {
            $ticket = $data->jsapi_ticket;
        }

        $this->pub->data_log('getJsApiTicket_start_end', $this->file_path_log);
        return $ticket;
    }

    public function getAccessToken() {
        $this->pub->data_log('getAccessToken_start',$this->file_path_log);
        $path = dirname(WY_ROOT) . $this->token_path;
//        $data = json_decode(file_get_contents($path));
        $data='';//其他web跳转小程序 调用,该token缓存失效
        //无文件补丁
        if(!$data){
            $data=(object)['expire_time'=>0];
        }
        if ($data->expire_time < time()) {
            $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=$this->appId&secret=$this->appSecret";
            $res = json_decode($this->pub->httpRequest($url));
            if (isset($res->errcode)) {
                $this->pub->data_log($res->errmsg, $this->file_path_log);
                echo json_encode(['code' => $res->errcode, 'msg' => $res->errmsg]);
                die;
            }
            $access_token = $res->access_token;
            if ($access_token) {
                $data->expire_time = time() + 7000;
                $data->access_token = $access_token;
                $this->pub->data_log($data);
                $fp = @fopen($path, "w");
                @flock($fp, LOCK_EX | LOCK_NB); //文件上锁
                @fwrite($fp, json_encode($data));
                @flock($fp, LOCK_UN); //解锁
                @fclose($fp);
            }
        } else {
            $access_token = $data->access_token;
        }
        $this->pub->data_log('getAccessToken_end',  $this->file_path_log);
        return $access_token;
    }

    public function httpGet($url) {
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($curl, CURLOPT_TIMEOUT, 500);
        curl_setopt($curl, CURLOPT_URL, $url);

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

        return $res;
    }

}

好像还有个allclass的公共类,我找找。

ALLClass.php

<?php

/*
 * 公共方法类
 * ALL Public Class
 *  2018-11-30
 * @author lianyu001
 */
//error_reporting(0);//运行时开启-- 有错误也运行
//error_reporting(E_ALL & ~E_NOTICE); //没有错误就运行
//date_default_timezone_set('PRC'); //设置时区
//session_start(); //开启session
//$starttime = time();
//defined("NOW_TIME") or define(NOW_TIME, $starttime);
//@header("Content-Type:text/html;charset=utf-8"); //页面UTF8编码

/**
 * Description of ALLClass
 *      2018-11-22
 * @author lianyu001
 */
class ALLClass {

    private $num = 0;
    private $mysqli; //数据库链接对象
    private $database = "";
    private $bool = true;
    private $where = " 1 = 1 "; //sql条件判定

    /**
     * 初始化,获取数据库链接信息
     */

    function __construct() {
        
    }

    /**
     * 创建主数据库
     * 更新 数据库文件,作为迁移新项目使用
     * @param type $database    数据库名称
     */
    function create_database($database = "") {
        if (empty($database)) {
            $database = $this->database['database'];
        }
        // 创建连接
        $conn = new mysqli($this->database['localhost'], $this->database['username'], $this->database['password'], "", $this->database['port']);
// 检测连接
        if ($conn->connect_error) {
            die("连接失败: " . $conn->connect_error);
        }
// 创建数据库
        $sql = "CREATE DATABASE if not exists " . $database;
        $bb = $conn->query($sql);
        if ($bb === TRUE) {
            //更新文件
            $str = '<?php return ['
                    . '    "database"=>"' . $database . '",'
                    . '    "username"=>"' . $this->database['username'] . '",'
                    . '    "password"=>"' . $this->database['password'] . '",'
                    . '    "localhost"=>"' . $this->database['localhost'] . '",'
                    . '    "port"=>"' . $this->database['port'] . '",'//
                    . '];';
            $path = dirname(__FILE__) . "/databases.php";
            $this->database['database'] = $database;
            $fp = fopen($path, "w"); //尝试打开该文件,如不存在则创建,存在清空内容 指针移向末尾
            flock($fp, LOCK_EX | LOCK_NB); //文件上锁
            fwrite($fp, $str); //写入
            flock($fp, LOCK_UN); //解锁
            fclose($fp); //关闭
//            $numbytes = file_put_contents($path, $str); //如果文件不存在创建文件,并写入内容
            if (!$numbytes) {
                $this->data_log("数据库文件更新失败" . $path . $sql, "file_err.txt");
            }
        } else {
            echo "Error creating database: " . $conn->error;
            die;
        }
        $conn->close();
    }

    /**
     * 取小数点后两位
     * 截取点后面两位拼接
     * @param type $str 带小数的数字
     * @return type     返回准确截取两位的小数
     */
    function num_format($str) {
        if (strpos($str, '.') === false) {
            return $str;
        }
        $retArr = explode(".", $str);
        $strs = substr($retArr[1], 0, 2);
        return $retArr[0] . "." . $strs;
    }

    /**
     * 二维数组转三维,按键值分组
     * @param type $arr
     * @param type $key
     * @return type
     */
    function group_same_key($arr, $key) {
        $new_arr = array();
        foreach ($arr as $k => $v) {
            if ($v[$key] == '') {
//                 $v[$key]='';
            }
            $new_arr[$v[$key]][] = $v;
        }
        return $new_arr;
    }

    /**
     * 二维数组转三维,按键值分组
     * @param type $arr
     * @param type $key
     * @return type
     */
    function group_same_key2($arr, $key) {
        $new_arr = $this->group_same_key($arr, $key);
        $i = 0;
        $new_new_arr = [];
        //没有的放前面
        foreach ($new_arr as $k => $val) {
            if (empty($k)) {
                foreach ($val as $v) {
                    $new_new_arr[] = $v;
                }
                unset($new_arr[$k]);
            }
        }
        foreach ($new_arr as $k => $val) {
            foreach ($val as $v) {
                $new_new_arr[] = $v;
            }
        }
        return $new_new_arr;
    }

    /**
     * 解码出邀请码
     */
    function decodeInviteCode_copy($code) {
        $code = strtoupper($code);
        static $source_string = 'E5FCDG3HQA4B1NOPIJ2RSTUV67MWX89KLYZ';
        if (strrpos($code, '0') !== false)
            $code = substr($code, strrpos($code, '0') + 1);
        $len = strlen($code);
        $code = strrev($code);
        $num = 0;
        for ($i = 0; $i < $len; $i++) {
            $num += strpos($source_string, $code[$i]) * pow(35, $i);
        }
        return $num;
    }

    /**
     * 生成邀请码
     */
    function createInviteCode_copy($user_id) {
        static $source_string = 'E5FCDG3HQA4B1NOPIJ2RSTUV67MWX89KLYZ';
        $num = $user_id;
        $code = '';
        while ($num > 0) {
            $mod = $num % 35;
            $num = ($num - $mod) / 35;
            $code = $source_string[$mod] . $code;
        }
        if (empty($code[3])) {
            $code = str_pad($code, 4, '0', STR_PAD_LEFT);
        }
        $new_code = '';
        for ($i = 0; $i < strlen($code); $i++) {//遍历字符串追加给数组
            if ($i == 0 || $i == 3) {
                $new_code.= strtolower($code[$i]);
            } else {
                $new_code.= $code[$i];
            }
        }
        return $new_code;
    }

    /**
     * 解密apptoken
     */
    function decode_apptoken($apptoken = '') {
        if (empty($apptoken)) {
            return false;
        }
        $id = decodeInviteCode_copy(str_replace(DB_DB_ME, '', str_replace(DB_JHS, '', base64_decode($apptoken))));
        return --$id;
    }

    /**
     * 生成唯一标识apptoken
     */
    function encode_apptoken($lastInsID) {
        if (empty($lastInsID)) {
            return false;
        }
        ++$lastInsID;
        $apptoken = base64_encode(DB_JHS . createInviteCode_copy($lastInsID) . DB_ME);
        return $apptoken;
    }

    /**
     * 冒泡排序
     * @param ary $arr      数组
     * @param string $type  asc | desc
     * @return $arr         排序后数组
     */
    function maopao($arr, $type = 'asc') {
        //定义一个变量保存交换的值
        $temp = 0;
        for ($i = 0; $i < count($arr); $i++) {
            for ($j = 0; $j < count($arr) - $i - 1; $j++) {
                if ($type == 'asc') {
                    if ($arr[$j] > $arr[$j + 1]) {
                        //如果前面的那个数大于后面的那个数,那么他们就进行交换
                        $temp = $arr[$j];
                        $arr[$j] = $arr[$j + 1];
                        $arr[$j + 1] = $temp;
                    }
                } else {
                    if ($arr[$j] < $arr[$j + 1]) {
                        //如果前面的那个数小于后面的那个数,那么他们就进行交换
                        $temp = $arr[$j];
                        $arr[$j] = $arr[$j + 1];
                        $arr[$j + 1] = $temp;
                    }
                }
            }
        }
        return $arr;
    }

    /**
     * 两层冒泡排序
     * @param ary $arr      数组
     * @param type $field   排序数组中用来排序的字段名
     * @param string $type  asc | desc
     * @return $arr         排序后数组
     */
    function maopao2($arr, $field = '', $type = 'asc') {
        if (empty($field)) {
            return false;
        }
        //定义一个变量保存交换的值
        $temp = 0;
        for ($i = 0; $i < count($arr); $i++) {
            for ($j = 0; $j < count($arr) - $i - 1; $j++) {
                if ($type == 'asc') {
                    if ($arr[$j][$field] > $arr[$j + 1][$field]) {
                        //如果前面的那个数大于后面的那个数,那么他们就进行交换
                        $temp = $arr[$j];
                        $arr[$j] = $arr[$j + 1];
                        $arr[$j + 1] = $temp;
                    }
                } else {
                    if ($arr[$j][$field] < $arr[$j + 1][$field]) {
                        //如果前面的那个数小于后面的那个数,那么他们就进行交换
                        $temp = $arr[$j];
                        $arr[$j] = $arr[$j + 1];
                        $arr[$j + 1] = $temp;
                    }
                }
            }
        }
        return $arr;
    }

    /**
     * 时间转换
     */
    function tranTime($time) {
        $time2 = $time;
        $rtime = date("m-d H:i", $time);
        $htime = date("H:i", $time);
        $time = time() - $time;
        if ($time < 60) {
            $str = '刚刚';
        } elseif ($time < 60 * 60) {
            $min = floor($time / 60);
            $str = $min . '分钟前';
        } elseif ($time < 60 * 60 * 24) {
            $h = floor($time / (60 * 60));
            $str = $h . '小时前 ' . $htime;
        } elseif ($time < 60 * 60 * 24 * 3) {
            $d = floor($time / (60 * 60 * 24));
            if ($d == 1) {
                $str = '昨天 ' . $rtime;
            } else
            if ($d == 1) {
                $str = '前天 ' . $rtime;
            } else
            if ($d == 2) {
                $str = '大前天 ' . $rtime;
            } else {
                $str = $rtime;
            }
        } else {
            $str = date("Y-m-d H:i", $time2);
        }
        return $str;
    }

    /**
     * 打印输出
     * @param type $obj     要输出对象
     * @param type $die     是否输出后停止运行
     * @param type $msg     停止运行输出字符
     */
    function pre($obj, $die = true, $msg = "") {
        echo "<pre>";
        var_dump($obj);
        echo "</pre>";
        if ($die)
            die($msg);
    }

    /**
     * 返回经addslashes处理过的字符串或数组
     * @param $string 需要处理的字符串或数组
     * @return mixed
     */
    function new_addslashes($string) {
        if (!is_array($string))
            return addslashes($string);
        foreach ($string as $key => $val)
            $string[$key] = $this->new_addslashes($val);
        return $string;
    }

    /**
     * 返回经stripslashes处理过的字符串或数组
     * @param $string 需要处理的字符串或数组
     * @return mixed
     */
    function new_stripslashes($string) {
        if (!is_array($string))
            return stripslashes($string);
        foreach ($string as $key => $val)
            $string[$key] = new_stripslashes($val);
        return $string;
    }

    /**
     * 返回经htmlspecialchars处理过的字符串或数组
     * @param $obj 需要处理的字符串或数组
     * @return mixed
     */
    function new_html_special_chars($string) {
        $encoding = 'utf-8';
        if (strtolower(CHARSET) == 'gbk')
            $encoding = 'ISO-8859-15';
        if (!is_array($string))
            return htmlspecialchars($string, ENT_QUOTES, $encoding);
        foreach ($string as $key => $val)
            $string[$key] = new_html_special_chars($val);
        return $string;
    }

    function new_html_entity_decode($string) {
        $encoding = 'utf-8';
        if (strtolower(CHARSET) == 'gbk')
            $encoding = 'ISO-8859-15';
        return html_entity_decode($string, ENT_QUOTES, $encoding);
    }

    function new_htmlentities($string) {
        $encoding = 'utf-8';
        if (strtolower(CHARSET) == 'gbk')
            $encoding = 'ISO-8859-15';
        return htmlentities($string, ENT_QUOTES, $encoding);
    }

    /**
     * 安全过滤函数
     *
     * @param $string
     * @return string
     */
    function safe_replace($string) {
        $string = str_replace('%20', '', $string);
        $string = str_replace('%27', '', $string);
        $string = str_replace('%2527', '', $string);
        $string = str_replace('*', '', $string);
        $string = str_replace('"', '"', $string);
        $string = str_replace("'", '', $string);
        $string = str_replace('"', '', $string);
        $string = str_replace(';', '', $string);
        $string = str_replace('<', '<', $string);
        $string = str_replace('>', '>', $string);
        $string = str_replace("{", '', $string);
        $string = str_replace('}', '', $string);
        $string = str_replace('\\', '', $string);
        return $string;
    }

    /**
     * xss过滤函数
     *
     * @param $string
     * @return string
     */
    function remove_xss($string) {
        $string = preg_replace('/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]+/S', '', $string);

        $parm1 = Array('javascript', 'vbscript', 'expression', 'applet', 'meta', 'xml', 'blink', 'link', 'script', 'embed', 'object', 'iframe', 'frame', 'frameset', 'ilayer', 'layer', 'bgsound', 'title', 'base');

        $parm2 = Array('onabort', 'onactivate', 'onafterprint', 'onafterupdate', 'onbeforeactivate', 'onbeforecopy', 'onbeforecut', 'onbeforedeactivate', 'onbeforeeditfocus', 'onbeforepaste', 'onbeforeprint', 'onbeforeunload', 'onbeforeupdate', 'onblur', 'onbounce', 'oncellchange', 'onchange', 'onclick', 'oncontextmenu', 'oncontrolselect', 'oncopy', 'oncut', 'ondataavailable', 'ondatasetchanged', 'ondatasetcomplete', 'ondblclick', 'ondeactivate', 'ondrag', 'ondragend', 'ondragenter', 'ondragleave', 'ondragover', 'ondragstart', 'ondrop', 'onerror', 'onerrorupdate', 'onfilterchange', 'onfinish', 'onfocus', 'onfocusin', 'onfocusout', 'onhelp', 'onkeydown', 'onkeypress', 'onkeyup', 'onlayoutcomplete', 'onload', 'onlosecapture', 'onmousedown', 'onmouseenter', 'onmouseleave', 'onmousemove', 'onmouseout', 'onmouseover', 'onmouseup', 'onmousewheel', 'onmove', 'onmoveend', 'onmovestart', 'onpaste', 'onpropertychange', 'onreadystatechange', 'onreset', 'onresize', 'onresizeend', 'onresizestart', 'onrowenter', 'onrowexit', 'onrowsdelete', 'onrowsinserted', 'onscroll', 'onselect', 'onselectionchange', 'onselectstart', 'onstart', 'onstop', 'onsubmit', 'onunload');

        $parm = array_merge($parm1, $parm2);

        for ($i = 0; $i < sizeof($parm); $i++) {
            $pattern = '/';
            for ($j = 0; $j < strlen($parm[$i]); $j++) {
                if ($j > 0) {
                    $pattern .= '(';
                    $pattern .= '(&#[x|X]0([9][a][b]);?)?';
                    $pattern .= '|(&#0([9][10][13]);?)?';
                    $pattern .= ')?';
                }
                $pattern .= $parm[$i][$j];
            }
            $pattern .= '/i';
            $string = preg_replace($pattern, ' ', $string);
        }
        return $string;
    }

    /**
     * 过滤ASCII码从0-28的控制字符
     * @return String
     */
    function trim_unsafe_control_chars($str) {
        $rule = '/[' . chr(1) . '-' . chr(8) . chr(11) . '-' . chr(12) . chr(14) . '-' . chr(31) . ']*/';
        return str_replace(chr(0), '', preg_replace($rule, '', $str));
    }

    /**
     * 格式化文本域内容
     *
     * @param $string 文本域内容
     * @return string
     */
    function trim_textarea($string) {
        $string = nl2br(str_replace(' ', ' ', $string));
        return $string;
    }

    /**
     * redis队列添加
     * @param type $select      数据库名称
     * @param type $obj         数据
     */
    function redis_add($obj = 1, $key = "id", $select = 0) {
        $redis = new Redis();
        $redis->connect('127.0.0.1', 6379);
        $redis->auth();
        $redis->select($select);
        return $redis->lPush($key, $obj); //加入队列 返回队列总数
    }

    /**
     * 获取Redis队列
     * @param type $key     数据
     * @param type $select
     * @return type
     */
    function redis_sel($key = "id", $select = 0) {
        $redis = new Redis();
        $redis->connect('127.0.0.1', 6379);
        $redis->auth();
        $redis->select($select);
        $id = $redis->lPop($key); //出队
        return $id;
    }

    /**
     * php字符串截取固定值并且多余部分用省略号代替
     * utf8编码下:中文占 3个字节,英文和数字占 1个字节(可变编码)(变长编码)
     * gbk编码下:所有的中文、英文、数字都占2个字节(定长编码)
     * @param type $str     字符串 
     * @param type $len     控制长度
     * @return type
     */
    function GetPartStr($str, $len) {//$str字符串   $len 控制长度
        $one = 0;
        $partstr = '';
        for ($i = 0; $i < $len; $i++) {
            $sstr = substr($str, $one, 1);
            if (ord($sstr) > 224) {
                $partstr .= substr($str, $one, 3);
                $one += 3;
            } elseif (ord($sstr) > 192) {
                $partstr .= substr($str, $one, 2);
                $one += 2;
            } elseif (ord($sstr) < 192) {
                $partstr .= substr($str, $one, 1);
                $one += 1;
            }
        }
        if (strlen($str) < $one) {
            return $partstr;
        } else {
            return $partstr . '....';
        }
    }

    /**
     * 查询快递
     * @param $postcom  快递公司编码
     * @param $getNu  快递单号
     * @return array  物流跟踪信息数组
     */
    function queryExpress($postcom, $getNu) {

        $url = "https://m.kuaidi100.com/query?type=" . $postcom . "&postid=" . $getNu . "&id=1&valicode=&temp=0.49738534969422676";
        $resp = httpRequest($url, "GET");
        return json_decode($resp, true);
    }

    /**
     * 异步上传,直接访问全局文件变量
     * @return type     返回路径
     */
    function ajaxfile() {
        foreach ($_FILES as $key => $val) {
            if (!empty($val) && $val['error'] == 0)
                $fileurl = $this->file_copy($val);
            else
                $fileurl = 0;
            break;
        }
        $fileurl = ltrim($fileurl, "/");

//        echo ($fileurl);
        return $fileurl;
    }

    /**
     * 创建多级目录
     * mkdir()  只能在已经存在的目录中创建创建文件夹(即父级必须有才行)。
     * mkdirs()  可以在不存在的目录中创建文件夹。诸如:a\b,既可以创建多级目录。
     * dirname()  是返回路径中的目录部分。
     * is_dir()  用于判断给出的文件名是否是一个有效的目录
     *
     * */
    function create_folders($dir) {
        return is_dir($dir) or ( $this->create_folders(dirname($dir)) and @ mkdir(iconv("UTF-8", "GBK", $dir), 0777, true));
    }

    /**
     * 上传文件
     * @param type $file    上传的文件
     * @return string       服务器路径
     */
    public function file_copy($file, $bool = true) {
//判断是否存在日期文件
        $filename = "/public/Uploads/file/" . date("Ymd");
        if (!file_exists("." . $filename)) {
            $this->create_folders("." . $filename);
        }
//获取后缀
        $ary = explode('.', $file['name']);
        $su = end($ary);
//文件名
        $filenames = $filename . "/" . time() . rand(1, 10000) . "." . $su;
        move_uploaded_file($file['tmp_name'], "." . $filenames);
        if ($bool)
            $_SESSION['ajaxfile'][] = $filenames;
        return $filenames;
    }

    /**
     * 删除图片
     */
    function delajaxfile($filename) {
        if (isset($_SESSION['ajaxfile'])) {
            //删除图片
            foreach ($_SESSION['ajaxfile'] as $key => $val) {
                if ($val != $filename) {
                    $val2 = "." . $val;
                    if (file_exists($val2)) {
                        $filename2 = trim($val, "/");
                        unlink($filename2);
                    }
                }
                $_SESSION['ajaxfile'][$key] = null;
                unset($_SESSION['ajaxfile'][$key]);
            }
        } else {
            return 0;
        }
    }

    /**
     * 数据插入 特殊字符处理 
     */
    function isyy($ary, $bool = true) {
        //如果是数组
        if ($bool) {
            foreach ($ary as $key => $val) {
                $ary[$key] = addslashes($val);
                if (!is_array($val)) {
                    $ary[$key] = addslashes($val);
                }
            }
        } else {
            $ary = addslashes($ary);
        }
        return $ary;
    }

    /**
     * 获取二维数组中的 某个 值 为索引 某个值 为值 的一维索引数组
     * 适用于以某个唯一索引为外表链接的主表内容 
     * @param type $array       二维数组
     * @param type $keyname     新数组键名
     * @param type $valname     新数组键名对应值
     * @return type
     */
    function aryary21($array = array(), $keyname, $valname) {
        $ary21 = array();
        foreach ($array as $k => $v) {
            $ary21[$v[$keyname]] = $v[$valname];
        }
        return $ary21;
    }

    /**
     * 设置脚本运行时间 为 运行结束
     */
    function client_max_time() {
        set_time_limit(0); //设置不超时,程序一直运行。
        ignore_user_abort(true); //即使Client断开(如关掉浏览器),PHP脚本也可以继续执行.
    }

    /**
     * // 读取nlp text 并存到mongodb
     * @param type $file        要读取的文件
     * @param type $return
     * @return boolean
     */
    public function read_file($filePath = "", $return = array("code" => 200, "msg" => "Success over")) {
        $this->client_max_time();
        $firststr = substr($filePath, 0, 1);
        if ($firststr != "/" && $firststr != ".") {
            $filePath = $_SERVER["DOCUMENT_ROOT"] . "/{$filePath}";
        } else if ($firststr != ".") {
            // $_SERVER["DOCUMENT_ROOT"],获取当前运行脚本所在文档根目录。$filePath为.txt文件所在路径
            $filePath = $_SERVER["DOCUMENT_ROOT"] . $filePath;
        }
        $newfilepath = basename($filePath);
//        var_dump($newfilepath);die;
        try {
            $file = fopen($filePath, "r"); // 以只读的方式打开文件
            if (empty($file)) {
                $return['code'] = 201;
                $return["msg"] = "file not found";
                return $return;
            }
            $i = 0;
            //输出文本中所有的行,直到文件结束为止。
            while (!feof($file)) {
                $itemStr = fgets($file); //fgets()函数从文件指针中读取一行
                //去掉结尾的/r/n
                $itemStr = str_replace(PHP_EOL, '', $itemStr);
                $itemArray = explode(",", $itemStr); // 将tab分割的各部分内容提取出来
                //提取安全码 写入文件
                $part = "safezm=";
                $safezm = substr($itemArray[0], strripos($itemArray[0], $part) + strlen($part)); //截取safezm 参数值
                $msg = $itemStr . ",{$safezm}";
                $this->data_log($msg, $newfilepath); //保存到新文件
                ++$i;
                if ($i % 5000 == 1) {
                    $this->output("已处理{$i}条数据");
                }
            }
            fclose($file); //关闭文件
        } catch (Exception $exception) {
            $return['code'] = $exception->getCode();
            $return['msg'] = $exception->getMessage();
        }
        return $return;
    }

    /**
     * 使用QQ邮箱发送邮件
     * @param type $subject     邮件主题
     * @param type $body        邮件内容
     * @param type $address     收件人--多个收件人用数组传值
     * @param type $fromName    发件人昵称
     * @param type $isHTML      邮件正文是否为html编码
     * @param type $username    SMTP帐号-- QQ邮箱
     * @param type $password    授权码
     * @param type $SMTPDebug   是否开启调试(1|0)
     * @return type
     */
    function send_email_qq($subject = '邮件主题', $body = '<h1>Hello World.test</h1>', $address = "2414599284@qq.com", $fromName = "发件人昵称", $isHTML = false, $username = '1411479499@qq.com', $password = 'nqvvyoyvqitgigbf', $SMTPDebug = 0) {
// 引入PHPMailer的核心文件
        require_once "../classes/PHPMailer-master/src/PHPMailer.php";
        require_once "../classes/PHPMailer-master/src/SMTP.php";
        $mail = new PHPMailer(); // 实例化PHPMailer核心类
//        $SMTPDebug=1;//调试使用
        $mail->SMTPDebug = $SMTPDebug; // 是否启用smtp的debug进行调试 开发环境建议开启 生产环境注释掉即可 默认关闭debug调试模式
        $mail->isSMTP(); // 使用smtp鉴权方式发送邮件
        $mail->SMTPAuth = true; // smtp需要鉴权 这个必须是true
        $mail->Host = 'smtp.qq.com'; // 链接qq域名邮箱的服务器地址
        $mail->SMTPSecure = 'ssl'; // 设置使用ssl加密方式登录鉴权
        $mail->Port = 465; // 设置ssl连接smtp服务器的远程服务器端口号
        $mail->CharSet = 'UTF-8'; // 设置发送的邮件的编码
        $mail->FromName = $fromName; // 设置发件人昵称 显示在收件人邮件的发件人邮箱地址前的发件人姓名
        $mail->Username = $username; // smtp登录的账号 QQ邮箱即可
        $mail->Password = $password; // smtp登录的密码 使用生成的授权码

        $mail->From = $username; // 设置发件人邮箱地址 同登录账号
        $mail->isHTML($isHTML); // 邮件正文是否为html编码 注意此处是一个方法
// 设置收件人邮箱地址
//$mail->addAddress('2456932381@qq.com');
// 添加多个收件人 则多次调用方法即可
        if (is_array($address)) {
            foreach ($address as $val) {
                $mail->addAddress($val);
            }
        } else {
            $mail->addAddress($address);
        }
        $mail->Subject = $subject; // 添加该邮件的主题
// 添加邮件正文
        $mail->Body = $body;
//$mail->addAttachment('./example.pdf');// 为该邮件添加附件
        $status = $mail->send(); // 发送邮件 返回状态
        return $status;
    }

    /**
     * 创建文件并写入数据
     * @param type $obj         要写入数据
     * @param type $filename    要写入文件 的文件名
     * @param type $files       文件隶属 的文件夹
     * @param type $datatime    数据写入开头是否添加时间
     */
    function data_log($obj = "error", $filename = "error.txt", $files = "/error", $datatime = true) {
        $path = dirname(__FILE__);
        $filename = ltrim($filename, "/"); //
        if (strpos($files, $path) === false) {
            $files = $path . $files;
        }
        $files = rtrim($files, "/"); //方便拼接
//        if (empty($files)) {
//            $files .= ".";
//        }
        if (is_object($obj)) {
            $obj = (array) $obj;
        }
        if (is_array($obj)) {
            $this->data_log(print_r($obj, true), $filename, $files);
        } else {
            $msg = $datatime ? date("Y-m-d H:i:s") . "  " . $obj : $obj;
            $files .= "/" . date("Ymd");
            if (!is_dir($files) && $files != "." && !file_exists($files)) {
                $this->create_folders($files); //创建目录
            }
            $filePath = $files . "/{$filename}";
            $fp = @fopen($filePath, "a+"); //尝试打开该文件,如不存在则创建,存在指针移向末尾
            @flock($fp, LOCK_EX | LOCK_NB); //文件上锁
            @fwrite($fp, $msg . "\r\n"); //文件末尾添加换行
            @flock($fp, LOCK_UN); //解锁
            @fclose($fp); //关闭
        }
    }

    /**
     * 读文件
     * @param type $filePath    文件路径
     * @return boolean          文件内容
     * r 只读。在文件的开头开始。
     * r+ 读/写。在文件的开头开始。
     * w 只写。打开并清空文件的内容;如果文件不存在,则创建新文件。
     * w+ 读/写。打开并清空文件的内容;如果文件不存在,则创建新文件。
     * a 追加。打开并向文件文件的末端进行写操作,如果文件不存在,则创建新文件。
     * a+ 读/追加。通过向文件末端写内容,来保持文件内容。
     * x 只写。创建新文件。如果文件已存在,则返回 FALSE。
     * x+ 读/写。创建新文件。如果文件已存在,则返回 FALSE 和一个错误。
     */
    function reading_file($filePath = 'reading_file.log') {
        if (empty($filePath)) {
            return false;
        }
        $files = dirname($filePath);
        if (!is_dir($files) && $files != '.' && !file_exists($files)) {
            $this->create_folders($files); //创建目录
        }
        $str = '';
        //判定文件是否存在
        if (file_exists($filePath) && filesize($filePath) > 0) {
            $fp = @fopen($filePath, 'r'); //只读
            @flock($fp, LOCK_SH | LOCK_NB); //文件上锁 共享锁,避免dirty数据
            $str = @fread($fp, filesize($filePath));
            @flock($fp, LOCK_UN); //解锁
            @fclose($fp); //关闭
        } else {
            //创建该文件
            $fp = @fopen($filePath, 'w'); //
            @fclose($fp);
            /*             * mode 参数由 4 个数字组成:
             * 第一个数字通常是 0
             * 第二个数字规定所有者的权限
             * 第三个数字规定所有者所属的用户组的权限
             * 第四个数字规定其他所有人的权限
             * 可能的值(如需设置多个权限,请对下面的数字进行总计):
             * 1 = 执行权限
             * 2 = 写权限
             * 4 = 读权限
             */
            @chmod($filePath, 0777); //给予文件权限
        }
        return $str;
    }

    /**
     * 写文件
     * @param type $obj         要写入的内容
     * @param type $filePath    写入的文件路径
     * @return boolean          true | false
     */
    function written_file($obj = '', $filePath = 'written_file.log') {
        if (empty($filePath)) {
            return false;
        }
        $files = dirname($filePath);
        if (!is_dir($files) && $files != "." && !file_exists($files)) {
            $this->create_folders($files); //创建目录
        }
        $fp = @fopen($filePath, "w"); //尝试打开该文件,如不存在则创建,且清空文件内容
        @flock($fp, LOCK_EX | LOCK_NB); //文件上锁 排他锁
        @fwrite($fp, $obj); //文件内容写入
        @flock($fp, LOCK_UN); //解锁
        @fclose($fp); //关闭
        $str = $this->reading_file($filePath);
        if ($str == $obj) {
            return true;
        }
        return false;
    }

    /**
     * 纵向数组横向排
     * select 查询数据结果集 纵向数组横向排
     */
    function aryy_x($ary) {
        $ary2 = array(); //返回数组
        $column = array();
        foreach ($ary[0] as $k => $v) {
            $column[] = $k; //字段名
        }
        $arylength = count($ary); //总公多少数据
        $columnlength = count($column); //总公多少字段
        for ($i = 0; $i < $columnlength; $i++) {
            $value = array();
            for ($j = 0; $j < $arylength; $j++) {
                $value[] = $ary[$j][$column[$i]]; //竖排集合
            }
            $ary2[$column[$i]] = $value; //竖排集合 -- 以列名 作为键值
        }
        return $ary2;
    }

    /**
     * 实时输出打印
     * @param type $msg         需要打印的消息
     * @param type $datetime    是否打印时间
     * @param type $sleep       是否需要输出间歇时间
     * @param type $size        缓冲区大小 默认 4096
     * @param type $br          打印BR个数 默认2
     */
    function output($msg = "This is test.", $datetime = true, $sleep = true, $size = '', $br = 2) {
        if ($datetime) {
            echo date("Y-m-d H:i:s");
        }
        if (empty($size)) {
            $size = ini_get('output_buffering');
        }
        if (is_array($msg)) {
            var_dump($msg);
        } else {
            echo "  $msg";
        }
        for ($i = 0; $i < $br; $i++) {
            echo "<br/>";
        }
        echo str_pad(' ', $size); //使缓冲区溢出 复制输出4096个字节
        ob_flush(); //释放php内置缓存
        flush(); //输出送出的缓冲内容 到浏览器
        if ($sleep === true) {
            sleep(1);
        } else if (is_numeric($sleep) && $sleep > 0) {
            sleep($sleep);
        } else {
            //不休息
        }
    }

    /**
     * 数据输出并结束运行
     * @param type $msg     需要打印的数据
     */
    function dump($msg) {
        echo "<pre>";
        print_r($msg);
        echo "</pre>";
        die;
    }

    /**
     * 返回上一页
     * @param type $num     返回的页数,默认返回上一页
     */
    function history($num = 1) {
        echo "<script type='text/javascript'>history.go(-{$num});</script>";
        exit();
    }

    /**
     * URL重定向
     * @param string $url 重定向的URL地址
     * @param integer $time 重定向的等待时间(秒)
     * @param string $msg 重定向前的提示信息
     * @return void
     */
    public function redirect($url, $time = 3, $msg = '') {
        //多行URL地址支持
        $url = str_replace(array("\n", "\r"), '', $url);
        if (empty($msg))
            $msg = "系统将在" . $time . "秒之后自动跳转到" . $url . "!";
        if (!headers_sent()) {
            // redirect
            if (0 === $time) {
                header('Location: ' . $url);
            } else {
                header("refresh:" . $time . ";url=" . $url);
                echo($msg);
            }
            exit();
        } else {
            $str = "<meta http-equiv='Refresh' content='" . $time . ";URL={$url}'>";
            if ($time != 0)
                $str .= $msg;
            exit($str);
        }
    }

    /**
     * 浏览器友好的变量输出
     * @param mixed $var 变量
     * @param boolean $echo 是否输出 默认为True 如果为false 则返回输出字符串
     * @param string $label 标签 默认为空
     * @param boolean $strict 是否严谨 默认为true
     * @return void|string
     */
    function dump2($var, $echo = true, $label = null, $strict = true) {
        $label = ($label === null) ? '' : rtrim($label) . ' ';
        if (!$strict) {
            if (ini_get('html_errors')) {
                $output = print_r($var, true);
                $output = '<pre>' . $label . htmlspecialchars($output, ENT_QUOTES) . '</pre>';
            } else {
                $output = $label . print_r($var, true);
            }
        } else {
            ob_start();
            var_dump($var);
            $output = ob_get_clean();
            if (!extension_loaded('xdebug')) {
                $output = preg_replace('/\]\=\>\n(\s+)/m', '] => ', $output);
                $output = '<pre>' . $label . htmlspecialchars($output, ENT_QUOTES) . '</pre>';
            }
        }
        if ($echo) {
            echo($output);
            return null;
        } else
            return $output;
    }

    /**
     * 计算使用内存
     * @param type $unit        单位,默认kb
     * @param type $bool        是否开启MB以上单位
     * @return type             返回 存储单位
     */
    function memory($unit = "kb", $bool = false) {
        $return = 0;
        $bit = memory_get_usage(); //比特
        $byte = ceil($bit / 8); //字节
        $KiloByte = ceil($byte / 1024); //KB
        $MegaByte = ceil($KiloByte / 1024 * 100) / 100; //MB
        if ($bool) {
            $GigaByte = ceil($MegaByte / 1024 * 100) / 100; //GB
            $TeraByte = ceil($GigaByte / 1024 * 100) / 100; //TB
        }
        switch ($unit) {
            case "bit":
                $return = $bit . " Bit";
                break;
            case "byte":
                $return = $byte . " Byte";
                break;
            case "kb":
                $return = $KiloByte . " KB";
                break;
            case "mb":
                $return = $MegaByte . " MB";
                break;
            case "gb":
                $return = $GigaByte . " GB";
                break;
            case "tb":
                $return = $TeraByte . " TB";
                break;
        }
        return $return;
    }

    /**
     * 链接数据库
     * @param type $database        数据库名称
     * @param type $username        访问用户
     * @param type $password        用户密码
     * @param type $localhost       访问主机地址
     * @return type                 链接标识
     */
    function linkmysql($database = '', $username = '', $password = '', $localhost = '', $port = "") {
        if (empty($this->database)) {
            $this->database = require_once 'databases.php';
            $this->create_database("lianyu");
        }
        if (!empty($this->database)) {
            $database = $database ? $database : $this->database['database'];
            $username = $username ? $username : $this->database['username'];
            $password = $password ? $password : $this->database['password'];
            $localhost = $localhost ? $localhost : $this->database['localhost'];
            $port = $port ? $port : $this->database['port'];
        }
        $conn = @new mysqli($localhost, $username, $password, $database, $port);
        if ($conn->connect_errno) { //返回链接错误号
// 返回链接错误信息
            die("数据库链接失败:" . $conn->connect_error);
        }
        $conn->select_db($database) or die("选择数据库失败:" . $conn->error);
//    3.设置字符集编码
        $conn->set_charset("utf8") or die("设置字符集失败:" . $conn->error);
        $this->mysqli = $conn;
        /**
         * 4准备SQL语句
         *     6. 返回结果集中的字段数
          var_dump($res->field_count);
          返回结果集中的总行数
          var_dump($res->num_rows);
          7. 返回关联数组和索引数组
          var_dump($res->fetch_array());
          返回索引数组
          var_dump($res->fetch_row());
          返回关联数组
          var_dump($res->fetch_assoc());
          返回一个对象
          var_dump($res->fetch_object());

          8. 将结果集指针移到指定位置
          $res->data_seek(0);
          9. 返回结果集中的一个字段,并将指针移到下一列
          var_dump($res->fetch_field());
          直接返回结果集中的所有字段
          var_dump($res->fetch_fields());
         */
        return $conn;
    }

    /**
     * 处理mysql 返回结果集
     * @param type $obj     mysql 结果集
     * @param type $type    转换类型 1为关联数组,2为 索引数组,3为关联索引数组
     * @return array        翻译数组
     */
    function mysql_parsing($obj, $type = 1) {
        $result = array();
        if (!empty($obj)) {
            while ($res = $obj->fetch_assoc()) {
                $result[] = $res;
            }
        }
        return $result;
    }

    /**
     * mysql 直接返回关联数组
     * @param type $sql      sql语句,当不传参时返回数据库所有表
     * @param type $bool     返回结果是否需要处理,默认处理为数组
     * @return string       运行sql结果集,如果未链接数据,则返回503错误
     */
    function query($sql = "show tables", $bool = true) {
        $return = array("msg" => "数据库链接失败", "code" => "503", "state" => 0);
        if (!empty($this->mysqli)) {
            $result = $this->mysqli->query($sql);
            if ($result) {
                if ($bool)
                    return $this->mysql_parsing($result);
                else
                    return $result;
            }
            $return = array(
                "msg" => "错误sql:{$sql}",
                "code" => "400",
                "state" => 0,
            );
        }
        return $return;
    }

    /**
     * 判定表是否存在数据库中
     * @param type $table       表名
     * @param type $database    数据库名
     * @return boolean          如果不存在返回false,如果存在返回表结构
     */
    function exists_table($table, $database = "") {
        $database2 = $database ? $database : $this->database['database'];
//        $this->mysqli->query("drop table ".$table);
        $seltable = "SELECT TABLE_NAME,COLUMN_NAME,IS_NULLABLE,DATA_TYPE,COLUMN_TYPE,COLUMN_KEY,COLUMN_COMMENT "
                . "FROM information_schema.COLUMNS WHERE table_schema = '" . $database2 . "' "//. "#表所在数据库 "
                . "AND table_name = '" . $table . "';"; //#你要查的表
//        $seltable = "SELECT TABLE_NAME AS tableName,TABLE_COMMENT AS tableComment,CREATE_TIME AS createTime "
//                . "FROM information_schema.TABLES "
//                . "WHERE    TABLE_SCHEMA = (SELECT DATABASE ()) and TABLE_NAME = '".$table."' ";//查询表是否存在,存在返回表名和创建时间及注释
        $tabledec = $this->mysqli->query($seltable);
        if ($tabledec->num_rows == 0) {
            /**
             * 判断表创建文件是否存在
             */
            $file_path = "../sql/" . $table . ".php";
            if (file_exists($file_path) && $this->bool) {
                $this->bool = false; //控制建表,防止死循环
                $creatable = require_once "$file_path";
                $this->mysqli->query($creatable);
                return $this->exists_table($table);
            }
            $tabledec = false;
        } else {
            $tabledec = $this->mysql_parsing($tabledec);
        }
        $this->bool = true; //解锁,防止只能创建第一张表
        if ($tabledec === false) {
            $str = "警告!" . $table . "表不存在!";
            $this->data_log($str, "table_err.txt");
            die($str);
        }
        return $tabledec;
    }

    /**
     * 设置数据库某表某列的值
     * @param type $setname     列名称
     * @param type $setvalue    设置值
     * @param type $table       表名
     * @return type             返回受影响行数
     */
    function setField($setname, $setvalue, $table) {
        $sql = "update " . $table . " set `" . $setname . "` = '" . $setvalue . "' where " . $this->where;
        return $this->query($sql);
    }

    /**
     * 
     * @param type $where   数据库检索条件
     */
    function where($where = "") {
        if (empty($where)) {
            $this->where = " 1 ";
        }
        if (is_string($where)) {
            $this->where = $where;
        } else if (is_array($where)) {
            $ary = $this->isyy($where);
            $this->where = "";
            foreach ($ary as $key => $val) {
                if (empty($this->where)) {
                    $this->where.="`" . $key . "` = '" . $val . "'";
                } else {
                    $this->where.=" and `" . $key . "` = '" . $val . "'";
                }
            }
        }
    }

    /**
     * 数据库 一维关联数组 添加数据
     * @param type $data        需要添加的数据
     * @param type $table       需要添加的表
     * @param type $insert_id   是否需要返回自增长ID,默认为返回
     * @return string           返回添加标识
     */
    function insert($data, $table, $insert_id = true) {
        $this->exists_table($table);
        $return = array("msg" => "数据库链接失败", "code" => "503", "state" => 0);
        if (empty($data)) {
            $return = array("msg" => "数据为空", "code" => "417", "state" => 0);
        } else
        if (!empty($this->mysqli)) {
            $data = $this->isyy($data); //去除特殊字符 转义特殊字符,输出如有异常,则使用 stripslashes()
            $sql = "insert into {$table}(";
            foreach ($data as $key => $val) {
                $sql .= "`" . $key . "`,";
            }
            $sql = rtrim($sql, ",");
            $sql .= ") values(";
            foreach ($data as $val) {
                $sql .= "'" . $val . "',";
            }
            $sql = rtrim($sql, ",");
            $sql .= ");";
            if ($result = $this->mysqli->query($sql)) {
                if ($insert_id) {
                    $result = mysqli_insert_id($this->mysqli);
                }
                return $result;
            }
            $return = array(
                "msg" => "错误sql:{$sql}",
                "code" => "400",
                "state" => 0,
            );
        }
        if ($return['code'] > 0) {
            $this->data_log($return['msg'], "insert.sql");
        }
        return $return;
    }

    /**
     * 关闭数据库
     * 
     * @param type $mysql 数据库链接标识
     */
    function closemysql($mysql = 0) {
        //关闭数据库连接
        if (empty($mysql)) {
            return $this->mysqli->close();
        } else {
            return $mysql->close();
        }
    }

    /**
     * 获取客户端IP地址
     * @param integer $type 返回类型 0 返回IP地址 1 返回IPV4地址数字
     * @return mixed
     */
    function get_client_ip($type = 0) {
        $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地址合法验证
        $long = sprintf("%u", ip2long($ip));
        $ip = $long ? array($ip, $long) : array('0.0.0.0', 0);
        return $ip[$type];
    }

//获取用户真实IP
    function get_user_ip() {
        if (getenv('HTTP_CLIENT_IP') && strcasecmp(getenv('HTTP_CLIENT_IP'), 'unknown')) {
            $onlineip = getenv('HTTP_CLIENT_IP');
        } elseif (getenv('HTTP_X_FORWARDED_FOR') && strcasecmp(getenv('HTTP_X_FORWARDED_FOR'), 'unknown')) {
            $onlineip = getenv('HTTP_X_FORWARDED_FOR');
        } elseif (getenv('REMOTE_ADDR') && strcasecmp(getenv('REMOTE_ADDR'), 'unknown')) {
            $onlineip = getenv('REMOTE_ADDR');
        } elseif (isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], 'unknown')) {
            $onlineip = $_SERVER['REMOTE_ADDR'];
        }
        preg_match("/[\d\.]{7,15}/", $onlineip, $onlineipmatches);
        return $onlineipmatches[0] ? $onlineipmatches[0] : $this->get_client_ip();
    }

    // 过滤表单中的表达式
    function think_filter(&$value) {
        // TODO 其他安全过滤
        // 过滤查询特殊字符
        if (preg_match('/^(EXP|NEQ|GT|EGT|LT|ELT|OR|LIKE|NOTLIKE|NOTBETWEEN|NOT BETWEEN|BETWEEN|NOTIN|NOT IN|IN)$/i', $value)) {
            $value .= ' ';
        }
    }

    /**
     * CURL请求
     * @param $url 请求url地址
     * @param $method 请求方法 get post
     * @param null $postfields post数据数组
     * @param array $headers 请求header信息
     * @param bool|false $debug  调试开启 默认false
     * @return mixed
     */
    function httpRequest($url, $method = "GET", $postfields = [], $headers = array(), $debug = false) {
        $method = strtoupper($method);
        $ci = curl_init();
        /* Curl settings */
        curl_setopt($ci, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
        curl_setopt($ci, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 6.2; WOW64; rv:34.0) Gecko/20100101 Firefox/34.0");
        curl_setopt($ci, CURLOPT_CONNECTTIMEOUT, 60); /* 在发起连接前等待的时间,如果设置为0,则无限等待 */
        curl_setopt($ci, CURLOPT_TIMEOUT, 7); /* 设置cURL允许执行的最长秒数 */
        curl_setopt($ci, CURLOPT_RETURNTRANSFER, true);
        switch ($method) {
            case "POST":
                curl_setopt($ci, CURLOPT_POST, true);
                if (!empty($postfields)) {
                    $tmpdatastr = is_array($postfields) ? http_build_query($postfields) : $postfields;
                    curl_setopt($ci, CURLOPT_POSTFIELDS, $tmpdatastr);
                }
                if (empty($headers)) {
                    $postfields = is_array($postfields) ? json_encode($postfields) : $postfields;
                    $headers = [
                        'Content-Type: application/json',
                        'Content-Length: ' . strlen($postfields),
                    ];
                }
                break;
            case "GET":
                $params = "";
                foreach ($postfields as $k => $v) {
                    $params .= $k . "=" . urlencode($v) . "&";
                }
                curl_setopt($ci, CURLOPT_POSTFIELDS, $params);
                break;
            case 'GANK':
                //抓取不需要使用方法
                break;
            default:
                curl_setopt($ci, CURLOPT_CUSTOMREQUEST, $method); /* //设置请求方式 */
                break;
        }
        $ssl = preg_match('/^https:\/\//i', $url) ? TRUE : FALSE;
        curl_setopt($ci, CURLOPT_URL, $url);
        if ($ssl) {
            curl_setopt($ci, CURLOPT_SSL_VERIFYPEER, FALSE); // https请求 不验证证书和hosts
            curl_setopt($ci, CURLOPT_SSL_VERIFYHOST, FALSE); // 不从证书中检查SSL加密算法是否存在
        }
        //curl_setopt($ci, CURLOPT_HEADER, true); /*启用时会将头文件的信息作为数据流输出*/
        curl_setopt($ci, CURLOPT_FOLLOWLOCATION, 1);
        curl_setopt($ci, CURLOPT_MAXREDIRS, 2); /* 指定最多的HTTP重定向的数量,这个选项是和CURLOPT_FOLLOWLOCATION一起使用的 */
        curl_setopt($ci, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($ci, CURLINFO_HEADER_OUT, true);
        /* curl_setopt($ci, CURLOPT_COOKIE, $Cookiestr); * *COOKIE带过去** */
        $response = curl_exec($ci);
        $requestinfo = curl_getinfo($ci);
        $http_code = curl_getinfo($ci, CURLINFO_HTTP_CODE);
        if ($debug) {
            echo "=====post data======\r\n";
            var_dump($postfields);
            echo "=====info===== \r\n";
            print_r($requestinfo);
            echo "=====response=====\r\n";
            print_r($response);
        }
        curl_close($ci);
        return $response;
        //return array($http_code, $response,$requestinfo);
    }

    /**
     * 检查手机号码格式
     * @param $mobile 手机号码
     */
    function check_mobile($mobile) {
        if (preg_match('/1[34578]\d{9}$/', $mobile))
            return true;
        return false;
    }

    /**
     * 检查邮箱地址格式
     * @param $email 邮箱地址
     */
    function check_email($email) {
        if (filter_var($email, FILTER_VALIDATE_EMAIL))
            return true;
        return false;
    }

    /**
     * json格式输出
     * @param type $msg     消息
     * @param type $code    状态码
     */
    function json_output($msg, $code = 1) {
        $data = [
            "msg" => $msg,
            "code" => $code,
        ];
        echo json_encode($data);
        die;
    }

    /**
     *   实现中文字串截取无乱码的方法
     */
    function getSubstr($string, $start, $length) {
        if (mb_strlen($string, 'utf-8') > $length) {
            $str = mb_substr($string, $start, $length, 'utf-8');
            return $str . '...';
        } else {
            return $string;
        }
    }

    /**
     * 是否移动端访问访问
     *
     * @return bool
     */
    function isMobile() {
        // 如果有HTTP_X_WAP_PROFILE则一定是移动设备
        if (isset($_SERVER['HTTP_X_WAP_PROFILE']))
            return true;

        // 如果via信息含有wap则一定是移动设备,部分服务商会屏蔽该信息
        if (isset($_SERVER['HTTP_VIA'])) {
            // 找不到为flase,否则为true
            return stristr($_SERVER['HTTP_VIA'], "wap") ? true : false;
        }
        // 脑残法,判断手机发送的客户端标志,兼容性有待提高
        if (isset($_SERVER['HTTP_USER_AGENT'])) {
            $clientkeywords = array('nokia', 'sony', 'ericsson', 'mot', 'samsung', 'htc', 'sgh', 'lg', 'sharp', 'sie-', 'philips', 'panasonic', 'alcatel', 'lenovo', 'iphone', 'ipod', 'blackberry', 'meizu', 'android', 'netfront', 'symbian', 'ucweb', 'windowsce', 'palm', 'operamini', 'operamobi', 'openwave', 'nexusone', 'cldc', 'midp', 'wap', 'mobile');
            // 从HTTP_USER_AGENT中查找手机浏览器的关键字
            if (preg_match("/(" . implode('|', $clientkeywords) . ")/i", strtolower($_SERVER['HTTP_USER_AGENT'])))
                return true;
        }
        // 协议法,因为有可能不准确,放到最后判断
        if (isset($_SERVER['HTTP_ACCEPT'])) {
            // 如果只支持wml并且不支持html那一定是移动设备
            // 如果支持wml和html但是wml在html之前则是移动设备
            if ((strpos($_SERVER['HTTP_ACCEPT'], 'vnd.wap.wml') !== false) && (strpos($_SERVER['HTTP_ACCEPT'], 'text/html') === false || (strpos($_SERVER['HTTP_ACCEPT'], 'vnd.wap.wml') < strpos($_SERVER['HTTP_ACCEPT'], 'text/html')))) {
                return true;
            }
        }
        return false;
    }

    function is_weixin() {
        if (strpos($_SERVER['HTTP_USER_AGENT'], 'MicroMessenger') !== false) {
            return true;
        } return false;
    }

    function is_qq() {
        if (strpos($_SERVER['HTTP_USER_AGENT'], 'QQ') !== false) {
            return true;
        } return false;
    }

    function is_alipay() {
        if (strpos($_SERVER['HTTP_USER_AGENT'], 'AlipayClient') !== false) {
            return true;
        } return false;
    }

    function ajaxReturn($result = array()) {
        if (is_string($result)) {
            $msg = $result;
            $result = [];
            $result['msg'] = $msg;
        }
        if (empty($result['data'])) {
            $result['data'] = (object) [];
        }
        //
        else if (empty($result['data']['list'])) {
            $result['data']['list'] = [];
        }
        $result['code'] = isset($result['code']) ? $result['code'] : 200;
        $result['msg'] = empty($result['msg']) ? "Success." : $result['msg'];
        header('Content-Type:application/json; charset=utf-8');
        exit(json_encode($result, 256));
    }

    /**
     * 根据ip地址获取地址信息
     * @param string $ip
     * @return bool|mixed
     */
    function GetIpLookup($ip = '') {
        if (empty($ip)) {
            $ip = $this->ip();
        }
        $res = @file_get_contents('http://int.dpool.sina.com.cn/iplookup/iplookup.php?format=js&ip=' . $ip);
        if (empty($res)) {
            return false;
        }
        $jsonMatches = array();
        preg_match('#\{.+?\}#', $res, $jsonMatches);
        if (!isset($jsonMatches[0])) {
            return false;
        }
        $json = json_decode($jsonMatches[0], true);
        if (isset($json['ret']) && $json['ret'] == 1) {
            $json['ip'] = $ip;
            unset($json['ret']);
        } else {
            return false;
        }
        return $json;
    }

    /**
     * 获取客户端IP地址
     * @param integer   $type 返回类型 0 返回IP地址 1 返回IPV4地址数字
     * @param boolean   $adv 是否进行高级模式获取(有可能被伪装)
     * @return mixed
     */
    public function ip($type = 0, $adv = false) {
        $type = $type ? 1 : 0;
        static $ip = null;
        if (null !== $ip) {
            return $ip[$type];
        }

        if ($adv) {
            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(current($arr));
            } elseif (isset($_SERVER['HTTP_CLIENT_IP'])) {
                $ip = $_SERVER['HTTP_CLIENT_IP'];
            } elseif (isset($_SERVER['REMOTE_ADDR'])) {
                $ip = $_SERVER['REMOTE_ADDR'];
            }
        } elseif (isset($_SERVER['REMOTE_ADDR'])) {
            $ip = $_SERVER['REMOTE_ADDR'];
        }
        // IP地址合法验证
        $long = sprintf("%u", ip2long($ip));
        $ip = $long ? [$ip, $long] : ['0.0.0.0', 0];
        return $ip[$type];
    }

    public function getip() {
        if (getenv('HTTP_CLIENT_IP') && strcasecmp(getenv('HTTP_CLIENT_IP'), 'unknown')) {
            $onlineip = getenv('HTTP_CLIENT_IP');
        } elseif (getenv('HTTP_X_FORWARDED_FOR') && strcasecmp(getenv('HTTP_X_FORWARDED_FOR'), 'unknown')) {
            $onlineip = getenv('HTTP_X_FORWARDED_FOR');
        } elseif (getenv('REMOTE_ADDR') && strcasecmp(getenv('REMOTE_ADDR'), 'unknown')) {
            $onlineip = getenv('REMOTE_ADDR');
        } elseif (isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], 'unknown')) {
            $onlineip = $_SERVER['REMOTE_ADDR'];
        }
        preg_match("/[\d\.]{7,15}/", $onlineip, $onlineipmatches);
        return $onlineipmatches[0] ? $onlineipmatches[0] : 'unknown';
    }

    /**
     * 获取时间戳
     * @param type $type 默认0,今日的开始时间和结束时间 | 2=>昨日 | 3=>上周 |4=>本月
     * @return type
     */
    function gettime($type = 0) {
        $time = array();
        switch ($type) {
            case 2:
//php获取昨日起始时间戳和结束时间戳
                $time['start_time'] = mktime(0, 0, 0, date('m'), date('d') - 1, date('Y'));
                $time['end_time'] = mktime(0, 0, 0, date('m'), date('d'), date('Y')) - 1;
                break;
            case 3:
                //php获取上周起始时间戳和结束时间戳
                $time['start_time'] = mktime(0, 0, 0, date('m'), date('d') - date('w') + 1 - 7, date('Y'));
                $time['end_time'] = mktime(23, 59, 59, date('m'), date('d') - date('w') + 7 - 7, date('Y'));
                break;
            case 4:
                //php获取本月起始时间戳和结束时间戳
                $time['start_time'] = mktime(0, 0, 0, date('m'), 1, date('Y'));
                $time['end_time'] = mktime(23, 59, 59, date('m'), date('t'), date('Y'));
                break;
            default:
                //php获取今日开始时间戳和结束时间戳
                $time['start_time'] = mktime(0, 0, 0, date('m'), date('d'), date('Y'));
                $time['end_time'] = mktime(0, 0, 0, date('m'), date('d') + 1, date('Y')) - 1;
                break;
        }
        return $time;
    }

    /**
     * 时间转中文
     * @param type $poortime        所用时间
     */
    function chtime($poortime) {
        $seconds = $poortime;
        $minute = 0; //分
        $hour = 0; //时
        $day = 0; //天
        if ($poortime > 60) {
            $seconds = $poortime % 60;
            $minute = floor($poortime / 60);
            if ($minute > 60) {
                $hour = floor($minute / 60);
                $minute = $minute % 60;
                if ($hour > 24) {
                    $day = floor($hour / 24);
                    $hour = $hour % 24;
                }
            }
        }
        $datatime = "{$day} 天 {$hour} 时 {$minute} 分 {$seconds} 秒";
        return $datatime;
    }

    /**
     * 从服务器下载文件
     * @param type $fileurl     服务器路径
     * @param type $filename    下载到本地的文件名
     */
    function download($fileurl, $filename = "") {
        if (empty($filename)) {
            //获取文件后缀
            $filename = basename($fileurl);
        }
        header("Content-Disposition:  attachment;  filename=" . $filename); //告诉浏览器通过附件形式来处理文件
        header('Content-Length: ' . filesize($fileurl)); //下载文件大小
        readfile($fileurl);  //读取文件内容
    }

    /**
     *  数据导入
     * @param string $file excel文件
     * @param string $sheet
     * @return string   返回解析数据
     * @throws PHPExcel_Exception
     * @throws PHPExcel_Reader_Exception
     */
    function importExecl($file = '', $sheet = 0) {
        $file = iconv("utf-8", "gb2312", $file);   //转码
        if (empty($file) OR ! file_exists($file)) {
            die('file not exists!');
        }
        include ('./Classes/PHPExcel.php'); //必须类
//    include('PHPExcel.php');  //引入PHP EXCEL类
        $objRead = new PHPExcel_Reader_Excel2007();   //建立reader对象
        if (!$objRead->canRead($file)) {
            $objRead = new PHPExcel_Reader_Excel5();
            if (!$objRead->canRead($file)) {
                die('No Excel!');
            }
        }

        $cellName = array('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', 'AA', 'AB', 'AC', 'AD', 'AE', 'AF', 'AG', 'AH', 'AI', 'AJ', 'AK', 'AL', 'AM', 'AN', 'AO', 'AP', 'AQ', 'AR', 'AS', 'AT', 'AU', 'AV', 'AW', 'AX', 'AY', 'AZ');

        $obj = $objRead->load($file);  //建立excel对象
        $currSheet = $obj->getSheet($sheet);   //获取指定的sheet表
        $columnH = $currSheet->getHighestColumn();   //取得最大的列号
        $columnCnt = array_search($columnH, $cellName);
        $rowCnt = $currSheet->getHighestRow();   //获取总行数
//    output("统计完成,共 {$rowCnt} 行数据。");
        $data = array();
        $ALLClass = new ALLClass();
        for ($_row = 1; $_row <= $rowCnt; $_row++) {  //读取内容
            for ($_column = 0; $_column <= $columnCnt; $_column++) {
                $cellId = $cellName[$_column] . $_row;
                $cellValue = $currSheet->getCell($cellId)->getValue();
                //$cellValue = $currSheet->getCell($cellId)->getCalculatedValue();  #获取公式计算的值
                if ($cellValue instanceof PHPExcel_RichText) {   //富文本转换字符串
                    $cellValue = $cellValue->__toString();
                }
                if ($cellName[$_column] == "A") {
                    $cellValue = PHPExcel_Shared_Date::ExcelToPHP($cellValue);
                }
                $data[$_row][$cellName[$_column]] = $cellValue;
            }

            if ($_row % 5000 == 0) {
                $this->output("第 {$_row}  行数据已读取");
//            output($ALLClass->memory());
            }
        }
        $this->output("读取完成,数据存档中。。。");
        return $data;
    }

    /**
     * 处理Excel导出 
     * @param $datas array 设置表格数据 
     * @param $datas array 导出文件名称 
     */
    function excelData($datas, $filename) {
        $filename .= ".xls";
        $str = "<html xmlns:o=\"urn:schemas-microsoft-com:office:office\"\r\nxmlns:x=\"urn:schemas-microsoft-com:office:excel\"\r\nxmlns=\"http://www.w3.org/TR/REC-html40\">\r\n<head>\r\n<meta http-equiv=Content-Type content=\"text/html; charset=utf-8\">\r\n</head>\r\n<body>";
        $str .= "<table border=1>";
//    $str.="<head style='text-align:center;'><h2>曾经沧海难为水,除去巫山不是云</h2></head>";
        $str .= $datas;
        if (is_array($datas)) {
            foreach ($datas as $key => $rt) {
                $str .= "<tr>";
                foreach ($rt as $k => $v) {
                    $str .= "<td>{$v}</td>";
                }
                $str .= "</tr>\n";
            }
        }
        $str .= "</table></body></html>";
        header("Content-Type: application/vnd.ms-excel; name='excel'");
        header("Content-type: application/octet-stream");
        header("Content-Disposition: attachment; filename=" . $filename);
        header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
        header("Pragma: no-cache");
        header("Expires: 0");
        exit($str);
    }

    /**
     * 删除指定目录
     * [delAllFiles description] 删除指定目录
     * @param [type] $dirName [description] 目录
     * @param [type] $file [description] 记录的过程文件
     * @param integer $type [description] 第一次默认打开新文件,第二次调用不打开
     * @return [type]   [description]
     * 
     * 删除一个目录相对比较简单,基本步骤为:

      1、判断是否是目录,是目录则递归调用自己,否则直接删除文件;

      2、判断目录是否为空,不为空 rmdir会抛出错误;

      3、文件权限的问题(window,这个不是什么问题)
     */
    public function delAllFiles($dirName, $file = "./DelLog.txt", $type = 1) {
        $bool = false;
        /**
         * 判断是文件还是文件夹
         */
        if (is_file($dirName)) {
            unlink($dirName); //删除文件
            $this->data_log("{$dirName}清理完成\r\n", $file, "");
            $bool = true;
        }
        if (is_dir($dirName)) {
            $re = $this->checkDir($dirName);
            //默认第一次打开文件
            if ($type) {
                $file = fopen($file, 'a+'); //打开日志文件
            }
            if ($re) {
                $this->delFile($dirName, $file);
            } else {
                fwrite($file, "{$dirName}清理完成\r\n");
            }
            $bool = true;
        }
        return $bool;
    }

    /**
     * 创建excel文件
     */
    function wr_excel() {
        include_once 'public/classes/PHPExcel.php';                            // 插件主文件
        $objExcel = new PHPExcel();
        $objWriter = new PHPExcel_Writer_Excel5($objExcel);     // 用于其他版本格式   
        $objExcel->setActiveSheetIndex(0);
        $objActSheet = $objExcel->getActiveSheet();
//设置当前活动sheet的名称   

        $objActSheet->setTitle('sheet1');

        $objActSheet->setCellValue('A2', '中国11');  // 设置Excel中的内容  A2表示坐标
//生成excel到文件   
        $objWriter->save('./test.xls');
    }

    /**
     * [checkDir description] 检测文件夹是否为空,为空直接删除
     * @param [type] $dirName [description] 文件夹名
     * @return [type]   [description]
     */
    private function checkDir($dirName) {
        $a = scandir($dirName); //列出 images 目录中的文件和目录:
        //只包含.和..目录的文件夹为空文件夹
        if (sizeof($a) == 2) {
            rmdir($dirName);
            return false;
        }
        return true;
    }

    /**
     * [delFile description] 上传文件的方法
     * @param [type] $dirName [description] 目录
     * @param [type] $file [description] 记录的文件
     * @return [type]   [description]
     */
    private function delFile($dirName, $file) {
        $dh = openDir($dirName);
        while ($handle = readdir($dh)) {
            if ($handle == '.' || $handle == '..') {
                continue;
            }

            $resource = $dirName . '/' . $handle;
            //判断是否是文件夹
            if (is_dir($resource)) {
                //判断文件夹是否为空
                $re = $this->checkDir($dirName);
                if ($re) {
                    $this->delAllFiles($resource, $file, 0);
                } else {
                    fwrite($file, "{$resource}清理完成\r\n");
                    continue;
                }
            } else {
                unlink($resource);
                fwrite($file, "{$resource}清理完成\r\n");
            }
        }
//       关掉资源,删除目录
//        closedir($dh); //关闭目录资源 
//        fwrite($file, "{$dirName}清理完成\r\n");
//        rmdir($dirName); //删除空目录 
        //每次目录层级高了就报错,故加个循环处理
        $i = 1;
        while ($i) {
            $re = $this->checkDir($dirName);
//            echo "$dirName $i 次<br/><hr/>";
            $i++;
            if (!$re) {
                $i = 0;
                closedir($dh); //关闭目录资源 
                fwrite($file, "{$dirName}清理完成\r\n");
            }
        }
    }

    /**
     * 获得随机字符串
     * @param int $len          需要的长度
     * @param int $size         是否大写 1为小写 2为大写,0为不变
     * @param boolen $special   是否需要特殊符号
     * @return string           返回随机字符串
     */
    function getRandomStr($len = "4", $size = 1, $special = false) {
        $chars = array(
            "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", "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", "0", "1", "2",
            "3", "4", "5", "6", "7", "8", "9"
        );

        if ($special) {
            $chars = array_merge($chars, array(
                "!", "@", "#", "$", "?", "|", "{", "/", ":", ";",
                "%", "^", "&", "*", "(", ")", "-", "_", "[", "]",
                "}", "<", ">", "~", "+", "=", ",", "."
            ));
        }

        $charsLen = count($chars) - 1;
        shuffle($chars);                            //打乱数组顺序
        $str = '';
        for ($i = 0; $i < $len; $i++) {
            $str .= $chars[mt_rand(0, $charsLen)];    //随机取出一位
        }
        switch ($size) {
            case 0:
                break;
            case 1:
                $str = strtolower($str);
                break;
            case 2:
                $str = strtoupper($str);
                break;
        }
        return $str;
    }

    /**
     * 威盾PHP加密专家解密算法
     * @param type $file_path   要解密的文件路径
     * @param type $file_url    解密之后保存的文件路径
     */
    function weidun_jm($file_path = 'test_jiami/IndexAction.class.php', $file_url = "jiemi.php") {
        $filename = $file_path;
//要解密的文件 
        $lines = file($filename); //0,1,2行  
//第一次base64解密 
        $content = "";
        if (preg_match("/O0O0000O0\('.*'\)/", $lines[1], $y)) {
            $content = str_replace("O0O0000O0('", "", $y[0]);
            $content = str_replace("')", "", $content);
            $content = base64_decode($content);
        }
//第一次base64解密后的内容中查找密钥
        $decode_key = "";
        if (preg_match("/\),'.*',/", $content, $k)) {
            $decode_key = str_replace("),'", "", $k[0]);
            $decode_key = str_replace("',", "", $decode_key);
        }
//查找要截取字符串长度 
        $str_length = "";
        if (preg_match("/,\d*\),/", $content, $k)) {
            $str_length = str_replace("),", "", $k[0]);
            $str_length = str_replace(",", "", $str_length);
        }
//截取文件加密后的密文
        $Secret = substr($lines[2], $str_length);
//echo $Secret;
        $this->data_log("<?php", $file_url);
        $str = base64_decode(strtr($Secret, $decode_key, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'));
        $this->data_log($str, $file_url);
        $this->data_log("?>", $file_url);
//直接还原密文输出
//        echo  base64_decode(strtr($Secret, $decode_key, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'));
    }

    /**
     * PHP截取两个指定字符(串)之间的所有字符。拿到任何地方都可以使用
     */
    function getBetweenAB($str, $begin, $end) {
        if ($begin == '')
            return '';
        $beginPos = mb_strpos($str, $begin);
        if ($beginPos === false)
            return '';       // 起始字符不存在,直接返回空。合理
        $start = $beginPos + mb_strlen($begin);       // 1.1、开始截取下标
        if ($end == '')
            $endPos = mb_strlen($str); // 结束字符不存在,默认截取到字符串末尾。合理
        else
            $endPos = mb_strpos($str, $end, $start); // 1.2、从开始下标之后查找
        if ($endPos === false)
            $endPos = mb_strlen($str);
        $length = $endPos - $start;                   // 2、截取字符的长度
        return mb_substr($str, $start, $length);
    }

}

代码就都在上面了,各位自行更改需要即可。

有时候单纯的搬砖和动脑子的搬砖还是不一样的。

天不老,

情难绝。

心似双丝网,

中有千千结。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值