2

加密解密类

由于 PHP7.1 开始废弃传统的加密函数 mcrypt_encrypt 而改用 openssl_encrypt,因此该类支持的 PHP 版本为: (PHP 5 >= 5.3.0, PHP 7)

<?php

/**
    * 简易加解密类
    */
class Mcrypt {
    // 通用秘钥
    private $KEY = 'YOUR SECRET KEY';

    private $METHOD = 'AES-128-ECB';
    // 所有可用的加密类型可参考: http://php.net/manual/zh/function.openssl-get-cipher-methods.php
    /**
        * 构造函数
        *
        * @param string 加密类型。若不传,则为默认的 AES-128-ECB.
        * @return void
        */
    public function __constructor($method = '') {
        if (!empty($method)) {
            $this->METHOD = $method;
        }
    }

    /**
        * 加密字符串
        *
        * @param String 待加密数据
        * @param string 加密秘钥,若为空,则使用通用秘钥
        * @return void
        */
    public function encrypt($input, $key = '') {
        if (empty($key)) $key = $this->KEY;
        $data = openssl_encrypt($input, $this->METHOD, $key, OPENSSL_RAW_DATA);
        $data = base64_encode($data);

        return $data;
    }

    /**
        * 解密字符串
        *
        * @param String 待解密字符串
        * @param string 解密秘钥,若为空,则使用通用秘钥
        * @return void
        */
    public function decrypt($input, $key = '') {
        if (empty($key)) $key = $this->KEY;
        $data = openssl_decrypt(base64_decode($input), $this->METHOD, $key, OPENSSL_RAW_DATA);

        return $data;
    }
}

发送邮件类

先下载 PHPMailer,解压后,将其放置你的项目中,并修改类中的引入路径。

<?php
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;

require dirname(__FILE__).'/PHPMailer/Exception.php';
require dirname(__FILE__).'/PHPMailer/PHPMailer.php';
require dirname(__FILE__).'/PHPMailer/SMTP.php';

class Mail {
    private $_email = null;
    private $_baseURL = '';

    public function __construct() {
        $this->_init();
        $this->_baseURL = $_SERVER['REQUEST_SCHEME'] . '://' . $_SERVER['HTTP_HOST'];
    }

    private function _init() {
        if ($this->_email == null) {
            $mail = new PHPMailer(true);
            try {
                $mail->SMTPDebug = 0;
                $mail->isSMTP();
                $mail->Host = get_global_config('mail.Host');
                $mail->SMTPAuth = true;
                $mail->Username = get_global_config('mail.Username');
                $mail->Password = get_global_config('mail.Password');
                $mail->SMTPSecure = get_global_config('mail.SMTPSecure');
                $mail->Port = get_global_config('mail.Port');
                $mail->setFrom(get_global_config('mail.Username'), get_global_config('mail.Fromname'));
                $this->_email = $mail;
                return true;
            } catch (Exception $e) {
                // return null;
                return false;
            }
        }
        return true;
    }

    public function sendEmail($toEmail, $toUsername, $subject, $body) {
        if (!$this->_email) return false;
        try {
            $this->_email->addAddress($toEmail, $toUsername);
            $this->_email->isHTML(true);
            $this->_email->Subject = $subject;
            $this->_email->Body    = $body;
            // 当邮件不支持 HTML 时显示的邮件内容
            $this->_email->AltBody = $body;
        
            $this->_email->send();
            // echo 'Message has been sent';
            return true;
        } catch (Exception $e) {
            return false;
            // echo 'Message could not be sent.';
            // echo 'Mailer Error: ' . $this->_email->ErrorInfo;
        }
    }
}

模拟锁

使用 Redis 模拟进程锁,参考至 discuz 的进程锁源码。

<?php 

/**
 * 模拟进程锁
 */
class Process {
    protected $cache;

    /**
     * 构造函数,初始化 redis
     */
    public function __construct() {
        $this->cache = Roc::redis();
        $this->cache->select(Roc::get('redis.db'));
    }

    /**
     * 是否被锁
     *
     * @param string 锁名
     * @param integer 上锁时间
     * @return boolean
     */
    public function islocked($process, $ttl = 0) {
        $ttl = $ttl < 1 ? 600 : intval($ttl);
        return $this->_status('get', $process) || $this->_find($process, $ttl);
    }

    /**
     * 解锁
     *
     * @param string 锁名
     * @return void
     */
    public function unlock($process) {
        $this->_status('rm', $process);
        $this->_cmd('rm', $process);
    }

    private function _status($action, $process) {
        static $plist = array();
        switch ($action) {
            case 'set' : $plist[$process] = true; break;
            case 'get' : return !empty($plist[$process]); break;
            case 'rm' : $plist[$process] = null; break;
            case 'clear' : $plist = array(); break;
        }
        return true;
    }

    private function _find($name, $ttl) {

        if(!$this->_cmd('get', $name)) {
            $this->_cmd('set', $name, $ttl);
            $ret = false;
        } else {
            $ret = true;
        }
        // $this->_status('set', $name);
        return $ret;
    }

    private function _cmd($cmd, $name, $ttl = 0) {
        return $this->_process_cmd_memory($cmd, $name, $ttl);
        // static $allowmem;
        // if($allowmem === null) {
        //     $allowmem = Roc::get('redis.db');
        // }
        // if($allowmem) {
        //     return self::_process_cmd_memory($cmd, $name, $ttl);
        // } else {
        //     return false;
        //     // return self::_process_cmd_db($cmd, $name, $ttl);
        // }
    }

    private function _process_cmd_memory($cmd, $name, $ttl = 0) {
        $ret = '';
        $name = 'process_lock_'.$name;
        switch ($cmd) {
            case 'set' :
                $ret = $this->cache->setex($name, time(), $ttl);
                // $ret = memory('set', 'process_lock_'.$name, time(), $ttl);
                break;
            case 'get' :
                $ret = $this->cache->get($name);
                // $ret = memory('get', 'process_lock_'.$name);
                break;
            case 'rm' :
                $ret = $this->cache->delete($name);
                // $ret = memory('rm', 'process_lock_'.$name);
        }
        echo $cmd . ':';
        var_dump($ret);
        return $ret;
    }

    private function _process_cmd_db($cmd, $name, $ttl = 0) {
        $ret = '';
        switch ($cmd) {
            case 'set':
                $ret = C::t('common_process')->insert(array('processid' => $name, 'expiry' => time() + $ttl), FALSE, true);
                break;
            case 'get':
                $ret = C::t('common_process')->fetch($name);
                if(empty($ret) || $ret['expiry'] < time()) {
                    $ret = false;
                } else {
                    $ret = true;
                }
                break;
            case 'rm':
                $ret = C::t('common_process')->delete_process($name, time());
                break;
        }
        return $ret;
    }
}

Redis

一个简易的 Redis 操作类,支持在查找不到缓存时,进行相对应的回调操作。

<?php

class Cache {
    protected $cache;
    protected $prefix;

    public function __construct() {
        // 根据项目实际情况初始化你的 Reids。
        $this->cache = new Redis();
    }

    // ============= String 操作
    /**
     * 设置缓存
     *
     * @param String 缓存key值
     * @param String/Object 缓存数据,可为字符串可为数组。
     * @param Int 过期时间
     * @return Boolean
     */
    public function set($key, $value, $ttl = null) {
        if (is_array($value)) $value = serialize($value);
        if ($ttl !== null && $ttl > 0)
            return $this->cache->setex($this->_key($key), $ttl, $value);
        else
            return $this->cache->set($this->_key($key), $value);
    }

    /**
     * 获取缓存数据
     *
     * @param String 值
     * @param Data 默认值,设置后,如果缓存没有数据则返回默认值
     * @return Data
     */
    public function get($key, $callback = false) {
        $res = $this->cache->get($this->_key($key));
        if ($res === false && $callback === true) {
            $method_name = "_$key";
            if (method_exists($this, $method_name)) {
                return $this->$method_name();
            } else {
                return false;
            }
            
        }
        // 如果反序列化成功,则返回反序列化的数据。
        // @防止报 warning。
        if (@unserialize($res) !== false) return unserialize($res);
        return $res;
    }

    /**
     * 删除缓存
     *
     * @param String 需要删除的键名
     * @return true or false
     */
    public function rm($key) {
        return $this->cache->delete($this->_key($key));
    }

    public function inc($key, $step = 1) {
        return $this->cache->incr($this->_key($key), $step);
    }

    public function dec($key, $step = 1) {
        return $this->cache->decr($this->_key($key), $step);
    }

    private function _key($key) {
        return $this->prefix . $key;
    }

    public function getMultiple($keys) {
        $_keys = [];
        foreach ($keys as $key) $_keys[] = $this->_key($key);
        return $this->cache->getMultiple($_keys);
    }

    // ============== Hash 操作
    public function hset($hash, $key, $value) {
        return $this->cache->hSet($hash, $key, $value);
    }

    public function hget($hash, $key) {
        return $this->cache->hGet($hash, $key);
    }

    public function hgetall($hash) {
        return $this->cache->hGetAll($hash);
    }

    public function hvals($hash) {
        return $this->cache->hVals($hash);
    }

    public function hkeys($hash) {
        return $this->cache->hKeys($hash);
    }


    // ================ 通用回调
    // Your callback code here.
}

leungjz
919 声望25 粉丝