Joyber 发布的文章

在开发中写了一个生成商品推广海报的功能,代码记录到这里以备后面有需求的时候直接用就可以:


        $mod = new Model_Product();
        $item = $mod->getProduct($this->_input->id);
        if (empty($item)) {
            return $this->warning('商品已删除');
        }

        $conf   = Sr::arrayGet($this->conf, 'wxapp');
        $page   = 'p/index';

        if (false) {
            //test app
            $conf['app_id'] = 'wx499be8478f6cd037';
            $conf['secret'] = '9c0e112b45c108f39c7976ca8a36359e';
            $page = '';
        }

        $wxapp    = new SrWxApp($conf);
        $images = explode(',', $item['image']);
        $dst_path = $images[0]; // 背景图
        $user_id  = $this->_userId;
        $filepath = 'product/'.$item['id'].'_' . $user_id . '_' . md5($item['image']) . '.png';
        $outpath  = $this->conf['upload_path'] . $filepath;
        if (is_file($outpath)) {
            //邀请海报存在,直接返回
            $url = str_replace('http:', 'https:', $this->conf['upload_domain']);
            return $this->success(['url'=>$url. $filepath]);
        }

        if (!is_dir(dirname($outpath))) {
            @mkdir(dirname($outpath), 0766, true);
        }

        $qrcodepath    = "product/{$item['id']}_{$user_id}_". md5($page) .'.qrcode.png';
        $qrcodefile = $this->conf['upload_path'] . $qrcodepath;
        if (!is_file($qrcodefile)) {
            //创建二维码
            if (!is_dir(dirname($qrcodefile))) {
                @mkdir(dirname($qrcodefile), 0766, true);
            }
            $res = $wxapp->getUnlimit('iid='.$item['id'].'&uid='.$user_id, ['page'=>$page], $qrcodefile);
            if (!$res) {
                $this->logger->log($wxapp->error, 'create_invite_image_err');
                $this->error = '获取二维码失败';
                return false;
            }
        }

        //配置
        $qrw = 150; //码宽高
        $qrh = 150;
        $bgx = 575; //码坐标
        $bgy = 775;

        //创建图片的实例
        $dst = imagecreatefromstring(file_get_contents($dst_path));
        $src = imagecreatefromstring(file_get_contents($qrcodefile));
        //将二维码白色背景透明,接口有参数可以做到透明的
        //imagecolortransparent($src, imagecolorallocate($src, 255, 255, 255));
        //获取水印图片的宽高
        list($dst_w, $dst_h) = getimagesize($dst_path);
        list($src_w, $src_h) = getimagesize($qrcodefile);
        //创建图像,将二维码和商品图片复制到图片上
        $newimg = imagecreatetruecolor(750, 750+200);
        //将图片设置成白色
        $bgcolor = imagecolorallocate($newimg, 255, 255, 255);
        $txtcolor = imagecolorallocate($newimg, 50, 50, 50);
        imagefill($newimg, 0,0, $bgcolor);
        //写文本
        $fontfile = SOTER_APP_PATH . '/data/Alibaba-PuHuiTi-Medium.ttf';
        imagefttext($newimg, 24, 0, 25, 750 + 25 + 24, $txtcolor, $fontfile, $item['title']);
        imagefttext($newimg, 14, 0, 450, 915, $txtcolor, $fontfile, '长按扫码购买');
        imagecopyresampled($newimg, $dst, 0, 0, 0, 0, 750, 750, $dst_w, $dst_h);
        imagecopyresampled($newimg, $src, $bgx, $bgy, 0, 0, $qrw, $qrh, $src_w, $src_h);
        //将水印图片复制到目标图片上
        //imagecopymerge($dst, $src, $bgx, $bgy, 0, 0, $qrw, $qrh, 100);
        //生成图片
        $uu       = imagepng($newimg, $outpath);
        //销毁
        imagedestroy($dst);
        imagedestroy($src);
        imagedestroy($newimg);
        if ($uu) {
            $url = str_replace('http:', 'https:', $this->conf['upload_domain']);
            return $this->success(['url' => $url . $filepath]);
        }

        return $this->warning('创建海报失败');

这篇文章主要介绍了php脚本守护进程原理与实现方法,较为详细的分析了php脚本守护进程的实现思路、原理、格式及具体实现方法,需要的朋友可以参考下

本文实例讲述了php脚本守护进程原理与实现方法。分享给大家供大家参考,具体如下:

思路:

  1. while 循环,若当前没有数据要操作可以休眠;
  2. crontab 脚本每隔固定时间段执行该脚本,执行时先检测是否已在执行,若无 执行,有则 跳过。
  3. nohup 后台执行
  4. flock -xn 加锁

实例:

要执行代码:index.php

<?php
set_time_limit(0);
//死循环
while(1) {
  $message = '1111111' . "\n";
  error_log($message);
  sleep(5);
}

/tmp/lock/test1.lock 为当前进程要锁定的文件,不同的进程配置不同的锁文件,该文件会自动创建

* * * * * flock -xn /tmp/lock/test1.lock -c 'nohup php index.php >> /php/test.log 2>&1 &'
* * * * * flock -xn /tmp/mytest.lock -c 'php /home/fdipzone/php/test.php >> /home/fdipzone/php/test.log'

在写好的php脚本。为防止守护进程内存溢出,建议定期检测内存占用。
将以下代码放到业务脚本中:

if(memory_get_usage()>100*1024*1024){
  exit('内存溢出');//大于100M内存退出程序,防止内存泄漏被系统杀死导致任务终端
}

注意:

nohup 任务查看与关闭方法:

关闭:

//方法一:
ps -e | grep commend
kill -9 pid
//方法二:
fg %n  //n为jobs命令查看的进程号

查看:

//查看后台进程
jobs

原理:

使用linux flock 文件锁实现任务锁定,解决冲突

格式:

flock [-sxun][-w #] fd#
flock [-sxon][-w #] file [-c] command

选项

-s, --shared:    获得一个共享锁
-x, --exclusive: 获得一个独占锁
-u, --unlock:    移除一个锁,通常是不需要的,脚本执行完会自动丢弃锁
-n, --nonblock:  如果没有立即获得锁,直接失败而不是等待
-w, --timeout:   如果没有立即获得锁,等待指定时间
-o, --close:     在运行命令前关闭文件的描述符号。用于如果命令产生子进程时会不受锁的管控
-c, --command:   在shell中运行一个单独的命令
-h, --help       显示帮助
-V, --version:   显示版本

运行一个php文件,文件锁使用独占锁,如果锁定则失败不等待。参数为-xn

* * * * * flock -xn /tmp/mytest.lock -c 'php /home/fdipzone/php/test.php >> /home/fdipzone/php/test.log'

这样当任务未执行完成,下一任务判断到/tmp/mytest.lock被锁定,则结束当前的任务,下一周期再判断。