作者: ethan

  • csv解读bom头问题

    csv文件时业务场景中经常用到的,今天业务场景遇到了csv的bom头引发的一个问题。

    问题

    从csv文件读取数据,写入mysql,下面是库里看起来完全正常的一条数据

    问题来了,当将内容取出,explode拆分后

    $part = [
       0 => '2000117008',
       1 => '600001',
       2 => '1',
       3 => '1'
    ];

    intval($part[0]) 竟然等于 0 ???

    排查

    既然这样,那么肯定,$part[0] 不完全等于 我们所表面看到的 ‘2000117008’

    json_encode($part[0])看一下:

    真相出来了,实际隐藏了一些字节, 而这些恰好就是bom头

    解决

    获取csv内容后,先取出bom头,在取数据插入数据库

    private function dropBom($contents) {
            $charset[1] = substr($contents, 0, 1);
            $charset[2] = substr($contents, 1, 1);
            $charset[3] = substr($contents, 2, 1);
            if (ord($charset[1]) == 239 && ord($charset[2]) == 187 && ord($charset[3]) == 191) {
                $contents = substr($contents, 3);
            }
            return $contents;
        }
  • php正则替换preg_replace_callback

    preg_replace_callback 函数执行一个正则表达式搜索并且使用一个回调进行替换。

    语法

    mixed preg_replace_callback ( mixed $pattern , callable $callback , mixed $subject [, int $limit = -1 [, int &$count ]] )

    这个函数的行为除了可以指定一个 callback 替代 replacement 进行替换字符串的计算,其他方面等同于 preg_replace()。

    参数说明:

    • $pattern: 要搜索的模式,可以使字符串或一个字符串数组。
    • $callback: 一个回调函数,在每次需要替换时调用,调用时函数得到的参数是从subject 中匹配到的结果。
    • $subject: 要搜索替换的目标字符串或字符串数组。
    • $limit: 可选,对于每个模式用于每个 subject 字符串的最大可替换次数。 默认是-1(无限制)。
    • $count: 可选,为替换执行的次数。

    返回值

    如果subject是一个数组, preg_replace_callback()返回一个数组,其他情况返回字符串。 错误发生时返回 NULL。

    如果查找到了匹配,返回替换后的目标字符串(或字符串数组), 其他情况subject 将会无变化返回。

    举例:

    $b = 'dfsdf[2020]dfsdf[2020]';
    $c = preg_replace_callback('/\[(\d+)\]/', function ($matches){return $matches[1];}, $b);
    echo $c . PHP_EOL; // 输出: dfsdf2020dfsdf2020
  • redis列表常用应用场景

    已展示用户的文章列表为例

    require_once '../../CacheRedis.php';
    
    $server = '127.0.0.1:6379';
    $redis = CacheRedis::getInstance($server);
    
    // 用户的文章列表
    $user_id = 12;
    $key = 'user:article:list:' . $user_id;
    $article_ids = [1,2,3,4,5,6,7,8,9,10];
    
    // 模拟用户发布文章流程
    foreach ($article_ids as $article_id) {
        // 选取lpush或rpush要根据业务场景,我们这里是想要优先展示最新的文章
        $res = $redis->lPush($key, $article_id);
        $res = $redis->expire($key, 5);
    }
    
    // 模拟访问用户文章列表流程
    $page = 0;
    $page_count = 2;
    do {
        $start = $page * $page_count;
        $end = $start + $page_count - 1;
        // 要注意, end是结束为止的下标
        if (!$redis->exists($key)) {
            // 从db获取文章列表
            // 种缓存
        }
        $list = $redis->lRange($key, $start, $end);
        if (empty($list)) {
            break;
        }
        var_dump($list);
        $page++;
    } while(true);
    
    // 模拟用户下线/删除文章流程
    $res = $redis->del($key);
    
    
    // ps: 列表一般只存id, 具体内容,通过id再去查string,hash等, 尽量保证数据缓存的唯一性,避免修改清缓存时需清多处缓存

    推荐相关精品课程: redis基础&实战教程

  • goland提取特殊字符

    提取键盘所有可输入特殊字符

    func GetSpecialNum(text string) int {
    	rCharacter := regexp.MustCompile("[`~!@#$%^&*()_\\-+=<>?:\"{}|,.\\/;'\\\\[\\]·~!@#¥%……&*()——\\-+={}|《》?:“”【】『』「」、;‘',。、]")
    	return len(rCharacter.FindAllStringSubmatch(text,-1))
    }
  • goland提取英文、数字、中文字符

    提取所含A-Za-z的字符数

    func GetEnglishNum(text string) int {
    	rCharacter := regexp.MustCompile("[a-zA-Z]")
    	return len(rCharacter.FindAllStringSubmatch(text,-1))
    }

    提取所含数字0-9的字符数

    func GetNumberNum(text string) int {
    	rCharacter := regexp.MustCompile(`\d`)
    	return len(rCharacter.FindAllStringSubmatch(text,-1))
    }

    提取所含中文字符数

    func GetChineseNum(text string) int {
    	num := 0
    	for _, char := range text{
    		if unicode.Is(unicode.Han, char){
    			num++
    		}
    	}
    	return num
    }
  • goland提取中文

    // 提取所含中文字符数
    func GetChineseNum(text string) int {
    	num := 0
    	for _, char := range text{
    		if unicode.Is(unicode.Han, char){
    			num++
    		}
    	}
    	return num
    }
  • goland提取emoji表情

    提取字符串中emoji表情的个数:

    func GetEmojiNum(text string) int {
    	num := 0
    	for _, value := range text {
    		_, size := utf8.DecodeRuneInString(string(value))
    		if size > 3 {
    			num++
    		}
    	}
    	return num
    }
  • php关于json_encode接口输出问题

    今天线上遇到一个问题,以数字为键的数组,通过json_encode接口输出后,接口中的数组自动按照键值从小到大排序。

    这种问题是浏览器读取json字符串的自动处理,程序上无法控制,如果需要保证数组的有序的话,需要将键改为非数字。

  • 平凡之路-朴树

    作曲 : 朴树
    作词 : 朴树/韩寒
    编曲:朴树
    徘徊着的 在路上的
    你要走吗 via via
    易碎的 骄傲着
    那也曾是我的模样
    沸腾着的 不安着的
    你要去哪 via via
    谜一样的 沉默着的
    故事你真的在听吗
    我曾经跨过山和大海
    也穿过人山人海
    我曾经拥有着一切
    转眼都飘散如烟
    我曾经失落失望失掉所有方向
    直到看见平凡才是唯一的答案
    当你仍然
    还在幻想
    你的明天 via via
    她会好吗 还是更烂
    对我而言是另一天
    我曾经毁了我的一切
    只想永远地离开
    我曾经堕入无边黑暗
    想挣扎无法自拔
    我曾经像你像他像那野草野花
    绝望着 渴望着
    也哭也笑平凡着


    jia do
    la so
    哦~
    向前走 就这么走
    就算你被给过什么
    向前走 就这么走
    就算你被夺走什么
    向前走 就这么走
    就算你会错过什么
    向前走 就这么走
    就算你会
    我曾经跨过山和大海
    也穿过人山人海
    我曾经拥有着一切
    转眼都飘散如烟
    我曾经失落失望失掉所有方向
    直到看见平凡才是唯一的答案
    我曾经毁了我的一切
    只想永远地离开
    我曾经堕入无边黑暗
    想挣扎无法自拔
    我曾经像你像他像那野草野花
    绝望着 渴望着 也哭也笑平凡着
    我曾经跨过山和大海
    也穿过人山人海
    我曾经问遍整个世界
    从来没得到答案
    我不过像你像他像那野草野花
    冥冥中这是我 唯一要走的路啊
    时间无言
    如此这般
    明天已在 via via
    风吹过的 路依然远
    你的故事讲到了哪

  • PHP ISO-8859-1转utf-8

    今天线上遇到了一个问题,上传的csv文件在按行取出时,有的数据行文本是ISO-8859-1编码,导致出现乱码。

    判断文本编码

    $fileType = mb_detect_encoding($str , array('ASCII','gb2312','UTF-8','GBK','LATIN1','BIG5')) ;

    编码转换

    方法一

    conv($from, $to, $str);

    方法二

    mb_convert_encoding($str, $to, $from);

    ISO-8859-1编码特殊处理

    方法一:

    utf8_encode($str) // php 方法,不一定有效 (个人业务场景尝试,无效)

    方法二

    $str = mb_convert_encoding($str, 'UTF-8', "GBK"); 
    $str = str_replace('uf8f5', '', $str);
    //方法二: 个人业务场景尝试, 有效