zoukankan      html  css  js  c++  java
  • 一些php常用函数积累

    本文链接
    <?php
    
    // id: ecffe70d3af54df9bad97b61918ace7d 
    global $ct_path, $ct_log_path;
    $log_path = "test_php.txt";
    // 是否先log到buffer,再通过CT_flush()一次性写入文件
    $ct_log_buffer = true;
    $CT_off = true;
    $request_num = uniqid();
    $CT_format = "";
    
    if ($ct_path) {
        $dir = dirname($ct_path);
        if (!file_exists($dir)) {
            mkdir($dir, 0777, true);
        }
        $file = fopen($ct_path, "a+");
        $file_ct_log = $file;
    }
    if ($ct_log_path) {
        $dir = dirname($ct_log_path);
        if (!file_exists($dir)) {
            mkdir($dir, 0777, true);
        }
        $file_ct_log = fopen($ct_log_path, "a+");
    }
    
    $ct_buffer = [];
    
    $path_my = __DIR__ . "/common.my.php";
    if (is_file($path_my)) {
        require $path_my;
    }
    
    function clear_log() {
       Global $log_path;
       unlink($log_path);
    }
    
    function clog($content, $with_lf = true) {
       Global $log_path;
       $file = fopen($log_path,"a+");
       fwrite($file, $content);
       CT_log($content);
       if($with_lf) {
          fwrite($file, "
    ");
          CT_log("
    ");
       }
       fclose($file);
    
    }
    
    function get_safe($obj, $key, $def = NULL) {
       if(isset($obj[$key])) {
          return $obj[$key];
       }
       return $def;
    }
    
    function get_stack_trace($title = "") {
       $html = "=================stack trace:".$title."
    ";
       $array =debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
       foreach($array as $row) {
          $html .= sprintf("file:%s, line:%d, class:%s, function:%s
    ",
             get_safe($row, 'file'), get_safe($row, 'line'), get_safe($row, 'class'), get_safe($row, 'function'));
       }
       return $html;
    }
    
    function log_stack_trace($title = "") {
       clog(get_stack_trace($title));
    }
    
    // error handler function with stack trace.
    // use like this:
    // $old_error_handler = set_error_handler("err_handler");
    function err_handler($errno, $errstr, $errfile, $errline)
    {
       $errno_map = array(1 => "E_ERROR", 2 => "E_WARNING", 4 => "E_PARSE", 8 => "E_NOTICE",
          16 => "E_CORE_ERROR", 32 => "E_CORE_WARNING", 64 => "E_COMPILE_ERROR",
          128 => "E_COMPILE_WARNING", 256 => "E_USER_ERROR", 512 => "E_USER_WARNING", 
          1024 => "E_USER_NOTICE", 2048 => "E_STRICT", 4096 => "E_RECOVERABLE_ERROR",
          8192 => "E_DEPRECATED", 16384 => "E_USER_DEPRECATED", 32767 => "E_ALL");
       clog(sprintf("------------ %s(%d), msg:%s", $errno_map[$errno], $errno, $errstr));
       log_stack_trace("");
       /* Don't execute PHP internal error handler */
       return true;
    }
    
    // 获取当前系统时间,返回float格式,单位:秒
    function get_time() {
       date_default_timezone_set('Asia/Shanghai');
       list($usec, $sec) = explode(" ", microtime());
       return ((float)$usec + (float)$sec);
    }
    
    function get_prefix() {
        return "";
        Global $ip, $pid;
        if(!isset($ip)) {
            $pid = getmypid();
            $ip = $_SERVER['REMOTE_ADDR'];
        }
        return $pid.' '.$ip.' '.date("m-d H:i:s ");
    }
    
    function CT($content) {
        Global $CT_off, $file;
        if($CT_off || !$file)
            return;
    
        Global $last_time, $first_time, $is_first, $ct_log_buffer, $ct_buffer, $request_num, $CT_format;
        if ($CT_format == "raw") {
            $all_out = $content . "
    ";
        } else {
            // 通过stack trace计算缩进
            $array =debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
            $ignore_count = 0;
            $count = count($array);
            $ignore_names = ["call_user_func_array", "call_user_func", "spl_autoload_call"];
            $ignore_classes = ["ReflectionClass"];
            for ($i = 2; $i < $count; $i++) {
                $frame = $array[$i];
                if (in_array($frame["function"], $ignore_names) || isset($frame["class"]) && in_array($frame["class"], $ignore_classes)) {
                    $ignore_count++;
                }
            }
            $all_out = get_prefix() . str_pad("", $count - 2 - $ignore_count, " ") . $request_num . " " . $content;
            $cur_time=get_time();
            if(!$is_first) {
                $is_first = true;
                $last_time = $first_time = $cur_time;
            }
            $total_time=$cur_time-$first_time;
            $delta_time=$cur_time-$last_time;
            $overtime_flag = "";
            // 添加超时标记
            if($delta_time * 1000 > 10)
                $overtime_flag = "----overtime";
    
            $all_out = $all_out." cur_time: $cur_time, total_time: $total_time, delta_time: $delta_time $overtime_flag
    ";
            $last_time=$cur_time;
        }
    
        if ($ct_log_buffer === true) {
            $ct_buffer[] = $all_out;
        } else {
            fwrite($file, $all_out);
        }
    }
    
    /**
     * 将buffer的CT内容写入文件
     * @param boolean turn_off_buffer, 完成后是否关闭buffer,以保证通过register_shutdown_function等调用的函数能够被输出
     */
    function CT_flush($turn_off_buffer)
    {
        global $file, $ct_buffer, $ct_log_buffer;
        if (!$file) {
            return;
        }
        fwrite($file, join("", $ct_buffer));
        $ct_buffer = [];
        $ct_log_buffer = !$turn_off_buffer;
    }
    
    function CT_log($content = "", $path = NULL) {
        Global $file_ct_log;
        if (!$file_ct_log && !$path) {
            return;
        }
        $content = get_prefix().print_r($content, true)."
    ";
        if($path) {
            file_create_path($path);
            $file = fopen($path, "a+");
            if($file) {
                fwrite($file, $content);
                fclose($file);
            }
        }
        else {
            fwrite($file_ct_log, $content);
        }
    }
    
    /**
     * 日志输出,使用info level
     * @param $content
     * @param array $params
     * @param string $logger
     */
    function slog($content, $params = [], $logger = "default")
    {
        SeasLog::info($content, $params, $logger);
    }
    
    /**
     * 日志输出,使用debug level
     * @param $content
     * @param array $params
     * @param string $logger
     */
    function slog_debug($content, $params = [], $logger = "default")
    {
        SeasLog::debug($content, $params, $logger);
    }
    
    /**
     * 日志输出,使用error level
     * @param $content
     * @param array $params
     * @param string $logger
     */
    function slog_error($content, $params = [], $logger = "default")
    {
        SeasLog::error($content, $params, $logger);
    }
    
    /**
     * 日志输出,使用warning level
     * @param $content
     * @param array $params
     * @param string $logger
     */
    function slog_warning($content, $params = [], $logger = "default")
    {
        SeasLog::warning($content, $params, $logger);
    }
    
    /*
        获取指定的http response header 值。
        eg:
        HTTP/1.1 200 OK
        Server: Tengine/2.1.2
        Date: Sun, 02 Apr 2017 02:49:34 GMT
        Content-Type: text/html; charset=gb2312
        Content-Length: 124378
        Connection: keep-alive
        Cache-Control: private
        X-AspNetMvc-Version: 4.0
        X-AspNet-Version: 4.0.30319
    */
    function curl_get_header($ch, $response, $key)
    {
        $header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
        $header = substr($response, 0, $header_size);
        // header processing
        $header_arr = explode("
    ", $header);
    
        $value = "";
        $key .= ":";
        foreach ($header_arr as $entry) {
            if (!strncmp($entry, $key, strlen($key))) {
                $value = trim(substr($entry, strlen($key)));
                break;
            }
        }
        return $value;
    }
    
    // 获取response状态码
    function curl_get_status($ch, $response)
    {
        $header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
        $header = substr($response, 0, $header_size);
        $header_arr = explode("
    ", $header);
        return explode(" ", $header_arr[0])[1];
    }
    
    function startsWith($haystack, $needle)
    {
        // search backwards starting from haystack length characters from the end
        return $needle === "" || strrpos($haystack, $needle, -strlen($haystack)) !== FALSE;
    }
    
    // http 301 is handled.
    function http_get_core($url, &$status = null)
    {
        CT_log("-----------http_get:" . $url);
        $ch = curl_init();
        $status = -1;
    
        // 301 最多嵌套3次。
        for ($i = 0; $i < 3; $i++) {
            $options = array(
                CURLOPT_HEADER => 1,
                CURLOPT_POST => 0,            // 请求方式为POST
                CURLOPT_URL => $url,      // 请求URL
                CURLOPT_RETURNTRANSFER => 1,  // 获取请求结果
                CURLOPT_TIMEOUT_MS => 30000,    // 超时时间(ms)
                CURLOPT_POSTFIELDS => http_build_query(array()), // 注入接口参数
                CURLOPT_SSL_VERIFYPEER => 0,  // 不验证证书
            );
            curl_setopt_array($ch, $options);
            curl_setopt($ch, CURLOPT_ENCODING, "gzip,deflate"); // 百度不支持
            curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
    
            if (($response = curl_exec($ch))) {
                // 有的网站header、<head>指定的编码不一致,会导致乱码。因此如果有编码信息,将其转送到client。
                $content_type = curl_get_header($ch, $response, "Content-Type");
                if($content_type) {
                    header("Content-Type: " . $content_type);
                }
    
                $header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
                $status = $code = curl_get_status($ch, $response);
                if ($code == 301 || $code == 302) {
                    $redirect_url = curl_get_header($ch, $response, "Location");
                    $parsed_re = parse_url($redirect_url);
                    if(isset($parsed_re["host"])) {
                        $url = $redirect_url;
                    }
                    else {
                        $parsed = parse_url($url);
                        if(startsWith($redirect_url, "/")) {
                            $url = $parsed["schema"]. "://" . $parsed["host"] . $redirect_url;
                        }
                        else {
                            // TODO 相对路径拼接
                            $content =  "relative path TODO";
                            curl_close($ch);
                            return $content;
                        }
                    }
                    continue;
                } else if ($code == 404) {
                    header("Status: 404 Not Found");
                    $msg = array(
                        "status" => 404
                    );
                    $content = "<p id='http_util_message_block' style='display: none'>" . json_encode($msg) . "</p>";
                    $content .= "404, not found!";
                } else if ($code == 200) {
                    $content = substr($response, $header_size);
                } else {
                    $content = "http error, code=" . $code . "
    " . substr($response, $header_size);
                }
            } else {
                $msg = array(
                    "status" => -1
                );
                $content = "<p id='http_util_message_block' style='display: none'>" . json_encode($msg) . "</p>";
                $content .= "invoke error[" . curl_error($ch) . "]";
            }
            curl_close($ch);
            return $content;
        }
    }
    
    // 递归为path创建必要的路径
    function file_create_path($path)
    {
        $dir = dirname($path);
        if ($dir && !file_exists($dir)) {
            mkdir($dir, 0755, true);
        }
    }
    
    // $save_path 需要gbk编码
    function file_save($content, $save_path, $append)
    {
        file_create_path($save_path);
        if ($append) {
            $file = fopen($save_path, "a+");
            if ($file) {
                fwrite($file, $content);
                fclose($file);
            }
        } else {
            file_put_contents($save_path, $content);
        }
    }
    
    // 默认的curl封装
    function curl_do($url, $close_after_use = true)
    {
        CT_log("curl_do: " . $url);
        $ch = curl_init();
    
        $options = array(
            CURLOPT_HEADER => 0,
            CURLOPT_POST => 0,            // 请求方式为POST
            CURLOPT_URL => $url,      // 请求URL
            CURLOPT_RETURNTRANSFER => 1,  // 获取请求结果
            CURLOPT_TIMEOUT_MS => 30000,    // 超时时间(ms)
            CURLOPT_POSTFIELDS => http_build_query(array()), // 注入接口参数
            CURLOPT_SSL_VERIFYPEER => 0,  // 不验证证书
        );
    
        curl_setopt_array($ch, $options);
        curl_setopt($ch, CURLOPT_ENCODING, "gzip");
        $response = curl_exec($ch);
        $err = curl_error($ch);
        if ($err) {
            CT_log("curl error: " . $err);
        }
        if ($close_after_use) {
            curl_close($ch);
        }
        return array("handle" => $ch, "response" => $response, "err" => $err);
    }
    
    /**
     * url拼接,没有处理user,pass两个components
     * 详细定义参见单元测试
     * @param $url
     * @param $base
     * @return string
     */
    function get_absolute_url($url, $base)
    {
        // 两种情况直接返回$url:
        if (!$base)
            return $url;
        $url_host = parse_url($url, PHP_URL_HOST);
        if ($url_host) {
            return $url;
        }
    
        $base_parsed = parse_url($base);
        $base_scheme = get_safe($base_parsed, "scheme", "");
        $base_host = get_safe($base_parsed, "host", "");
        $base_port = isset($base_parsed["port"]) ? ":" . $base_parsed["port"] : "";
        $base_path = get_safe($base_parsed, "path");
    
        if ($base_host) {
            $base_calc = $base_scheme . "://" . $base_host . $base_port;
            if (startsWith($url, "/")) {
                return $base_calc . $url;
            } else if ($base_path) {
                $pos = strrpos($base_path, "/");
                if ($pos !== false) {
                    $dir = substr($base_path, 0, $pos + 1); // with last "/"
                    return $base_calc . $dir . $url;
                } else {
                    return $base_calc . "/" . $url;
                }
            } else {
                return $base_calc . "/" . $url;
            }
        } else {
            if (startsWith($url, "/")) {
                return $url;
            } else if ($base_path) {
                $pos = strrpos($base_path, "/");
                if ($pos !== false) {
                    $dir = substr($base_path, 0, $pos + 1); // with last "/"
                    return $dir . $url;
                } else {
                    return $url;
                }
            } else {
                return $url;
            }
        }
    }
    
    function get_absolute_url_tests()
    {
        // empty tests
        $tests[] = [null, null, null];
        $tests[] = ["", null, ""];
        $tests[] = [null, "", null];
        $tests[] = ["", "", ""];
    
        $tests[] = [null, "/", "/"];
        $tests[] = [null, "/a", "/"];
        $tests[] = [null, "/a/", "/a/"];
    
        $tests[] = ["a.html", "b", "a.html"];
        $tests[] = ["a.html", "", "a.html"];
        $tests[] = ["a.html", "/", "/a.html"];
        $tests[] = ["a/b/c/a.html", "http://1.1.1.1", "http://1.1.1.1/a/b/c/a.html"];
        $tests[] = ["a.html", "http://1.1.1.1:83", "http://1.1.1.1:83/a.html"];
        $tests[] = ["a.html", "http://1.1.1.1:83/", "http://1.1.1.1:83/a.html"];
        $tests[] = ["a.html", "http://1.1.1.1:83/a/b", "http://1.1.1.1:83/a/a.html"];
        $tests[] = ["a.html", "http://1.1.1.1:83/?", "http://1.1.1.1:83/a.html"];
        $tests[] = ["a.html", "http://1.1.1.1:83?", "http://1.1.1.1:83/a.html"];
        $tests[] = ["a.html", "http://1.1.1.1:83?a=b", "http://1.1.1.1:83/a.html"];
        $tests[] = ["a.html", "https://1.1.1.1:83?a=b#1", "https://1.1.1.1:83/a.html"];
        $tests[] = ["a.html", "www.baidu.com?a=b#1", "a.html"]; // www被认为是path
    
        // starts with "/"
        $tests[] = ["/a.html", "b", "/a.html"];
        $tests[] = ["/a.html", "", "/a.html"];
        $tests[] = ["/a.html", "/", "/a.html"];
        $tests[] = ["/a/b/c/a.html", "http://1.1.1.1", "http://1.1.1.1/a/b/c/a.html"];
        $tests[] = ["/a.html", "http://1.1.1.1:83", "http://1.1.1.1:83/a.html"];
        $tests[] = ["/a.html", "http://1.1.1.1:83/", "http://1.1.1.1:83/a.html"];
        $tests[] = ["/a.html", "http://1.1.1.1:83/a/b", "http://1.1.1.1:83/a.html"];
        $tests[] = ["/a.html", "http://1.1.1.1:83/?", "http://1.1.1.1:83/a.html"];
        $tests[] = ["/a.html", "http://1.1.1.1:83?", "http://1.1.1.1:83/a.html"];
        $tests[] = ["/a.html", "http://1.1.1.1:83?a=b", "http://1.1.1.1:83/a.html"];
        $tests[] = ["/a.html", "https://1.1.1.1:83?a=b#1", "https://1.1.1.1:83/a.html"];
        $tests[] = ["/a.html", "www.baidu.com?a=b#1", "/a.html"]; // www被认为是path
    
        $r = true;
        foreach ($tests as $test) {
            $abs = get_absolute_url($test[0], $test[1]);
            echo $abs . "
    ";
            if ($abs !== $test[2]) {
                $r = false;
                break;
            }
        }
        echo "pass: " . $r . "
    ";
    
        // return self tests
        $tests_self = [];
        $tests_self[] = ["http://test.com/a.html", "b", ""];
        $tests_self[] = ["http://test.com/a.html", "", ""];
        $tests_self[] = ["http://test.com/a.html", "/", ""];
        $tests_self[] = ["http://test.com/a/b/c/a.html", "http://1.1.1.1", ""];
        $tests_self[] = ["http://test.com/a.html", "http://1.1.1.1:83", ""];
        $tests_self[] = ["http://test.com/a.html", "http://1.1.1.1:83/", ""];
        $tests_self[] = ["http://test.com/a.html", "http://1.1.1.1:83/a/b", ""];
        $tests_self[] = ["http://test.com/a.html", "http://1.1.1.1:83/?", ""];
        $tests_self[] = ["http://test.com/a.html", "http://1.1.1.1:83?", ""];
        $tests_self[] = ["http://test.com/a.html", "http://1.1.1.1:83?a=b", ""];
        $tests_self[] = ["http://test.com/a.html", "https://1.1.1.1:83?a=b#1", ""];
        $tests_self[] = ["http://test.com/a.html", "www.baidu.com?a=b#1", ""]; // www被认为是path
    
        echo "-------------------return self test--------:
    ";
        $r = true;
        foreach ($tests_self as $test) {
            $abs = get_absolute_url($test[0], $test[1]);
            echo $abs . "
    ";
            if ($abs !== $test[0]) {
                $r = false;
                break;
            }
        }
        echo "pass: " . $r . "
    ";
    }
    
    /**
     * 路径规范化。
     * eg:
     * a/../b => b
     * ../a/../../b => ../b
     * ./a/../b => ./b
     * @param $path
     * @return mixed|string
     */
    function normalize_path($path)
    {
        if (!$path) {
            return $path;
        }
        $path = str_replace("\", "/", $path);
    
        $dotdotCount = 0; // 以".."开头的处理
        $arr = explode("/", $path);
        $pathStack = [];
        foreach ($arr as $ele) {
            if ($ele !== "..") {
                array_push($pathStack, $ele);
            } else {
                if (count($pathStack) === 0) {
                    $dotdotCount++;
                } else {
                    array_pop($pathStack);
                }
            }
        }
        unset($ele);
    
        $r = str_pad("", $dotdotCount, "../");
        foreach ($pathStack as $path) {
            if ($r === "") {
                $r = $path;
            } else {
                $r .= "/" . $path;
            }
        }
        return $r;
    }
    
    // 尝试gbk、utf-8两种编码;优先尝试传入编码
    function is_file_ex($path)
    {
        if (is_file($path)) {
            return true;
        }
        $enc = mb_detect_encoding($path, "gb2312", true);
        if ($enc === 'EUC-CN') {
            $path2 = iconv("gbk", "utf-8", $path);
        } else {
            $path2 = iconv("utf-8", "gbk", $path);
        }
        return is_file($path2);
    }
    
    // 尝试gbk、utf-8两种编码;优先尝试传入编码
    function file_get_contents_ex($path)
    {
        if (is_file($path)) {
            return file_get_contents($path);
        }
        $enc = mb_detect_encoding($path, "gb2312", true);
        if ($enc === 'EUC-CN') {
            $path2 = iconv("gbk", "utf-8", $path);
        } else {
            $path2 = iconv("utf-8", "gbk", $path);
        }
        if (is_file($path2)) {
            return file_get_contents($path2);
        }
        return false;
    }
    
    // 创建文件lock,如果路径不存在则创建之
    function create_file_lock($path, &$output = null)
    {
        file_create_path($path);
        $f = null;
        // 不使用"@",这样忽略文件存在的报错,其他异常返回(如权限问题)
        try {
            $f = fopen($path, "x");
        } catch (Exception $e) {
            $msg = $e->getMessage();
            if (strpos($msg, "File exists") === false && strpos($msg, "文件已存在") === false) {
                $output = $e->getMessage() . "
    " . $e->getTraceAsString();
            }
        }
        return $f;
    }
    
    // 关闭、释放文件lock
    function release_file_lock($f, $path)
    {
        if ($f) {
            fclose($f);
            unlink($path);
        }
    }
    
    /**
     * echo udate('Y-m-d H:i:s.u T');
     * @param string $format
     * @param null $utimestamp
     * @return false|string
     */
    function udate ($format = 'u', $utimestamp = null)
    {
        if (is_null($utimestamp))
            $utimestamp = microtime(true);
    
        $timestamp = floor($utimestamp);
        $milliseconds = round(($utimestamp - $timestamp) * 1000000);
    
        return date(preg_replace('`(?<!\\)u`', $milliseconds, $format), $timestamp);
    }
    ?>
  • 相关阅读:
    luogu1210 回文检测
    luogu2420 让我们异或吧
    luogu4151 最大XOR和路径
    线性基
    博弈论(扯淡)
    矩阵求逆 模板
    luogu2513 逆序对数列
    洛谷4316 绿豆蛙的归宿(DAG递推/概率dp)
    1898: [Zjoi2005]Swamp 沼泽鳄鱼
    矩阵
  • 原文地址:https://www.cnblogs.com/yizijianxin/p/12049563.html
Copyright © 2011-2022 走看看