EasyTask简单易用的PHP常驻内存定时器

  EasyTask是PHP常驻内存定时器Composer包,定位与Javascript的setInterval定时器效果一致,您可以用它来完成需要重复运行的任务(如订单超时自动取消,短信邮件异步推送,队列/消费者/频道订阅者等等),甚至处理Crontab计划任务(如每天凌晨1点-3点同步DB数据,每月1号生成月度统一报表,每晚10点重启nginx服务器等等);内置任务异常上报功能,异常错误您都可以自定义处理(例如实现异常错误自动短信邮件通知);还支持任务异常退出自动重启功能,让您的任务运行更稳定 ,工具包同时支持windows、linux、mac环境运行。

运行环境

Composer安装

  composer require easy-task/easy-task

【一】. 快速入门->创建任务
//初始化
$task = new Task();

// 设置非常驻内存
$task->setDaemon(false);

// 设置项目名称
$task->setPrefix('EasyTask');

// 设置记录运行时目录(日志或缓存目录)
$task->setRunTimePath('./Application/Runtime/');

// 1.添加闭包函数类型定时任务(开启2个进程,每隔10秒执行1次你写闭包方法中的代码)
$task->addFunc(function () {
    $url = 'https://www.gaojiufeng.cn/?id=243';
    @file_get_contents($url);
}, 'request', 10, 2);

// 2.添加类的方法类型定时任务(同时支持静态方法)(开启1个进程,每隔20秒执行一次你设置的类的方法)
$task->addClass(Sms::class, 'send', 'sendsms', 20, 1);

// 3.添加指令类型的定时任务(开启1个进程,每隔10秒执行1次)
$command = 'php /www/web/orderAutoCancel.php';
$task->addCommand($command,'orderCancel',10,1);

// 4.添加闭包函数任务,不需要定时器,立即执行(开启1个进程)
$task->addFunc(function () {
    while(true)
    {
       //todo
    }
}, 'request', 0, 1);

// 5.每晚9点半通过curl命令访问网站
$task->addCommand('curl https://www.gaojiufeng.cn', 'curl', '30 21 * * *', 1);

// 启动任务
$task->start();

【二】. 快速入门->连贯操作
$task = new Task();

// 设置常驻内存
$task->setDaemon(true)   

// 设置项目名称
->setPrefix('ThinkTask')   

// 设置系统时区
->setTimeZone('Asia/Shanghai')  

// 设置子进程挂掉自动重启
->setAutoRecover(true)  

// 设置PHP运行路径,一般Window系统才需要设置,当系统无法找到才需要您手动设置
->setPhpPath('C:/phpEnv/php/php-7.0/php.exe')

/**
 * 设置运行时目录(日志或缓存目录)
 */
->setRunTimePath('./Application/Runtime/')

/**
 * 关闭EasyTask的异常注册
 * EasyTask将不再监听set_error_handler/set_exception_handler/register_shutdown_function事件
 */
->setCloseErrorRegister(true)

/**
 * 设置接收运行中的错误或者异常(方式1)
 * 您可以自定义处理异常信息,例如将它们发送到您的邮件中,短信中,作为预警处理
 * (不推荐的写法,除非您的代码健壮)
 */
->setErrorRegisterNotify(function ($ex) {
    //获取错误信息|错误行|错误文件
    $message = $ex->getMessage();
    $file = $ex->getFile();
    $line = $ex->getLine();
})

/**
 * 设置接收运行中的错误或者异常的Http地址(方式2)
 * Easy_Task会POST通知这个url并传递以下参数:
 * errStr:错误信息
 * errFile:错误文件
 * errLine:错误行
 * 您的Url收到POST请求可以编写代码发送邮件或短信通知您
 * (推荐的写法)
 */
->setErrorRegisterNotify('https://www.gaojiufeng.cn/rev.php')

// 添加任务定时执行闭包函数
->addFunc(function () {
    echo 'Success3' . PHP_EOL;
}, 'fucn', 20, 1)   

// 添加任务定时执行类的方法
->addClass(Sms::class, 'send', 'sendsms1', 20, 1)   

// 添加任务定时执行命令
->addCommand('php /www/wwwroot/learn/curl.php','cmd',6,1)

// 启动任务
->start();

【三】. 快速入门->命令整合
// 获取命令
$force = empty($_SERVER['argv']['2']) ? '' : $_SERVER['argv']['2'];
$command = empty($_SERVER['argv']['1']) ? '' : $_SERVER['argv']['1'];

// 配置任务
$task = new Task();
$task->setRunTimePath('./Application/Runtime/');
$task->addFunc(function () {
        $url = 'https://www.gaojiufeng.cn/?id=271';
        @file_get_contents($url);
    }, 'request', 10, 2);;

// 根据命令执行
if ($command == 'start')
{
    $task->start();
}
elseif ($command == 'status')
{
    $task->status();
}
elseif ($command == 'stop')
{
    $force = ($force == 'force'); //是否强制停止
    $task->stop($force);
}
else
{
    exit('Command is not exist');
}

启动任务: php console.php start
查询任务: php console.php status
普通关闭: php console.php stop
强制关闭: php console.php stop force

【四】. 快速入门->认识输出信息
┌─────┬──────────────┬─────────────────────┬───────┬────────┬──────┐
│ pid │ name         │ started             │ time │ status │ ppid │
├─────┼──────────────┼─────────────────────┼───────┼────────┼──────┤
│ 32  │ Task_request │ 2020-01-10 15:55:44 │ 10    │ active │ 31   │
│ 33  │ Task_request │ 2020-01-10 15:55:44 │ 10    │ active │ 31   │
└─────┴──────────────┴─────────────────────┴───────┴────────┴──────┘
参数:
pid:任务进程id
name:任务别名
started:任务启动时间
time:任务执行时间
status:任务状态
ppid:守护进程id

【五】. 进阶了解->建议阅读
(1). 建议您使用绝对路径进行开发,是标准更是规范
(2). 禁止在任务中使用exit/die语法,否则导致整个进程退出
(3). Windows安装Wpc扩展时请关闭杀毒软件,避免误报
(4). Windows建议开启popen,pclose方法,会自动尝试帮您解决CMD输出中文乱码问题,请尽量使用CMD管理员方式运行
(5). Windows命令行不支持utf8国际标准编码,可切换git_bash来运行,解决乱码问题
(6). Windows提示Failed to create COM object `Wpc.Core': 无效的语法,请按照文档安装Wpc扩展
(7). Windows提示com() has been disabled for security reasons,请在php.ini中删除disable_classes = com配置项目
(8). 日志文件在运行时目录的Log目录下,标出输入输出异常文件在运行时目录Std目录下
(9). 普通停止任务,任务会在执行成功后开始安全退出,强制停止任务直接退出任务,可能正在执行就强制退出
(10). 开发遵守先同步启动测试正常运行无任何报错再设置异步运行,有问题查看日志文件或者标准输入输出异常文件,或者上QQ群反馈

【六】. 进阶了解->框架集成教程

  -> thinkphp3.2.x教程.

  -> thinkPhp5.x.x教程.

  -> thinkPhp6.x.x教程.

  -> laravelPhp6.x.x教程.

【七】. 进阶了解->推荐操作
(1).推荐使用7.1以上版本的PHP,支持异步信号,不依赖ticks
(2).推荐安装php_event扩展基于事件轮询的毫秒级定时支持

【八】. 进阶了解->时间参数支持crontab命令
 (1).特殊表达式:
    @yearly                    每年运行一次 等同于(0 0 1 1 *) 
    @annually                  每年运行一次 等同于(0 0 1 1 *)
    @monthly                   每月运行一次 等同于(0 0 1 * *) 
    @weekly                    每周运行一次 等同于(0 0 * * 0) 
    @daily                     每日运行一次 等同于(0 0 * * *) 
    @hourly                    每小时运行一次 等同于(0 * * * *)
 (2).标准表达式:
    '30 21 * * *'              每天晚上21:30执行一次
    '0 23 * * 6'               每周星期六的晚上23:00执行一次
    '3,15 * * * *'             每小时的第3分钟和第15分钟执行一次
    '45 4 1,10,22 * *'         每月的1/10/22日的04:45执行一次
    '3,15 8-11 * * *'          每天上午8点到11点的第3分钟和第15分钟执行一次
    其他指令请自己测试
   使用example/build_cron_date.php生成执行时间列表来检查自己的命令是否符合预期

如何科学地分析学生成绩?

本文转自:https://www.zhihu.com/question/24398775

1、考情分析

  各个科目的平均分、最高分、最低分是老师首先要考察的指标。以下图这个班级为例,对比各个科目的及格线分析,所有科目平均分都及格了,化学成绩比较突出,平均分达到了72.54,但是物理和生物成绩却不甚理想。三门主课里,英语的平均成绩较好,但是高分却一般。

  光凭上面的图还不能看出学生的整体水平,那么来看看频数分布图吧:

以10为单位对总分进行分段,统计各个分数段的频数,可以看出不同科目在各个分数段的人数分布,大致呈中间高两头低的拟正态分布曲线。

  结果——真是远近高低各不同。物理成绩的波峰停留在61-70,说明大多数同学的成绩集中在这个分数段;化学在71-80分数段的人最多;数学的“山峰”最为绵延,分差较大;化学的“山峰”最陡峭,分差最小,大部分同学都及格了。

  我们再以总分的40%、60%、80%分别设定低分线、及格线、高分线。总体来说,生物的高分人数最多,数学和物理落后的情况比较严重。综合以上结论,据我推测:

  这可能是一个严重偏科的理科班,或者是一个分科后、会考前英语成绩比较好的文科班,也有可能只是考题太难,毕竟最高分都不理想。

  (推理脸,严肃)

2、考试难度

  一切抛开试题看分数都是在耍流氓。考试考的不只是学生的掌握水平,还有老师的出题水平。那我们就来看看这次考试的难度系数:

  难度系数是反映试题的难易程度的指标,难度系数越大自然考分就越低。难度系数这样来算:L=1—X/W其中,L为难度系数,X为样本平均得分,W为试卷总分。出(考)题(倒)无数的老师谈一点经验,试题的难度系数在0.3-0.7之间比较合适。

  生物难度系数为0.21,试题偏简单,及格率达到100%。物理难度系数为0.42,属于中等难度,而及格率仅为52%,说明这个班级物理成绩的确有待加强。

  其实,除了分析学生成绩之外,数据图表在平常的论文、报告、作业里也都适用的。

考试成绩分析案例:https://me.bdp.cn/share/index.html?shareId=sdo_a577450540c475cf4e7ccc9f1a6760d0编辑于 2016-09-12 17:31​赞同 162​​22 条评论​分享​收藏​喜欢收起​

知未

知未105 人赞同了该回答

如何科学地分析学生成绩?就小学、初高中的学生成绩分析而言,应该有以下几个要素:

  1. 多层次:在年级、班级、学生、科目、题目多个层面上分别详细分析,并提供便利的下钻途径,逐层细化分析,探寻问题的根源,而不是停留在统计结果的表象。
  2. 多维度:从原始的题目维度,扩展到难度范围、知识点和考察能力,从多个维度上评估一个学生或班级的能力特征。
  3. 多次数:单独的一次考试受很多因素的影响,只有结合多次考试的数据进行动态分析,才能更加客观地评价。

接下来结合图表案例进行说明。

年级层面上,首先关心的是整个年级的整体情况,例如各科的参考人数,均分,最高最低,标准差,优秀良好及格的三率等等,这些数据让级长对本次考试的整体表现有个基本的了解。

在年级总体均分的基础上,分析各分数段的人数,这样就对整个年级学生的分布有了直观认识,分布是否基本符合正态?是否有严重的两级分化?是否存在断层?

看完了整个年级的分数,接下来可以对各科目各班进行横向对比,通过均分柱图的比较,了解哪些班表现突出,哪些班落后于年级平均线。

但更重要的是,是要进行纵向的分析,即和上一次考试的数据对比,了解各班的进退步情况,对于有进步的给予鼓励,退步的给予提醒,而不单纯只看本次的绝对值。

同样,我们也应该对每个班在历次考试中的各项数据表现都进行跟踪观察,才能科学评估班级的每次进退步的性质,给予合理的激励。

各班的均分体现的是一个班的整体表现,那这个班级内部的学生分布情况如何呢?可以利用学生名次构成分析来了解,也许两个班都是一样的均分,但其学生群体的分布大不相同,接下来采取的教学措施也就不一样了,有的重点可能是培优,有的重点可能是补差。

就培优而言,年级和各班班主任都首先会关注高分段学生的占比:

例子中的4班、8班,在前100名的人数过少,该班的培优工作有待改进。

而在高三年级,我们特别重视各个分数线的达标情况,对每次考试我们都应设立各重点线、本科线的标准,分析并跟踪各班上线人数的情况,对于落实年级的上线指标任务尤为重要。

年级层面可以关注的分析内容还有很多,但任何一个总体层面的分析,都是为了分解问题:整体的表现欠佳,是源自那些班级的因素最大?明确了这一点,我们就知道要重点抓哪个班的工作。

那这个班具体该怎么改进,这就引出了对单个班级的分析。

班主任和任课老师,可以在名次分布和分数分布两方面来了解本班学生的总体情况。

对于表现不佳的学生,或者需要重点关注的临界生,则应分析他历次考试的表现情况,和最近考试科目平衡性,找出最优先改进的科目:

接下来就是针对该科目,详细分析他的题目层面的表现,了解该学生在哪些难度的题目上丢分较多,哪些知识点和考察能力较薄弱等等。

这些就是一个多层次、动态探究问题根源的完整过程,让一个年级层面的问题分解到一个学生具体的知识点层面的问题,把问题的解决落实到若干个可行的改进行动上,这样的分析最终才能产生教学质量进步的效果。也就是最前面提到的3要素:多层次、多维度、多次数;

要实现这样的分析体系,需要年级做到相应的准备工作:

1. 为每次考试收集详细的基础数据;

2. 建立合理的分析模型、采用高效率的分析工具;

3. 向全体师生分享数据,让大家在合理的权限控制下,适度参与分析,为自己的进步而分析。

这些工作有些是学校教务部门需要承担的,也有些可以采用外部的系统方案。目标只有一个,让每次考试所付出的时间和精力都得到回报,让考试产生的成绩数据,不仅用于正确地评价师生,更要给予师生们正确的反馈,引导师生进行有效的改进,从而实现教学质量的进步。

这些也是成绩云团队 一直致力于实现的目标,我们希望扮演的就是这么一个高效的工具系统,协助学校实现改进教学质量的大目标。

成绩云​chengjiyun.com/?from=zhihu

利用setInterval执行有限次的定时执行

使用setInterval可以定时无限次的执行某个事件,但如果想要执行一定的次数应该怎么操作?

代码如下:

        var t;  
        var ss=0;          
          
        function  setTimeOutss(){  
              
            ss+=1;  
            if(ss>(17)){  
                document.getElementById("dd").display="none";  
                document.getElementById("dd").innerHTML="";  
                clearInterval(t);  
            }  
        }  
        t=window.setInterval("setTimeOutss()",1000); 

关于七牛SSL过期的处理记录

这是很难忘的一天,今天早上想要把学生的总成绩传到平台上进行分析,但文件上传了却访问不了,由于之间没有处理过类似的问题,于是又是一天的尝试。

其实处理过程也就是重新申请证书,配置证书,之前的证书是在宝塔上做的,这次发现可以直接在七牛上申请免费的 TrustAsia 域名型 (DV) 单域名证书。

在配置证书完毕后,今天还做了域名所有权怎么验证,也就是在百度上进行。登陆百度账号 后找到“用户中心”>>“站点管理”,点击“添加网站”。输入域名和协议头,点击下一步。

经过不懈的努力终于解决了不能正常访问文件的问题.

Yii2.0实现的批量更新及批量插入功能示例

本文实例讲述了Yii2.0实现的批量更新及批量插入功能。分享给大家供大家参考,具体如下:

批量更新

方法1

/**
* 批量更新循环周期
* @param array $condition
* $condition = ['advertise_id' => '','status' => '', 'weekdays'=>[1,2,3]] 查询条件
* $params = ['status' => '']
* @param $params
* @return bool
*/
public function batchUpdateAdSchedule($condition = [], $params)
{
  if (count($condition) == 0 || !is_array($condition) || count($params) == 0) {
    return false;
  }
  $conditions = ' 1 = 1 ';
  $bind = [];
  if (array_key_exists('advertise_id', $condition) && !empty($condition['advertise_id'])) {
    $conditions .= ' AND `advertise_id` = :advertiseId';
    $bind['advertiseId'] = $condition['advertise_id'];
  }
  if (array_key_exists('status', $condition) && !empty($condition['status'])) {
    $conditions .= ' AND `status` = :status';
    $bind['status'] = $condition['status'];
  }
  $result = AdvertiseSchedule::updateAll($params, $conditions, $bind);
  return $result > 0 ? true : false;
}

方法2

/**
* 批量更新商品销量
* @param $params
* @return bool|int
* @throws \yii\db\Exception
*/
public function batchUpdateSalesNum($params)
{
  if (count($params) == 0 || !is_array($params)) {
    return false;
  }
  $sql = '';
  foreach ($params as $key => $value) {
    $sql .= 'UPDATE `morefun`.`mbb_goods` SET `sale_num` = `sale_num` -' . $value['amount'] . ' WHERE `id` =' . $value['goods_id'] . ';';
  }
  $result = Yii::$app->db->createCommand($sql)->execute();
  return $result == 1 ? true : false;
}

批量插入

/**
* 批量插入
* @param $params
* @return int
* @throws \yii\db\Exception
*/
public function batchAddShopClassConn($params)
{
  $connection = Yii::$app->db;
  $queryBuilder = $connection->queryBuilder;
  /*$sql = $queryBuilder->batchInsert('user', ['name', 'age'], [
    ['Tom', 30],
    ['Jane', 20],
    ['Linda', 25],
  ]);*/
  $sql = $queryBuilder->batchInsert(shopClassConn::tableName(),
    ['shop_id', 'class_id'], $params);
  return $connection->createCommand($sql)->execute();
}

PHP Ajax 跨域问题最佳解决方案

本文通过设置Access-Control-Allow-Origin来实现跨域。

例如:客户端的域名是client.runoob.com,而请求的域名是server.runoob.com。

如果直接使用ajax访问,会有以下错误:

XMLHttpRequest cannot load http://server.runoob.com/server.php. No 'Access-Control-Allow-Origin' header is present on the requested resource.Origin 'http://client.runoob.com' is therefore not allowed access.

1、允许单个域名访问

指定某域名(http://client.runoob.com)跨域访问,则只需在http://server.runoob.com/server.php文件头部添加如下代码:

header('Access-Control-Allow-Origin:http://client.runoob.com');

2、允许多个域名访问

指定多个域名(http://client1.runoob.com、http://client2.runoob.com等)跨域访问,则只需在http://server.runoob.com/server.php文件头部添加如下代码:

$origin = isset($_SERVER['HTTP_ORIGIN'])? $_SERVER['HTTP_ORIGIN'] : '';  
  
$allow_origin = array(  
    'http://client1.runoob.com',  
    'http://client2.runoob.com'  
);  
  
if(in_array($origin, $allow_origin)){  
    header('Access-Control-Allow-Origin:'.$origin);       
} 

3、允许所有域名访问

允许所有域名访问则只需在http://server.runoob.com/server.php文件头部添加如下代码:

header('Access-Control-Allow-Origin:*'); 

用了16款考研刷题app,就一两款好用,心好累

可考点、可随机、可刷套卷,有笔记、收藏、错题本,有计时,有手写蒙版打草稿

1.我是在职考研,选择刷题app,利用日常工作和通勤的间隙刷一刷。

2.主要用于刷管理类联考(管综),历年真题。

3.比较推荐的app有

MBA大师:可考点、可随机、可刷套卷,有计时,有错题集锦也可收藏题反复刷,做题时有手写蒙版打草稿,贴心。(缺点是只能全部做完提交才能看答案)(如下图)

粉笔考研:可刷套卷,可随机,可智能组合,有计时,有错题集锦也可收藏题反复刷,还有笔记和历史记录可查,做题时有手写蒙版打草稿,贴心。 (缺点是不能单独刷考点)

4.可以用用的

考研全题库:可考点、可随机、可刷套卷,有笔记、收藏、错题本,有计时,有手写蒙版打草稿(缺点是真题只更新到2018年)

5.不推荐

考研汇:之前最喜欢的一款,因为可以一道题一道题的刷(充分利用碎片时间),不需要等到刷完了提交才能看答案。可考点、可随机、可套卷、有计时,可收藏、有笔记,有错题本。(缺点是真题有乱码,有的题干表格无法显示,跟客服反馈没有任何回应)刷真题遇到几次题干有错误,无语(如下图)

考研准题库:可考点、随机、刷套卷,有笔记、收藏、错题本,有计时(缺点:没有蒙版打草稿,免费的真题只有4套,升级题库需要付费,且注册完了没一会 就有人打电话过来叫我报班

小西考研:可智能、可随机、可刷套题,有错题本、有收藏、有笔记(缺点:考点练习打不开,没有草稿蒙版。)

考研帮:刷题大部分功能都有,没有蒙版草稿功能(缺点:真题题库只更新到2017年)

掌上考研:主要是提供咨询,没有找到刷题的地方。

考虫:是上课的,没有找到刷题的地方。

研途考研:只有政治题,app会跳转到微信小程序刷题(不明白app存在的意义)

考研通:支付宝一键登录,还要验证手机,我觉得不安全,直接放弃了登陆,就用不了了。

师兄帮帮:拍照搜题用的,没有题库。

太府考研:属于咨询上课类型的,不能刷题。

橙啦:以英语为主,听课用的,练习科目没有管综,再见!

考研派:题库只有英语、政治,且真题题库只更新到2017年,再见!

口袋题库考研:专门刷题的app,啥都收费,它没什么不好,是我不好,我穷。(如下图)

php去除换行(回车换行)的三种方法


<?php   
 //php 不同系统的换行  
//不同系统之间换行的实现是不一样的  
//linux 与unix中用 \n  
//MAC 用 \r  
//window 为了体现与linux不同 则是 \r\n  
//所以在不同平台上 实现方法就不一样  
//php 有三种方法来解决  

//1、使用str_replace 来替换换行  
$str = str_replace(array("\r\n", "\r", "\n"), "", $str);   

//2、使用正则替换  
$str = preg_replace('//s*/', '', $str);  

//3、使用php定义好的变量 (建议使用)  
$str = str_replace(PHP_EOL, '', $str);   
?>  

Markdown image 替换为 html标签

使用Typora可以实现公式的预览,图片自动上传到服务器,但图片是markdown语法,这里实现从Markdown 转化为 Html的 img标签

public static function imageReplace($content)
{

	$pattern = ['/!\[img\]\((.*)\)/U','/<p>\s*<\/p>/U'];

	$replacement = ['<img src="\\1" \/>','']; 

	return preg_replace($pattern, $replacement, $content);

}