2019-12-16

本文链接

// id: ecffe70d3af54df9bad97b61918ace7dglobal $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,"\n"); CT_log("\n"); }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."\n"; $array =debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);foreach($arrayas $row) { $html .=sprintf("file:%s, line:%d, class:%s, function:%s\n", 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 ."\n";    }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\n";        $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)."\n";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("\r\n", $header);    $value ="";    $key .=":";foreach ($header_arras $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("\r\n", $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、指定的编码不一致,会导致乱码。因此如果有编码信息,将其转送到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 ="

";                $content .="404, not found!";            }else if ($code == 200) {                $content =substr($response, $header_size);            }else {                $content ="http error, code=" . $code ."\n" .substr($response, $header_size);            }        }else {            $msg =array("status" => -1            );            $content ="";            $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 ($testsas $test) {        $abs = get_absolute_url($test[0], $test[1]);echo $abs ."\n";if ($abs !== $test[2]) {            $r =false;break;        }    }echo "pass: " . $r ."\n";// 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--------:\n";    $r =true;foreach ($tests_selfas $test) {        $abs = get_absolute_url($test[0], $test[1]);echo $abs ."\n";if ($abs !== $test[0]) {            $r =false;break;        }    }echo "pass: " . $r ."\n";}/**

* 路径规范化。

* 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 ($arras $ele) {if ($ele !=="..") {array_push($pathStack, $ele);        }else {if (count($pathStack) === 0) {                $dotdotCount++;            }else {array_pop($pathStack);            }        }    }unset($ele);    $r =str_pad("", $dotdotCount,"../");foreach ($pathStackas $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() ."\n" . $e->getTraceAsString();        }    }return $f;}// 关闭、释放文件lockfunction 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('`(?, $milliseconds, $format), $timestamp);}?>

你可能感兴趣的:(2019-12-16)