php获取明天后天下星期时间戳

function futureTime($command){
    list($com,$n,$x)=explode("-",$command);
    if($com=="xq"){
        $time=date("w",time( ));
        $array = ["7","1","2","3","4","5","6"];
        $time=date("w",time( )); 
        $tmp=strtotime(date('Y-m-d',strtotime('+'.($n*7).' day')))-(($array[$time]-$x)*24*60*60)-8*60*60;
        return [$tmp,$tmp-time()];
    }
    if($com=="rq"){
        $tmp=strtotime(date('Y-m-d',strtotime('+'.$n.' day')))-8*60*60; 
        return [$tmp,$tmp-time()];
    }
}

获取下星期三:futureTime("xq-1-3")

xq:星期标识

1:代表下星期 2:代表下下星期 n:代表第n个星期

3:代表星期三 (1.2.3.4.5.6.7 星期一到星期天)

获取明天:futureTime("rq-1")

rq:日期标识

1:代表下一天

返回值:索引数组,一个是日期的时间戳,另一个是现在距离日期的秒数。

注意:所有的时间都是秒数,并且是从00:00:00开始计算的。


redis 死循环为什么CPU很低?

redis的事件循环代码

void aeMain(aeEventLoop *eventLoop) {
    eventLoop->stop = 0;
    while (!eventLoop->stop) {
        if (eventLoop->beforesleep != NULL)
            eventLoop->beforesleep(eventLoop);
        aeProcessEvents(eventLoop, AE_ALL_EVENTS);
    }
}

让我不理解的是,这是一个死循环,但是CPU占用很低。所以就看看代码学习一下。由于我只需要时间事件(processTimeEvents)。所以我将aeProcessEvents删掉了一些代码,只保留时间事件。然后CPU暴增。

微信图片_20190918182652.png

可以看到CPU从0.0涨到了90.3于是往上回溯代码。最终发现其中一个比较关键的:aeApiPoll函数。

网上有一段话:aeProcessEvents 都会先 计算最近的时间事件发生所需要等待的时间 ,然后调用 aeApiPoll 方法在这段时间中等待事件的发生,在这段时间中如果发生了文件事件,就会优先处理文件事件,否则就会一直等待,直到最近的时间事件需要触发。跟进去会发现是一个select,它是用来等待文件描述词(普通文件、终端、伪终端、管道、FIFO、套接字及其他类型的字符型)这些的改变事件。

在传递的时候会将tvp传入进来,tvp是最近发生的时间,也被设置成了select的过期时间,所以如果没有发生文件事件,然后又select又过期了,自动会走如下代码

    if (retval > 0) {
        for (j = 0; j <= eventLoop->maxfd; j++) {
            int mask = 0;
            aeFileEvent *fe = &eventLoop->events[j];
            if (fe->mask == AE_NONE) continue;
            if (fe->mask & AE_READABLE && FD_ISSET(j,&state->_rfds))
                mask |= AE_READABLE;
            if (fe->mask & AE_WRITABLE && FD_ISSET(j,&state->_wfds))
                mask |= AE_WRITABLE;
            eventLoop->fired[numevents].fd = j;
            eventLoop->fired[numevents].mask = mask;
            numevents++;
        }
    }

所以这里的等待就会造成while的一些时间片的释放,然后会降低CPU。

layui form on触发多次的问题

ThinkAdmin后台使用的layui框架,其中的data-open,和data-modal存在一些使用上的问题。例如table表有两个功能项。编辑,增加。

编辑是data-modal

增加是data-open

其中都使用了form.on

复现步骤如下:先点击编辑,然后点击增加。会发现增加里面触发了编辑的form.on事件。百度了一下也没有结果,没办法去查看了layui的源码。

绑定事件源码:

//表单事件监听
  Form.prototype.on = function(events, callback){
    return layui.onevent.call(this, MOD_NAME, events, callback);
  };

调用了一个call

Layui.prototype.onevent = function(modName, events, callback){
    if(typeof modName !== 'string' 
    || typeof callback !== 'function') return this;
    return Layui.event(modName, events, null, callback);
  };

查看event事件

//执行自定义模块事件
  Layui.prototype.event = Layui.event = function(modName, events, params, fn){
    var that = this
    ,result = null
    ,filter = events.match(/\((.*)\)$/)||[] //提取事件过滤器字符结构,如:select(xxx)
    ,eventName = (modName + '.'+ events).replace(filter[0], '') //获取事件名称,如:form.select
    ,filterName = filter[1] || '' //获取过滤器名称,,如:xxx
    ,callback = function(_, item){
      var res = item && item.call(that, params);
      res === false && result === null && (result = false);
    };
    
    //添加事件
    if(fn){
      config.event[eventName] = config.event[eventName] || {};
      //这里不再对多次事件监听做支持,避免更多麻烦
      //config.event[eventName][filterName] ? config.event[eventName][filterName].push(fn) : 
      config.event[eventName][filterName] = [fn];
      return this;
    }
    
    //执行事件回调
    layui.each(config.event[eventName], function(key, item){
      //执行当前模块的全部事件
      if(filterName === '{*}'){
        layui.each(item, callback);
        return;
      }
      
      //执行指定事件
      key === '' && layui.each(item, callback);
      (filterName && key === filterName) && layui.each(item, callback);
    });
    
    return result;
  };
  win.layui = new Layui();

其中可以看到 

config.event[eventName][filterName] = [fn];

可以将事件重置,所以在增加里面重新绑定编辑的事件就可以了,function可以设置为空。

layui table 选中返回

需要重写一下modules/table.js,从官网下载layui的源码。然后复制一份table.js到modules目录下,重命名为tables.js。

如果直接lay.use("tables")是无法加载的,所以需要更改一下layui.js或者layui.min.js,添加到内置对象里。

添加为:tables:"modules/tables"。这样就可以正常的使用,这也是实际更改过程中费时最久的一个部分。

找到如下代码:

that.elem.on('click', 'input[name="layTableCheckbox"]

增加如下代码:

// iwonmo 逻辑开始 把选择框写入到本地存储里
var xi = checkbox[0].getAttribute("data-indexkey");
if(xi>0) {
    var xjson = localStorage.getItem("iwonmo_table");
    if(xjson==null){
        if($(checkbox[0]).is(':checked')==true){
            var xjsons=[]
            xjsons.push(xi);
            localStorage.setItem("iwonmo_table",JSON.stringify(xjsons))
        }
    }else{
        xjson=JSON.parse(xjson)
        if($.inArray(xi, xjson) == -1)
        {
            if($(checkbox[0]).is(':checked')==true){
            xjson.push(xi)
            localStorage.setItem("iwonmo_table",JSON.stringify(xjson))
        }
        }else{
            if($(checkbox[0]).is(':checked') == false){
                delete xjson.splice([$.inArray(xi, xjson)],1);
                localStorage.setItem("iwonmo_table",JSON.stringify(xjson))
            }
        }
    }
}
// iwonmo 逻辑结束

找到如下代码

//渲染不同风格的列
switch(item3.type){

增加如下代码

// iwonmo 逻辑开始
var my_key="";
var ischecked = ""
if('id' in item1)
{
    my_key="data-indexKey="+item1.id
    var xjson = localStorage.getItem("iwonmo_table");
    if(xjson != null){
        xjson=JSON.parse(xjson)
        if($.inArray(""+item1.id, xjson) > -1)
            ischecked="checked";
    }
}
// iwonmo 逻辑结束

效果如下

222222.gif

取值方法也没有受到影响

微信截图222.png


下载:tables.zip