分类 默认分类 下的文章

json 格式化打印

想练手的可以手写一个出来,比如

<?php
class Helper{
    public static function jsonFormat($data, $indent=null){
        // 对数组中每个元素递归进行urlencode操作,保护中文字符
        array_walk_recursive($data, [self::class,'jsonFormatProtect']);

        // json encode
        $data = json_encode($data);

        // 将urlencode的内容进行urldecode
        $data = urldecode($data);

        // 缩进处理
        $ret = '';
        $pos = 0;
        $length = strlen($data);
        $indent = isset($indent)? $indent : '    ';
        $newline = PHP_EOL;
        $prevchar = '';
        $outofquotes = true;

        for($i=0; $i<=$length; $i++){

            $char = substr($data, $i, 1);

            if($char=='"' && $prevchar!='\\'){
                $outofquotes = !$outofquotes;
            }elseif(($char=='}' || $char==']') && $outofquotes){
                $ret .= $newline;
                $pos --;
                for($j=0; $j<$pos; $j++){
                    $ret .= $indent;
                }
            }

            $ret .= $char;

            if(($char==',' || $char=='{' || $char=='[') && $outofquotes){
                $ret .= $newline;
                if($char=='{' || $char=='['){
                    $pos ++;
                }

                for($j=0; $j<$pos; $j++){
                    $ret .= $indent;
                }
            }

            $prevchar = $char;
        }

        return $ret;
    }

    public static function jsonFormatProtect(&$val){
        if($val!==true && $val!==false && $val!==null){
            $val = urlencode($val);
        }
    }
}

$array = [
  'key1' => 123,
  'key2' => 'abc',
  'key3' => '中文测试'
];

$json = Helper::jsonFormat($array);
echo '</pre>';
print_r($json);

转自博客 原文

还有一种方法就是使用 json_encode() 函数,它再不断的添加参数来丰富它的功能,上面同样的操作可以简化成这样:

<?php
$array = [
  'key1' => 123,
  'key2' => 'abc',
  'key3' => '中文测试'
];

$json = json_encode($$array, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_NUMERIC_CHECK);
echo '</pre>';
print_r($json);

想知道 json_encode更多的参数可以看文档 文档地址

震惊!彩票的随机机制竟然是这样的...

<?php

$lanList = [];
$hongList = [];

for($i=1;$i<34;$i++){
  if($i<16){
    array_push($lanList,$i);
  }
  array_push($hongList, $i);
}

$res = [
  'red' => [],
  'blue' => []
];

for($i=0;$i<=6;$i++){
  if($i==0){
    $res['blue'] = array_slice($lanList, mt_rand( 0,count($lanList)-1) ,1);
  }
  $res['red'][] = array_splice($hongList, mt_rand( 0,count($hongList)-1),1)[0];

}
sort($res['red']);
echo 'red:'.implode(',',$res['red']).' blue:'.implode(',',$res['blue']).PHP_EOL;

?>

使用hexo和github-pages发布博客

本地搭建 hexo

  • 构建hexo需要在本地安装node.js
brew install node

当前版本的node版本

node -v
v7.7.3
  • 全局安装 hexo
npm install -g hexo

国外镜像慢的话可以搜索找下淘宝的 cnmp

  • 创建一个目录并且安装 hexo
mkdir hexo_blog
cd hexo_blog
hexo init
npm install
  • 新建一个文章
hexo new "your-first-page"

文件在 hexo_blog/source/_post/下进行编辑啊

  • 然后就是生成静态文件
hexo generate
hexo server

这时就可以访问 http://localhost:4000 来查看效果,这个时候hexo已经搭建成功了,
但是我们需要外网能够访问,这就用到了今天的另一个主角:github page

hexo 放到github上

  • 需要一个github账号,具体申请登录看 https://github.com 上的引导就行
  • 创建一个新的 repository 名字格式是固定的,比如我的账户名是 gaopengfei123123 那么这个库的名字就是 gaopengfei123123.github.io 不能改的哦
  • 为了可以直接提交远程文件需要添加 ssh 密匙
    本地操作
ssh-keygen -t rsa -C "5173180@qq.com” -f ~/.ssh/github-rsa
cat ~/.ssh/github_rsa.pub
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC3K5mcQxH9mu1cUIu2+byK1iksES/7Tnfh23l2U6y1fOKO4XFhPLdAoMQdePnI51PAF4faXxucOYsiDb6IpQimWPwORKTkEkcglOiZ414eZZ829gY98RAldbFQeT2L9A0l2APfcan1fH4HvrCmZKlY8CNDQDDfRzXub9hfSX3LS5mQlgS9PHiFoXRfrS10hYweere9Cb9OFiEdkdCfMKUBr25ImGahqbaHxE8Vb3QzMT8Q5PBITaqFwYnIE/z6HU6Lok92EZ/uVG81SMJb9A5SQCZdsjWmyDqXj1eDZ1A2YyUlA+/6QM7JjCrLoZAAtZHTH+ylNAG79w9WG0eYAuL GaoPengFeiFiy@github.com

把这一段完整的复制到 https://github.com/settings/keys 这个地址下,添加一条新的ssh-key,这样就能免登录提交版本文件

  • 现在编辑本地hexo根目录下的站点配置文件 path/to/hexo_blog/_config.yml
    查找字段 deploy 编辑成这样
# Deployment
## Docs: https://hexo.io/docs/deployment.html
deploy:
  type: git
  repo: git@github.com:gaopengfei123123/gaopengfei123123.github.io.git
  branch: master

设置好后,就将本地生成的静态文件发到github上

hexo deploy

#如果报错就可能是少个插件
npm install hexo-deployer-git
  • 进入 你的版本库地址/settings 比如我的就是 https://github.com/gaopengfei123123/gaopengfei123123.github.io/settings
    找到 github pages 设置块按照你的需求调整,这时访问 https://gaopengfei123123.github.io就能访问 hexo 上传的内容了

绑定一个自己的域名,通过它来访问github pages

我用的是阿里云的万网来举例

  • 首先进入到万网云解析的页面
记录类型:A
主机记录:blog
记录值:xxx.xxx.xxx  #这里需要 ping -c 3 https://gaopengfei123123.github.io 获取ip地址
  • 然后返回到 你的版本库地址/settings 这里,将 Custom domain 设置成你刚才解析的名字,
    与此同时在github上版本的根目录下添加一个文件 CNAME 内容是
#in CNAME
blog.justwe.site

这时再返回settings中就能看的 github pages 部分的域名绑定的是你的域名了,到这里博客算是搭建成功了

hexo官网

hexo的next模版官网

LBS使用redis的解决方案--GEOHASH

最近需要用到LBS距离测绘方面的东西,用于搜索附近的人,
在网上搜了一下有一个比较通用的方案,就是采用 GEOHASH 算法

相关的参考资料

这套算法在 mongoDB 当中已经集成了,但是公司的业务中没有用到 mongodb 而是用了redis,
本来打算自己造个轮子去实现,但是万幸翻看了一下redis的文档,它也在 3.* 版本后提供了GEO相关的api

相关文章

首先是添加命令 GEOADD

GEOADD key long lat name [long lat name1,long lat name2,long lat name3...]
  1. key GEOSET的名字
  2. long 地点的经度
  3. lat 地点的纬度
  4. name GEOSET内的值的名字
    可以批量输入

举个栗子

GEOADD chaoyangqu 116.43620200729366 39.916880160714435 "yabaolu" 116.4356870231628 39.908560377800676 "jianguomen" 116.4345336732864 39.924466658329585 "chaoyangmen" 116.4335788068771 39.921372916981106 "yinhesoho" 116.43564410781856 39.92024564137184 "zhongliang"
(integer) 5

返回值为1 说明是新添,返回0 说明是更新 错误的话就报错了

查看当前插入的内容

zrange chaoyangqu 0 -1
1) "jianguomen"
2) "yabaolu"
3) "zhongliang"
4) "yinhesoho"
5) "chaoyangmen"

从这条命令也可以看出来 geoset 是属于有序集合

命令 GEORADIUS

GEORADIUS key long lat radius unit [WITHDIST] [WITHHASH] [WITHCOORD] [ASC|DESC] [COUNT count]
  1. key 集合的名字
  2. long 指定的经度
  3. lat 指定的纬度
  4. radius 半径范围
  5. unit 单位 可以说 m km ft(英尺) mi(英里)
GEORADIUS chaoyangqu 116.435182767868 39.91811857809279 300 m
1) "zhongliang"
2) "yabaolu"

带上参数可以显示更多位置信息,通常业务需要显示下距离和进行排序,添加 WITHDIST ASC

GEORADIUS chaoyangqu 116.435182767868 39.91811857809279 300 m WITHDIST ASC
1) 1) "yabaolu"
   2) "162.8454"
2) 1) "zhongliang"
   2) "239.7758"

命令GEORADIUSBYMEMBER

GEORADIUSBYMEMBER key member radius unit [WITHDIST] [WITHHASH] [WITHCOORD] [ASC|DESC] [COUNT count]
  1. key 集合的名字
  2. long 指定的经度
  3. lat 指定的纬度
  4. radius 半径范围
  5. unit 单位 可以说 m km ft(英尺) mi(英里)

这个和 GEORADIUS 的区别就是 前者是指定坐标,后者是可以直接从集合中指定一个name做计算
栗子

GEORADIUSBYMEMBER chaoyangqu yinhesoho 300 m WITHDIST ASC
GEORADIUSBYMEMBER chaoyangqu yinhesoho 300 m WITHDIST ASC
1) 1) "yinhesoho"
   2) "0.0000"
2) 1) "zhongliang"
   2) "216.2817"

排在第一位的肯定是自己啊,而且需要确定你要搜寻的名字已经存在集合中,否则会报错

命令GEOPOS

GEOPOS key elem1 elem2 ... elemN

列出集合中指定name的坐标
栗子:

GEOPOS chaoyangqu yabaolu yinhesoho xxx
1) 1) "116.43620342016220093"
   2) "39.9168813345921123"
2) 1) "116.43358021974563599"
   2) "39.92137286048646416"
3) (nil)

说明如果 name 不存在set中就会返回nil

命令GEODIST

GEODIST key elem1 elem2 [unit]
1. unit 单位可以说m lm ft mi

只能是两个元素之间的啊,不然三个元素就是语法错误,两个元素中有一个不存在则返回 nil
栗子

GEODIST chaoyangqu yabaolu yinhesoho m
"547.4030"

下面的几个命令做个了解,平时不常用到

  • GEOHASH key elem1 elem2 ... elemN //获取指定name的hash值