1. <?php
    /*
  2.  
  3. Redis可真能坑爷,原先的设计用redis保存临时数据,可到了实际应用(实际上也就是几十个人同时用),总是出现莫名其妙的问题,最常见的就是读不出数据来,调试了好多天,那问题还是偶尔出现(也不是一直有,偶尔读不到),幸好这段时间接触swoole,发现有swoole_table这么个好东东,于是就先试试吧,下面的就是用于替换redis的。完了后再测,基本没出什么异常,也用了N个客户端同时自动发送(比原先十几个人手工发速度要快很多了),运行了十多分钟,基本没问题。
  4.  
  5. swoole_table还有些功能上的不足之处:
    1,不能getAll,可能是我没找到方法吧,于是就另外建个表专门用于记录键,虽然这样应付不了多少数据,而且可能也很慢,但这是目前能想到的唯一的办法。
    2,可保存的数据类型只有:string,int,float,如果能加上数组就好了,或者在保存时,若是数组,自动转换JSON,会好很多。
    3,创建表时,有点麻烦,如果能象redis那样允许直接一个字串就好了,虽然可以创建只有一个列的表,可还是觉得有点不方便;
  6.  
  7. 下面的类是完整应用类,里面的表结构需根据实际需要设置
  8.  
  9. 调用:
  10.  
  11. $mem=new Mem_swoole();
  12.  
  13. 然后就可以按对象直接使用啦。
  14.  
  15. */
  16.  
  17. class Mem_swoole
    {
    private $user;//数据表
    private $client;//数据表
    private $master;//数据表
  18.  
  19. private $index;//保存数据表的所有键
    private $count;//计数器
  20.  
  21. private $temp;//测试表
  22.  
  23. public function __construct($conf = [])
    {
    $user = [];
    $user[] = ['key' => 'ip', 'type' => 'string', 'len' => 15];
    $user[] = ['key' => 'port', 'type' => 'int', 'len' => 4];
    $user[] = ['key' => 'dns', 'type' => 'string', 'len' => 30];
    $user[] = ['key' => 'pid', 'type' => 'int', 'len' => 4];
    $user[] = ['key' => 'mode', 'type' => 'int', 'len' => 2];
    $user[] = ['key' => 'screen', 'type' => 'string', 'len' => 10];
    $user[] = ['key' => 'name', 'type' => 'string', 'len' => 30];
  24.  
  25. $client = [];
    $client[] = ['key' => 'dns', 'type' => 'string', 'len' => 15];
    $client[] = ['key' => 'client', 'type' => 'string', 'len' => 100];
  26.  
  27. $master = [];
    $master[] = ['key' => 'id', 'type' => 'int', 'len' => 4];
    $master[] = ['key' => 'dns', 'type' => 'string', 'len' => 15];
    $master[] = ['key' => 'lv', 'type' => 'int', 'len' => 1];
  28.  
  29. $index = [];
    $index[] = ['key' => 'keys', 'type' => 'string', 'len' => 65536];
  30.  
  31. $count = [];
    $count[] = ['key' => 'send', 'type' => 'int', 'len' => 8];
  32.  
  33. $this->user = new swoole_table(1024);
    $this->client = new swoole_table(1024);
    $this->master = new swoole_table(1024);
    $this->index = new swoole_table(8);
    $this->count = new swoole_table(8);
  34.  
  35. $this->column($this->user, $user);
    $this->column($this->client, $client);
    $this->column($this->master, $master);
    $this->column($this->index, $index);
    $this->column($this->count, $count);
  36.  
  37. $this->user->create();
    $this->client->create();
    $this->master->create();
    $this->index->create();
    $this->count->create();
    }
  38.  
  39. /**
    * swoole_table的测试
    * @param string $table
    */
    public function test($table = 'temp')
    {
    $count = [];
    $count[] = ['key' => 'name', 'type' => 'string', 'len' => 50];
    $count[] = ['key' => 'title', 'type' => 'string', 'len' => 50];
  40.  
  41. $this->{$table} = new swoole_table(1024);
    $allType = ['int' => swoole_table::TYPE_INT, 'string' => swoole_table::TYPE_STRING, 'float' => swoole_table::TYPE_FLOAT];
    foreach ($count as $row) {
    $this->{$table}->column($row['key'], $allType[$row['type']], $row['len']);
    }
    $this->{$table}->create();
  42.  
  43. foreach ([1, 2, 3] as $val) {
    $value = ['title' => "这是第{$val}个标题"];
    $this->{$table}->set("K_{$val}", $value);
    $this->record($table, "K_{$val}");
    }
  44.  
  45. foreach ([4, 5, 6] as $val) {
    $value = ['name' => "这是第{$val}个名字"];
    $this->{$table}->set("K_{$val}", $value);
    $this->record($table, "K_{$val}");
    }
  46.  
  47. foreach ([7, 8, 9] as $val) {
    $value = ['name' => "这是第{$val}个名字", 'title' => "这是第{$val}个标题"];
    $this->{$table}->set("K_{$val}", $value);
    $this->record($table, "K_{$val}");
    }
  48.  
  49. $value = [];
    foreach ([1, 2, 3, 4, 5, 6, 7, 8, 9] as $val) {
    $value["K_{$val}"] = $this->{$table}->get("K_{$val}");
    }
  50.  
  51. $key = $this->record($table);
    $all = $this->getAll($table);
    print_r($value);
    print_r($key);
    print_r($all);
    }
  52.  
  53. /**
    * 数据表定义
    * @param $name
    * @param $type
    * @param int $len
    */
    private function column(swoole_table $table, $arr)
    {
    $allType = ['int' => swoole_table::TYPE_INT, 'string' => swoole_table::TYPE_STRING, 'float' => swoole_table::TYPE_FLOAT];
    foreach ($arr as $row) {
    if (!isset($allType[$row['type']])) $row['type'] = 'string';
    $table->column($row['key'], $allType[$row['type']], $row['len']);
    }
    }
  54.  
  55. /**
    * 存入【指定表】【行键】【行值】
    * @param $key
    * @param array $array
    * @return bool
    */
    public function set($table, $key, array $array)
    {
    $this->{$table}->set($key, $this->checkArray($array));
    $this->add($table, 1);
    return $this->record($table, $key);
    }
  56.  
  57. /**
    * 存入数据时,遍历数据,二维以上的内容转换JSON
    * @param array $array
    * @return array
    */
    private function checkArray(array $array)
    {
    $value = [];
    foreach ($array as $key => $arr) {
    $value[$key] = is_array($arr) ? json_encode($arr, 256) : $arr;
    }
    return $value;
    }
  58.  
  59. /**
    * 读取【指定表】的【行键】数据
    * @param $key
    * @return array
    */
    public function get($table, $key)
    {
    return $this->{$table}->get($key);
    }
  60.  
  61. /**
    * 读取【指定表】所有行键值和记录
    * @param $table
    * @return array
    */
    public function getAll($table)
    {
    $recode = $this->record($table);
    return $this->getKeyValue($table, $recode);
    }
  62.  
  63. /**
    * 读取【指定表】【指定键值】的记录
    * @param $table
    * @param $recode
    * @return array
    */
    public function getKeyValue($table, $recode)
    {
    $value = [];
    foreach ($recode as $i => $key) {
    $value[$key] = $this->get($table, $key);
    }
    return $value;
    }
  64.  
  65. /**
    * 读取【指定表】的所有行键
    * @param $table
    * @return array
    */
    public function getKey($table)
    {
    return $this->record($table);
    }
  66.  
  67. /**
    * 记录【某个表】所有记录的键值,或读取【某个表】
    * @param $table
    * @param null $key 不指定为读取
    * @param bool|true $add 加,或减
    * @return array
    */
    private function record($table, $key = null, $add = true)
    {
    $this->index->lock();
    $oldVal = $this->index->get($table);
    if (!$oldVal) {
    $tmpArr = [];
    } else {
    $tmpArr = explode(',', $oldVal['keys']);
    }
    if ($key === null) {//读取,直接返回
    $this->index->unlock();
    return $tmpArr;
    }
    if ($add === true) {//加
    $tmpArr[] = $key;
    $tmpArr = array_unique($tmpArr);//过滤重复
    } else {//减
    $tmpArr = array_flip($tmpArr);//交换键值
    unset($tmpArr[$key]);
    $tmpArr = array_flip($tmpArr);//交换回来
    }
    $this->index->set($table, ['keys' => implode(',', $tmpArr)]);
    return $this->index->unlock();
    }
  68.  
  69. /**
    * 删除key
    * @param $key
    * @return bool
    */
    public function del($table, $key)
    {
    $this->{$table}->del($key);
    $this->add($table, -1);
    return $this->record($table, $key, false);
    }
  70.  
  71. /**
    * 原子自增操作,可用于整形或浮点型列
    * @param string $TabKey 表名.键名,但这儿的键名要是预先定好义的
    * @param int $incrby 可以是正数、负数,或0,=0时为读取值
    * @return bool
    */
    public function add($TabKey = 'count.send', $incrby = 1)
    {
    if (is_int($TabKey)) list($incrby, $TabKey) = [$TabKey, 'count.send'];
    list($table, $column, $tmp) = explode('.', $TabKey . '.send.');
  72.  
  73. if ($incrby >= 0) {
    return $this->count->incr($table, $column, $incrby);
    } else {
    return $this->count->decr($table, $column, 0 - $incrby);
    }
    }
  74.  
  75. /**
    * 某表行数
    * @param string $TabKey
    * @return bool
    */
    public function len($TabKey = 'count.send')
    {
    return $this->add($TabKey, 0);
    }
  76.  
  77. /**
    * 锁定整个表
    * @return bool
    */
    public function lock($table)
    {
    return $this->{$table}->lock();
    }
  78.  
  79. /**
    * 释放表锁
    * @return bool
    */
    public function unlock($table)
    {
    return $this->{$table}->unlock();
    }
  80.  
  81. }

swoole_table应用类的更多相关文章

  1. Java类的继承与多态特性-入门笔记

    相信对于继承和多态的概念性我就不在怎么解释啦!不管你是.Net还是Java面向对象编程都是比不缺少一堂课~~Net如此Java亦也有同样的思想成分包含其中. 继承,多态,封装是Java面向对象的3大特 ...

  2. C++ 可配置的类工厂

    项目中常用到工厂模式,工厂模式可以把创建对象的具体细节封装到Create函数中,减少重复代码,增强可读和可维护性.传统的工厂实现如下: class Widget { public: virtual i ...

  3. Android请求网络共通类——Hi_博客 Android App 开发笔记

    今天 ,来分享一下 ,一个博客App的开发过程,以前也没开发过这种类型App 的经验,求大神们轻点喷. 首先我们要创建一个Andriod 项目 因为要从网络请求数据所以我们先来一个请求网络的共通类. ...

  4. ASP.NET MVC with Entity Framework and CSS一书翻译系列文章之第二章:利用模型类创建视图、控制器和数据库

    在这一章中,我们将直接进入项目,并且为产品和分类添加一些基本的模型类.我们将在Entity Framework的代码优先模式下,利用这些模型类创建一个数据库.我们还将学习如何在代码中创建数据库上下文类 ...

  5. ASP.NET Core 折腾笔记二:自己写个完整的Cache缓存类来支持.NET Core

    背景: 1:.NET Core 已经没System.Web,也木有了HttpRuntime.Cache,因此,该空间下Cache也木有了. 2:.NET Core 有新的Memory Cache提供, ...

  6. .NET Core中间件的注册和管道的构建(2)---- 用UseMiddleware扩展方法注册中间件类

    .NET Core中间件的注册和管道的构建(2)---- 用UseMiddleware扩展方法注册中间件类 0x00 为什么要引入扩展方法 有的中间件功能比较简单,有的则比较复杂,并且依赖其它组件.除 ...

  7. Java基础Map接口+Collections工具类

    1.Map中我们主要讲两个接口 HashMap  与   LinkedHashMap (1)其中LinkedHashMap是有序的  怎么存怎么取出来 我们讲一下Map的增删改查功能: /* * Ma ...

  8. PHP-解析验证码类--学习笔记

    1.开始 在 网上看到使用PHP写的ValidateCode生成验证码码类,感觉不错,特拿来分析学习一下. 2.类图 3.验证码类部分代码 3.1  定义变量 //随机因子 private $char ...

  9. C# 多种方式发送邮件(附帮助类)

    因项目业务需要,需要做一个发送邮件功能,查了下资料,整了整,汇总如下,亲测可用- QQ邮箱发送邮件 #region 发送邮箱 try { MailMessage mail = new MailMess ...

随机推荐

  1. C# NPOI 导出Execl 工具类

    NPOI 导出Execl 自己单独工具类 详见代码 using System; using System.Collections.Generic; using System.Linq; using S ...

  2. vue.js 开发环境配置

    1. node.js环境(npm包管理器) 下载: https://nodejs.org/en/download/current/ 下载解压版的方便 添加path环境后运行 npm包管理器,是集成在n ...

  3. Vue.js 的一些小技巧

    给 props 属性设置多个类型 这个技巧在开发组件的时候用的较多,为了更大的容错性考虑,同时代码也更加人性化: export default { props: { width: { type: [S ...

  4. springboot项目的重定向和转发

    下面是idea软件创建的项目目录,这里总结了一下转发与重定向的问题,详解如下. 首先解释一下每个文件夹的作用,如果你是用的是idea创建的springboot项目,会在项目创建的一开始resource ...

  5. jQuery基础(样式篇,DOM对象,选择器,属性样式)

      1. $(document).ready 的作用是等页面的文档(document)中的节点都加载完毕后,再执行后续的代码,因为我们在执行代码的时候,可能会依赖页面的某一个元素,我们要确保这个元素真 ...

  6. angular自定义指令 repeat 循环结束事件;limitTo限制循环长度、限定开始位置

    1.获取repeat循环结束: 自定义指令: .directive('repeatFinish', function () { return { link: function (scope, elem ...

  7. pom.xml 如果使用 mvn exec:exec 命令运行项目

    pom.xml 如果使用 mvn exec:exec 命令运行项目,红色字体要与groupid相同 <project xmlns="http://maven.apache.org/PO ...

  8. asp.net mvc +easyui 实现权限管理(二)

    一写完后,好久没有继续写了.最近公司又在重新开发权限系统了,但是由于我人微言轻,无法阻止他们设计一个太监版的权限系统.想想确实是官大一级压死人啊, 没办法我只好不参与了 让他们去折腾. 我就大概说一下 ...

  9. Progress数据库配置与应用

    创建database 开始->程序->OpenEdge,选择:Desktop,进行database创建. 选择创建一个空database或直接copy一个demo的database,我们选 ...

  10. ssh终端常用快捷键

    ssh终端常用快捷键 快捷键 描述 Ctrl+a 光标移动到行首 Ctrl+e 光标移动到行尾 Ctrl+c 终止当前程序 Ctrl+d 删除光标前的字符,或者推出当前中断 Ctrl+l 清屏 Ctr ...