colly
2017-07-29 86c1b949e3b5b8a0b148000afd3831f39a0c41ac
增加redis和上传接口
6 files added
719 ■■■■■ changed files
Library/Redis/Config/app.php 27 ●●●●● patch | view | raw | blame | history
Library/Redis/Lite.php 481 ●●●●● patch | view | raw | blame | history
Library/Redis/README.md 130 ●●●●● patch | view | raw | blame | history
Yfs/Api/Data.php 38 ●●●●● patch | view | raw | blame | history
Yfs/Domain/Data.php 35 ●●●●● patch | view | raw | blame | history
Yfs/Model/Data.php 8 ●●●●● patch | view | raw | blame | history
Library/Redis/Config/app.php
New file
@@ -0,0 +1,27 @@
<?php
/**
 * Redis缓存配置
 * @author: 喵了个咪 <wenzhenxi@vip.qq.com> 2015-11-15
 */
return array(
    //Redis配置项
    'redis' => array(
        //Redis缓存配置项
        'servers'  => array(
            'host'   => '127.0.0.1',        //Redis服务器地址
            'port'   => '6379',             //Redis端口号
            'prefix' => 'yfs_',      //Redis-key前缀
            'auth'   => 'yfs_moral_password2017',    //Redis链接密码
        ),
        // Redis分库对应关系
        'DB'       => array(
            'developers' => 1,
            'user'       => 2,
            'code'       => 3,
        ),
        //使用阻塞式读取队列时的等待时间单位/秒
        'blocking' => 5,
    ),
);
Library/Redis/Lite.php
New file
@@ -0,0 +1,481 @@
<?php
/**
 * Redis 拓展类
 * @author: 喵了个咪 <wenzhenxi@vip.qq.com> 2015-11-15
 *
 * @author: Axios <axioscros@aliyun.com> 2016-09-01
 *
 * @update 2016-09-01
 * 1. 增加__call魔术方法,重载当前类中方法,统一切换DB,缩减代码行数,减少类中方法互相调用时,重复切换DB
 * 2. 增加save_time方法,更新具有有效时间key的value,并且不重置有效时间,使用方式: DI()->redis->save_time($key, $value,$dbname);
 * 3. 增加counter_forever方法,永久计数器,每次调用递增1,使用方式: DI()->redis->counter_forever($key,$dbname);
 * 4. 增加counter_time_create方法,创建临时计数器,每次调用重置计数器和有效时间,使用方式: DI()->redis->counter_time_create($key,$expire,$dbname);
 * 5. 增加counter_time_update方法,更新临时计数器,每次调用递增1,使用方式: DI()->redis->counter_time_update($key,$dbname);
 * 6. 修复一处bug,get_time_ttl方法中,$this->unformatValue($value)修改为$value。修改前,调用此方法,会一直回调false
 *
 */
class Redis_Lite extends PhalApi_Cache_Redis{
    private $db_old;
    /**
     * 重载方法,统一切换DB
     *
     * @param $name
     * @param $arguments
     * @return mixed
     *
     * @author: Axios <axioscros@aliyun.com> 2016-09-01
     */
    public function __call($name, $arguments)
    {
        $last = count($arguments)-1;
        $dbname = $arguments[$last];
        $this->switchDB($dbname);
        unset($arguments[$last]);
        $arguments = empty($arguments)? array():$arguments;
        return call_user_func_array(array($this,$name),$arguments);
    }
    //---------------------------------------------------string类型-------------------------------------------------
    /**
     * 将value 的值赋值给key,生存时间为永久 并根据名称自动切换库
     */
    protected function set_forever($key, $value){
        return $this->redis->set($this->formatKey($key), $this->formatValue($value));
    }
    /**
     * 获取value 并根据名称自动切换库
     */
    protected function get_forever($key){
        $value = $this->redis->get($this->formatKey($key));
        return $value !== FALSE ? $this->unformatValue($value) : NULL;
    }
    /**
     * 存入一个有实效性的键值队
     */
    protected function set_time($key, $value, $expire = 600){
        return $this->redis->setex($this->formatKey($key), $expire, $this->formatValue($value));
    }
    /**
     * 更新具有有效时间key的value,不重置有效时间
     * @author Axios <axioscros@aliyun.com>
     */
    protected function save_time($key, $value)
    {
        if($this->get_exists($key)){
            $ttl  = $this->get_time_ttl($key);
            return $this->set_time($key,$value,$ttl);
        }
        return NULL;
    }
    /**
     * 统一get/set方法,对于set_Time使用get_Time
     */
    protected function get_time($key){
        $value = $this->redis->get($this->formatKey($key));
        return $value !== FALSE ? $this->unformatValue($value) : NULL;
    }
    /**
     * 得到一个key的生存时间
     */
    protected function get_time_ttl($key){
        $value = $this->redis->ttl($this->formatKey($key));
        return $value !== FALSE ? $value : NULL;
    }
    /**
     * 批量插入k-v,请求的v需要是一个数组 如下格式
     * array('key0' => 'value0', 'key1' => 'value1')
     */
    protected function set_list($value){
        $data = array();
        foreach($value as $k => $v){
            $data[$this->formatKey($k)] = $this->formatValue($v);
        }
        return $this->redis->mset($data);
    }
    /**
     * 批量获取k-v,请求的k需要是一个数组
     */
    protected function get_list($key){
        $data = array();
        foreach($key as $k => $v){
            $data[] = $this->formatKey($v);
        }
        $rs = $this->redis->mget($data);
        foreach($rs as $k => $v){
            $rs[$k] = $this->unformatValue($v);
        }
        return $rs;
    }
    /**
     * 判断key是否存在。存在 true 不在 false
     */
    protected function get_exists($key){
        return $this->redis->exists($this->formatKey($key));
    }
    /**
     * 返回原来key中的值,并将value写入key
     */
    protected function get_getSet($key, $value){
        $value = $this->redis->getSet($this->formatKey($key), $this->formatValue($value));
        return $value !== FALSE ? $this->unformatValue($value) : NULL;
    }
    /**
     * string,名称为key的string的值在后面加上value
     */
    protected function set_append($key, $value){
        return $this->redis->append($this->formatKey($key), $this->formatValue($value));
    }
    /**
     * 返回原来key中的值,并将value写入key
     */
    protected function get_strlen($key){
        return $this->redis->strlen($this->formatKey($key));
    }
    /**
     * 自动增长
     * value为自增长的值默认1
     */
    protected function get_incr($key, $value = 1){
        return $this->redis->incr($this->formatKey($key), $value);
    }
    /**
     * 自动减少
     * value为自减少的值默认1
     */
    protected function get_decr($key, $value = 1){
        return $this->redis->decr($this->formatKey($key), $value);
    }
    //------------------------------------------------List类型-------------------------------------------------
    /**
     * 写入队列左边 并根据名称自动切换库
     */
    protected function set_lPush($key, $value){
        return $this->redis->lPush($this->formatKey($key), $this->formatValue($value));
    }
    /**
     * 写入队列左边 如果value已经存在,则不添加 并根据名称自动切换库
     */
    protected function set_lPushx($key, $value){
        return $this->redis->lPushx($this->formatKey($key), $this->formatValue($value));
    }
    /**
     * 写入队列右边 并根据名称自动切换库
     */
    protected function set_rPush($key, $value){
        return $this->redis->rPush($this->formatKey($key), $this->formatValue($value));
    }
    /**
     * 写入队列右边 如果value已经存在,则不添加 并根据名称自动切换库
     */
    protected function set_rPushx($key, $value){
        return $this->redis->rPushx($this->formatKey($key), $this->formatValue($value));
    }
    /**
     * 读取队列左边
     */
    protected function get_lPop($key){
        $value = $this->redis->lPop($this->formatKey($key));
        return $value != FALSE ? $this->unformatValue($value) : NULL;
    }
    /**
     * 读取队列右边
     */
    protected function get_rPop($key){
        $value = $this->redis->rPop($this->formatKey($key));
        return $value != FALSE ? $this->unformatValue($value) : NULL;
    }
    /**
     * 读取队列左边 如果没有读取到阻塞一定时间 并根据名称自动切换库
     */
    protected function get_blPop($key){
        $value = $this->redis->blPop($this->formatKey($key), DI()->config->get('app.redis.blocking'));
        return $value != FALSE ? $this->unformatValue($value[1]) : NULL;
    }
    /**
     * 读取队列右边 如果没有读取到阻塞一定时间 并根据名称自动切换库
     */
    protected function get_brPop($key){
        $value = $this->redis->brPop($this->formatKey($key), DI()->config->get('app.redis.blocking'));
        return $value != FALSE ? $this->unformatValue($value[1]) : NULL;
    }
    /**
     * 名称为key的list有多少个元素
     */
    protected function get_lSize($key){
        return $this->redis->lSize($this->formatKey($key));
    }
    /**
     * 返回名称为key的list中指定位置的元素
     */
    protected function set_lSet($key, $index, $value){
        return $this->redis->lSet($this->formatKey($key), $index, $this->formatValue($value));
    }
    /**
     * 返回名称为key的list中指定位置的元素
     */
    protected function get_lGet($key, $index){
        $value = $this->redis->lGet($this->formatKey($key), $index);
        return $value != FALSE ? $this->unformatValue($value[1]) : NULL;
    }
    /**
     * 返回名称为key的list中start至end之间的元素(end为 -1 ,返回所有)
     */
    protected function get_lRange($key, $start, $end){
        $rs = $this->redis->lRange($this->formatKey($key), $start, $end);
        foreach($rs as $k => $v){
            $rs[$k] = $this->unformatValue($v);
        }
        return $rs;
    }
    /**
     * 截取名称为key的list,保留start至end之间的元素
     */
    protected function get_lTrim($key, $start, $end){
        $rs = $this->redis->lTrim($this->formatKey($key), $start, $end);
        foreach($rs as $k => $v){
            $rs[$k] = $this->unformatValue($v);
        }
        return $rs;
    }
    //未实现 lRem lInsert  rpoplpush
    //----------------------------------------------------set类型---------------------------------------------------
    //----------------------------------------------------zset类型---------------------------------------------------
    //----------------------------------------------------Hash类型---------------------------------------------------
    //----------------------------------------------------通用方法---------------------------------------------------
    /**
     * 永久计数器,回调当前计数
     * @author Axios <axioscros@aliyun.com>
     */
    public function counter_forever($key,$dbname=0){
        $this->switchDB($dbname);
        if($this->get_exists($key)){
            $count = $this->get_forever($key);
            $count++;
            $this->set_forever($key,$count);
        }else{
            $count = 1;
            $this->set_forever($key,$count);
        }
        return $count;
    }
    /**
     * 创建具有有效时间的计数器,回调当前计数,单位毫秒ms
     * @author Axios <axioscros@aliyun.com>
     */
    public function counter_time_create($key,$expire  = 1000,$dbname=0){
        $this->switchDB($dbname);
        $count = 1;
        $this->set_time($key,$count,$expire);
        $this->redis->pSetEx($this->formatKey($key), $expire, $this->formatValue($count));
        return $count;
    }
    /**
     * 更新具有有效时间的计数器,回调当前计数
     * @author Axios <axioscros@aliyun.com>
     */
    public function counter_time_update($key,$dbname=0){
        $this->switchDB($dbname);
        if($this->get_exists($key)){
            $count = $this->get_time($key);
            $count++;
            $expire = $this->redis->pttl($this->formatKey($key));
            $this->set_time($key,$count,$expire);
            return $count;
        }
        return false;
    }
    /**
     * 设定一个key的活动时间(s)
     */
    protected function setTimeout($key, $time = 600){
        return $this->redis->setTimeout($key, $time);
    }
    /**
     * 返回key的类型值
     */
    protected function type($key){
        return $this->redis->type($key);
    }
    /**
     * key存活到一个unix时间戳时间
     */
    protected function expireAt($key, $time = 600){
        return $this->redis->expireAt($key, $time);
    }
    /**
     * 随机返回key空间的一个key
     */
    public function randomKey(){
        return $this->redis->randomKey();
    }
    /**
     * 返回满足给定pattern的所有key
     */
    protected function keys($key, $pattern){
        return $this->redis->keys($key, $pattern);
    }
    /**
     * 查看现在数据库有多少key
     */
    protected function dbSize(){
        return $this->redis->dbSize();
    }
    /**
     * 转移一个key到另外一个数据库
     */
    protected function move($key, $db){
        $arr = DI()->config->get('app.redis.DB');
        $rs  = isset($arr[$db]) ? $arr[$db] : $db;
        return $this->redis->move($key, $rs);
    }
    /**
     * 给key重命名
     */
    protected function rename($key, $key2){
        return $this->redis->rename($key, $key2);
    }
    /**
     * 给key重命名 如果重新命名的名字已经存在,不会替换成功
     */
    protected function renameNx($key, $key2){
        return $this->redis->renameNx($key, $key2);
    }
    /**
     * 删除键值 并根据名称自动切换库(对所有通用)
     */
    protected function del($key){
        return $this->redis->del($this->formatKey($key));
    }
    /**
     * 返回redis的版本信息等详情
     */
    public function info(){
        return $this->redis->info();
    }
    /**
     * 切换DB并且获得操作实例
     */
    public function get_redis(){
        return $this->redis;
    }
    /**
     * 查看连接状态
     */
    public function ping(){
        return $this->redis->ping();
    }
    /**
     * 内部切换Redis-DB 如果已经在某个DB上则不再切换
     */
    protected function switchDB($name){
        $arr = DI()->config->get('app.redis.DB');
        if(is_int($name)){
            $db = $name;
        }else{
            $db = isset($arr[$name]) ? $arr[$name] : 0;
        }
        if($this->db_old != $db){
            $this->redis->select($db);
            $this->db_old = $db;
        }
    }
    //-------------------------------------------------------谨慎使用------------------------------------------------
    /**
     * 清空当前数据库
     */
    protected function flushDB(){
        return $this->redis->flushDB();
    }
    /**
     * 清空所有数据库
     */
    public function flushAll(){
        return $this->redis->flushAll();
    }
    /**
     * 选择从服务器
     */
    public function slaveof($host, $port){
        return $this->redis->slaveof($host, $port);
    }
    /**
     * 将数据同步保存到磁盘
     */
    public function save(){
        return $this->redis->save();
    }
    /**
     * 将数据异步保存到磁盘
     */
    public function bgsave(){
        return $this->redis->bgsave();
    }
    /**
     * 返回上次成功将数据保存到磁盘的Unix时戳
     */
    public function lastSave(){
        return $this->redis->lastSave();
    }
    /**
     * 使用aof来进行数据库持久化
     */
    protected function bgrewriteaof(){
        return $this->redis->bgrewriteaof();
    }
}
Library/Redis/README.md
New file
@@ -0,0 +1,130 @@
#基于PhalApi的Redis拓展
![](http://webtools.qiniudn.com/master-LOGO-20150410_50.jpg)
##前言##
***先在这里感谢phalapi框架创始人@dogstar,为我们提供了这样一个优秀的开源框架.***
编写本次拓展出于的目的是为了解决并不是非常熟悉redis的童鞋能够方便的使用redis进行实际的运用
,对原生的phpredis进行的封装优化良好的注释和例子希望能提供更好的帮助!
**注:本拓展并没有开发完成,也没进行严格的测试,此版本为还处于开发阶段的鉴赏版.**
附上:
官网地址:[http://www.phalapi.net/](http://www.phalapi.net/ "PhalApi官网")
开源中国Git地址:[http://git.oschina.net/dogstar/PhalApi/tree/release](http://git.oschina.net/dogstar/PhalApi/tree/release "开源中国Git地址")
##安装配置redis以及phpredis##
基于centos6.5
        //下redis解压安装
        wget http://download.redis.io/releases/redis-2.8.17.tar.gz
        tar zxvf redis-2.8.17.tar.gz
        cd redis-2.8.17
        make
        make test
        make install
        //生成6379端口以及配置文件
        cd utils
        ./install_server.sh
        Please select the redis port for this instance: [6379]
        Please select the redis config file name [/etc/redis/6379.conf]
        Please select the redis log file name [/var/log/redis_6379.log]
        Please select the data directory for this instance [/var/lib/redis/6379]
        Please select the redis executable path [/usr/local/bin/redis-server]
        //对配置文件进行配置
        vi /etc/redis/6379.conf
        databases 100                            #可以使用的库的数量修改16为100
        masterauth xxxxxxxxxxxxx                 #连接 master 的认证密码
        requirepass woyouwaimai76                #连接此redis的连接密码
        :wq
        //修改关闭redis需要密码
        vi /etc/rc.d/init.d/redis_6379
        $CLIEXEC -p $REDISPORT -a woyouwaimai76 shutdown    #stop redis需要密码
        //重启redis
        service redis_6379 restart
        //添加到系统启动项
        chkconfig redis_6379 on
         //下载phpredis解压安装
         wget https://github.com/nicolasff/phpredis/archive/master.zip
         unzip master.zip -d phpredis
         cd phpredis/phpredis-master
         phpize
         ./configure
         make && make install
         //在php.ini中注册phpredis
         extension = redis.so
         //测试
          <?php
             $auth     = 'xxxxxxxxx';
             $source   = '127.0.0.1';
             $host     = '6379';
             $redis    = new Redis();
             echo $redis->connect($host) ? "$host connect" : "$host fail";
             if($auth){
                 echo $redis->auth($auth) ? " auth success" : " auth fail";
             }
##注册配置文件在Config.app文件下面##
    return array(
        //Redis配置项
        'redis' => array(
            //Redis缓存配置项
            'servers'  => array(
                'host'   => '127.0.0.1',        //Redis服务器地址
                'port'   => '6379',             //Redis端口号
                'prefix' => 'developers_',      //Redis-key前缀
                'auth'   => 'woyouwaimai76',    //Redis链接密码
            ),
            // Redis分库对应关系
            'DB'       => array(
                'developers' => 1,
                'user'       => 2,
                'code'       => 3,
            ),
            //使用阻塞式读取队列时的等待时间单位/秒
            'blocking' => 5,
        ),
    );
##在init入口文件注册redis拓展##
配置方式非常简单只需要把拓展下载下来放入Library文件内即可,然后就可以使用如下方法进行实例
    //redis链接
    DI()->redis = new Redis_Lite(DI()->config->get('app.redis.servers'));
##开始使用##
    //存入永久的键值队
    DI()->redis->set_forever(键名,值,库名);
    //获取永久的键值队
    DI()->redis->get_forever(键名, 库名);
    //存入一个有时效性的键值队,默认600秒
    DI()->redis->set_Time(键名,值,有效时间,库名);
    //获取一个有时效性的键值队
    DI()->redis->get_Time(键名, 库名);
    //写入队列左边
    DI()->redis->set_Lpush(队列键名,值, 库名);
    //读取队列右边
    DI()->redis->get_lpop(队列键名, 库名);
    //读取队列右边 如果没有读取到阻塞一定时间(阻塞时间或读取配置文件blocking的值)
    DI()->redis->get_Brpop(队列键名,值, 库名);
    //删除一个键值队适用于所有
    DI()->redis->del(键名, 库名);
    //自动增长
    DI()->redis->get_incr(键名, 库名);
    //切换DB并且获得操作实例
    DI()->redis->get_redis(键名, 库名);
Yfs/Api/Data.php
New file
@@ -0,0 +1,38 @@
<?php
/**
 * 用户信息类
 */
class Api_Data extends PhalApi_Api {
    public function getRules() {
        return array(
            'upload' => array(
                'data' => array('name' => 'data', 'type' => 'string' ,'require' => true, 'desc' => '上传数据'),
            ),
        );
    }
    /**
     * 上传数据
     * @desc 用于上传用户辐射数据
     * @return bool code 操作码,0表示注册成功, 1表示注册
     * @return string msg 返回提示
     */
    public function upload(){
        $rs = array('code' => 0, 'msg' => '');
        $data_service = new Domain_Data();
        $data = json_decode($this->data, true);
        //print_r(count($data['data']));die();
        if(json_last_error() == JSON_ERROR_NONE){
            $data_service->upload($data);
            $rs['msg'] = "数据上报成功";
        }
        else{
            $rs['code'] = 1;
            $rs['msg'] = "json格式异常";
        }
        return $rs;
    }
}
Yfs/Domain/Data.php
New file
@@ -0,0 +1,35 @@
<?php
/**
 * 用户业务类
 */
class Domain_Data {
    public function __construct(){
        //DI()->redis = new Redis_Lite(DI()->config->get('app.redis.servers'));
       $this->model = new Model_Data();
    }
    /**
     * 上传数据并保存入redis
     * @return [type] [description]
     */
    public function upload($data){
        $arr = array();
        $arr['user_id'] = $data['userid'];
        $arr['lon'] = $data['lon'];
        $arr['lat'] = $data['lat'];
        $arr['address'] = $data['address'];
        foreach ($data['data'] as $value) {
            $arr['value'] = $value['value'];
            $arr['create_time'] = $value['time'];
            $this->model->add($arr);
            if(isset($arr['_id']))
                unset($arr['_id']);
        }
        return true;
        //$a = rand(1,100);
        //DI()->redis->set_lPush('test', $a, 'master');
    }
}
Yfs/Model/Data.php
New file
@@ -0,0 +1,8 @@
<?php
class Model_Data extends Model_Base{
   public $table = 'data';
}