PHP定时器

浏览:14442 发布日期:2017/08/04 分类:功能实现 关键字: PHP 定时器 异步
PHP定时器Timer类
内容见附件 windows下的定时是用ping所以不是很准确
需要系统有curl的支持 linux可以 yum install curl 即可
windows 把附件的curl.exe 放到代码中的cmd里面的目录E:\YS\JAVA\curl\curl.exe即可/**
 *  定时器
 */
class Timer {

    const LOG_PRE = 'base/lib/timer/';
    const SHELL_DIR = 'basetimer/';
    private $tips;

    /**
     *  初始化
     */
    public function __construct() {
        
    }

    /**
     *  根据 时间 和 url 延时请求 url
     *  return 0|ok 1|err
     */
    public function addTimer($time, $url) {
        $time = floor(floatval($time));
        $nowTime = $this->microTime();
        $type = $this->isWin();
        $logTimer = [];
        $logTimer[] = '开始添加定时任务addTimer:'.$nowTime;
        $logTimer[] = 'time='.$time;
        $logTimer[] = 'url='.$url;
        $fileName = $this->fileName($url);
        $file = $this->shellDir().$fileName;
        $filePostFix = $type ? '.bat' : '.sh';
        $file = $file.$filePostFix;
        if ($type) {
            $file = $this->cmdPathReplace($file);
        }
        $logTimer[] = 'file='.$file;
        $logTimer[] = 'sys type='.($type ? 'cmdStr' : 'shellStr');
        // shell
        $shellStr = <<<shellStr
#!/bin/sh
# $nowTime
#time $time
#url $url
echo `date +"%Y-%m-%d %H:%M:%S"`
sleep $time
echo `date +"%Y-%m-%d %H:%M:%S"`
curl $url
# delete file
if [ -f $file ]; then
    rm -f $file
fi

shellStr;
        $shellStr = str_replace("\r", '', $shellStr);
        $logTimer[] = 'shellStr=';
        $logTimer[] = $shellStr;
        // cmd
        $cmdStr = <<<cmdStr
rem $nowTime
rem time $time
rem url $url
@echo off
echo %Date% %Time%
ping -n $time 127.0.0.1>nul
echo %Date% %Time%
E:\YS\JAVA\curl\curl.exe $url
rem delete file
if exist $file del $file
exit

cmdStr;
        $logTimer[] = 'cmdStr=';
        $logTimer[] = $cmdStr;
        $logTimer[] = 'file_put_contents='.file_put_contents($file, $type ? $cmdStr : $shellStr);
        $this->log($logTimer);
        // 执行shell
        if ($type) {
            $this->runCmdFile($file, $fileName);
        } else {
            $this->runShellFile($file, $fileName);
        }
        return 0;
    }

    /**
     *  根据 文件 执行 shell
     */
    private function runShellFile($file, $fileName) {
        $logFile = $this->shellLogDir().$fileName.'.log';
        pclose(popen("sh $file >> $logFile &", "r"));
    }

    /**
     *  根据 文件 执行 cmd
     */
    private function runCmdFile($file, $fileName) {
        $logFile = $this->shellLogDir().$fileName.'.log';
        pclose(popen("start /b $file >> $logFile", "r"));
    }

    /**
     *  cmd path replace
     */
    private function cmdPathReplace($path) {
        $path = str_replace('/', '\\', $path);
        return $path;
    }

    /**
     *  判断 是否是 windows
     *  return ture|是 false|不是
     */
    private function isWin() {
        $name = php_uname();
        if (strtolower(substr($name, 0, 6)) == 'window') {
            return true;
        }
        return false;
    }

    /**
     *  日志记录
     */
    private function log($con, $type = '') {
        $folder = self::LOG_PRE.$type.'/';
        $file = './FileData/'.$folder;
        $time = time();
        $file = $file.'/'.date('Ym', $time).'/'.date('Ymd', $time).'.log';
        // 创建文件
        if (!$this->file($file)) {
            return false;
        }
        // 追加写入
        if (file_put_contents($file, var_export($con, true), FILE_APPEND | LOCK_EX) === false) {
            $this->tips = '写入文件失败!';
            return false;
        }
        return true;
    }

    /**
     *  获取shell 保存的绝对目录 以 / 结尾
     */
    private function shellDir() {
        $path = './FileData/';
        $path = $path.self::SHELL_DIR.'shelldir/';
        $file = 'readme.md';
        if ($this->file($path.$file)) {
            $path = dirname(realpath($path.$file)).'/';
        }
        return $path;
    }

    /**
     *  获取 shell log 保存的绝对目录 以 / 结尾
     */
    private function shellLogDir() {
        $time = time();
        $path = './FileData/';
        $path = $path.self::SHELL_DIR.'shelldir/'.'runshelllog/'.date('Ym/', $time);
        $file = 'readme.md';
        if ($this->file($path.$file)) {
            $path = dirname(realpath($path.$file)).'/';
        }
        return $path;
    }

    /**
     *  生成一个新的文件名 用来记录即将要执行的shell
     */
    private function fileName($key = '') {
        $key = md5('md5'.$key);
        // 其实这里创建一张表 来维护这些文件名最好 但我就不
        list($h, $t) = explode(' ', microtime());
        $date = date('YmdHis', $t);
        $time = $date.substr($h, 2);
        $max = 10000000;
        $rand = rand(1, $max);
        $num = $max + floor($rand);
        $name = $time.'ms'.$num.'r'.$key;
        $name = strtolower($name);
        return $name;
    }

    /**
     *  判断文件是否存在 ,不存在创建
     */
    public function file($file) {
        $result = true;
        if (file_exists($file)) {
            return true;
        }
        // 创建目录
        if (!$this->mkDir(dirname($file))) {
            return false;
        }
        // 创建文件
        $fp = fopen($file, "x+");
        if (!$fp) {
            $result = false;
            $this->tips = $file.' 文件创建失败!';
        }
        fclose($fp);
        return $result;
    }

    /**
     *  创建文件夹
     */
    public function mkDir($path) {
        if (is_dir($path)) {
            return true;
        }
        if (!is_dir(dirname($path))) {
            if (!$this->mkDir(dirname($path))) {
                return false;
            }
            return $this->mkDir($path);
        }
        if (!mkdir($path)) {
            $this->tips = $path.' 目录创建失败!';
            return false;
        }
        return true;
    }

    /**
     *  获取 当前时间 毫秒级
     */
    public function microTime() {
        list($h, $t) = explode(' ', microtime());
        $date = date('Y-m-d H:i:s', $t);
        $time = $date.'.'.substr($h, 2);
        return $time;
    }
}
用法如下//使用
$timer = new Timer();
$timer->addTimer(10, 'www.thinkphp.cn');

附件 Timer.zip ( 851.44 KB 下载:294 次 )

评论( 相关
后面还有条评论,点击查看>>