小程序系列 - 登录获取 UnionID 方式

一、UnionID 机制说明

如果开发者拥有多个移动应用、网站应用、和公众帐号(包括小程序),可通过 unionid 来区分用户的唯一性,因为只要是同一个微信开放平台帐号下的移动应用、网站应用和公众帐号(包括小程序),用户的 unionid 是唯一的。换句话说,同一用户,对同一个微信开放平台下的不同应用,unionid 是相同的。

要获取 unionid,需先注册微信开放平台并完成开发者认证,然后把应用绑定到微信开放平台。

二、UnionID 登录获取方式

小程序登录获取 unionid 主要有两种方式,有丰富公众号开发经验的童鞋,千万不要用公众号的思维直接带入,不然会给自己挖坑。下面详细说明:

1. wx.login + code2Session

小程序端调用 wx.login 获取 code 传给后端,后端通过 code2Session 接口获取 unionid,但要满足下面两种条件之一:

  • 开发者帐号下存在同主体的公众号,并且该用户已经关注了该公众号。
  • 开发者帐号下存在同主体的公众号或移动应用,并且该用户已经授权登录过该公众号或移动应用。

否则 code2Session 接口只会返回 openid 相关信息,不会返回 unionid,很明显单纯使用这种方式不能满足我们的需求。

code2Session 接口官方文档地址: https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/login/auth.code2Session.html

2. wx.getUserInfo + 后端解密

小程序端调用 wx.getUserInfo 获取用户的加密数据 encrypted_data 和 iv 传给后端,后端通过解密获取 unionid。

效验及解密官方文档地址:https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/signature.html

前后端可以通过两种方式配合实现最佳登录逻辑。


本文首发于马燕龙个人博客,欢迎分享,转载请标明出处。
马燕龙个人博客:http://www.mayanlong.com
马燕龙个人微博:http://weibo.com/imayanlong
马燕龙Github主页:https://github.com/yanlongma

自己撸一个 LaraDock(使用 Docker LNMP 部署 PHP 开发环境)

项目简介

Docker LNMP 是基于 docker-compose 开发的运行在 Docker 上的 LNMP 开发环境,包含 PHP、MySQL、Redis 等镜像并支持多版本切换,满足您的学习、开发和测试需求。

Github 地址:https://github.com/yanlongma/docker-lnmp

包含镜像

Docker LNMP 包含以下镜像,每种镜像支持多个版本:

  • nginx
  • php-fpm (7.3 - 7.2 - 7.1 - 5.6)
  • mysql (8.0 - 5.7 - 5.6)
  • mongo
  • redis (5.0 - 4.0)
  • memcached (1.5.16 - 1.5 - 1)

其中:

php-fpm 默认是 7.1 版本,如需使用其它版本,配置 .env 文件中 PHP_VERSION 即可;

mysql 默认是 5.7 版本,如需使用其它版本,配置 .env 文件中 MYSQL_VERSION 即可;

下载使用

Docker LNMP 默认将同级目录映射到 php-fpm 容器的工作目录,在项目的同级目录下载 Docker LNMP:

$ git clone https://github.com/yanlongma/docker-lnmp.git

进入 docker-lnmp 目录,生成配置文件 .env

$ cd docker-lnmp
$ cp env-template .env

如需映射到其它目录,配置 .env 文件中 WEB_ROOT_PATH 即可。

启动服务

在 docker-lnmp 目录,启动服务,命令如下:

$ docker-compose up -d nginx
Creating network "docker-lnmp_default" with the default driver
Creating docker-lnmp_mysql_1   ... done
Creating docker-lnmp_php-fpm_1 ... done
Creating docker-lnmp_nginx_1   ... done

nginx 默认会启动 php-fpm 和 mysql 服务,如需启动其它服务请手动添加,可选服务有 mongo、redis、memcached。

启动成功后,在 docker-lnmp 同级目录新建 phpinfo.php 文件,浏览器访问 http://localhost/phpinfo.php,则可看到 phpinfo() 相关信息。

关闭服务

在 docker-lnmp 目录,关闭服务,命令如下:

$ docker-compose down

构建服务

如修改 dockerfile 文件,需重新构建服务,如重新构建 php-fpm 命令如下:

$ docker-compose build php-fpm

建议先关闭服务,构建完成再重启服务。

虚拟主机

配置虚拟主机请参考 nignx/sites/yii.conf 文件,配置完需构建并重启服务。

License

MIT license

Chart.js 动态图表的使用

一、相关资料

1. 简介

Chart.js 是一个基于 HTML5 的简单的面向对象的图表库,支持包括 IE7/8 和所有现代浏览器。支持六种图标:曲线图(Linecharts)、柱状图(Barcharts)、雷达图(Radarcharts)、饼状图(Piecharts)、极坐标区域图(Polararea charts)以及圆环图(Doughnutcharts)。并且带有动画效果(animated),支持 retina 屏。

2. 官网

官网:https://www.chartjs.org/

二、示例代码

本案例演示了最近 24 小时的 PV/UV 实时数据,在线 DEMO

<!DOCTYPE html>
<html>
<head>
    <title>Chart.js 动态图表的使用</title>
    <script src="https://cdn.jsdelivr.net/npm/chart.js@2.8.0"></script>
</head>
<body>
    <div>
        <canvas id="chart"></canvas>
    </div>

    <script type="text/javascript">
    
        var dataLabels = ['1h', '2h', '3h', '4h', '5h', '6h', '7h', '8h', '9h', '10h', '11h', '12h', '13h', '14h', '15h', '16h', '17h', '18h', '19h', '20h', '21h', '22h', '23h', '0h'];
        var dataPV = [133058,253219,255194,233058,253219,277318,277714,273337,255194,277318,277714,273337,233058,253219,277318,253219,277318,277714,273337,255194,277714,273337,255194,293058];
        var dataUV = [10651,22039,23955,23754,22664,10651,22039,23765,23955,23754,22664,23765,23955,23754,22664,10651,22039,23765,10651,22039,23765,23955,23754,22664];

        var config = {
            type: 'line',
            data: {
                labels: dataLabels,
                datasets: [
                    {
                        label: 'PV',
                        data: dataPV,
                        backgroundColor: 'rgb(255, 99, 132)',
                        borderColor: 'rgb(255, 99, 132)',
                        fill: false,
                    },
                    {
                        label: 'UV',
                        data: dataUV, 
                        backgroundColor: 'rgb(75, 192, 192)',
                        borderColor: 'rgb(75, 192, 192)',
                        fill: false, 
                    }
                ]
            },
            options: {
                responsive: true,
                title: {
                    display: true,
                    text: 'PV/UV 实时统计'
                },
            }
        };

        var ctx = document.getElementById('chart').getContext('2d');
        var chart = new Chart(ctx, config);

        setInterval(function() {
            if (config.data.datasets.length > 0) {

                var last = parseInt(dataLabels[dataLabels.length - 1]);
                var label = last + 1;
                if (last >= 23) {
                    label = 0;
                }
                label = label + 'h';

                dataLabels.push(label);
                dataPV.push(getRandomNum(200000, 300000));
                dataUV.push(getRandomNum(10000, 80000));

                dataLabels.shift();
                dataPV.shift();
                dataUV.shift();

                chart.update();
            }
        }, 1000);

        function getRandomNum(min, max) {
            var range = max - min;
            var rand = Math.random();
            return(min + Math.round(rand * range));
        }

    </script>
</body>
</html>

本文首发于马燕龙个人博客,欢迎分享,转载请标明出处。
马燕龙个人博客:http://www.mayanlong.com
马燕龙个人微博:http://weibo.com/imayanlong
马燕龙Github主页:https://github.com/yanlongma

Nginx 系列 - 用 GoAccess 实现可视化并实时监控 access 日志

一、安装使用

1. 安装 GoAccess

本例使用源码安装,./configure 如果出错请看问题说明部分:

$ wget https://tar.goaccess.io/goaccess-1.3.tar.gz
$ tar -xzf goaccess-1.3.tar.gz
$ cd goaccess-1.3
$ ./configure --enable-utf8 --enable-geoip=legacy
$ make
# make install

2. 修改 Nginx 配置

nginx.conf 文件中新增以下配置:

location /report.html {
        alias /usr/local/nginx/html/report.html;
}

并重新加载配置文件:

$ /usr/local/nginx/sbin/nginx -s reload

3. 启动 GoAccess

在 nginx 安装目录下,执行 goaccess 命令:

$ cd /usr/local/nginx
$ goaccess ./logs/access.log -o ./html/report.html --real-time-html --time-format='%H:%M:%S' --date-format='%d/%b/%Y' --log-format=COMBINED
WebSocket server ready to accept new client connections

4. 访问服务

在浏览器中打开http://127.0.0.1/report.html,如出现以下页面则安装配置成功:

goaccess-report

二、问题说明

本处整理了安装 GoAccess 执行 configure 命令报错和解决办法。

1. 如出现以下报错则需安装 GeoIP:

configure: error: 
    *** Missing development files for the GeoIP library

2. 如出现以下报错则需安装 NCurses:

checking for mvaddwstr in -lncursesw... no
configure: error: *** Missing development libraries for ncursesw

3. 解决办法

官方已经给出了各个平台对应依赖包的名字(传送至官网),只需使用对应平台的包管理工具安装即可,如下图:

goaccess-distribution-package.png

如以上两个报错在 centos 下只需安装 geoip-devel 和 ncurses-devel 即可:

$ yum install geoip-devel ncurses-devel

4. 相关资料

GoAccess 官网:https://goaccess.io


本文首发于马燕龙个人博客,欢迎分享,转载请标明出处。
马燕龙个人博客:http://www.mayanlong.com
马燕龙个人微博:http://weibo.com/imayanlong
马燕龙Github主页:https://github.com/yanlongma

手把手教你使用 GitBook

一、简介

GitBook 是一个支持用 MarkDown 编写文档的软件,支持输出 HTML、PDF、eBook 格式文档。作为开发者我们一般会用它来写一些技术和接口文档。

GitBook 官网:https://www.gitbook.com

二、安装

1. 安装 Node.js

GitBook 是基于 Node.js 的命令行工具,需先下载安装 Node.js,检测是否安装成功:

$ node -v
v6.9.1

2. 安装 GitBook

使用 npm 安装 GitBook,命令如下:

$ npm install -g gitbook-cli

检测是否安装成功:

$ gitbook -V
CLI version: 2.3.2
GitBook version: 3.2.3

三、使用

1. 初始化

新建目录 book,在该目录下执行如下命令进行初始化:

$ gitbook init
warn: no summary file in this book 
info: create README.md 
info: create SUMMARY.md 
info: initialization is finished

该命令将会生成 README.mdSUMMARY.md 两个文件。其中 README.md 是对文档的简单介绍,可以用来作为封面,SUMMARY.md 是文档的目录结构。

也可以自己预先定义好 SUMMARY.md 中的目录结构,然后再用 init 命令初始化,程序将会根据我们的目录结构生成目录和文件,目录结构示例:

# Summary

* [Introduction](README.md)
* [Chapter1](chapter1/README.md)
    * [Section1.1](chapter1/section1.1.md)
    * [Section1.2](chapter1/section1.2.md)
* [Chapter2](chapter2/README.md)

2. 生成并预览

book 目录下执行如下命令,将会生成 HTML 文件并提供预览地址:

$ gitbook serve
Live reload server started on port: 35729
Press CTRL+C to quit ...

info: 7 plugins are installed 
info: loading plugin "livereload"... OK 
info: loading plugin "highlight"... OK 
info: loading plugin "search"... OK 
info: loading plugin "lunr"... OK 
info: loading plugin "sharing"... OK 
info: loading plugin "fontsettings"... OK 
info: loading plugin "theme-default"... OK 
info: found 1 pages 
info: found 0 asset files 
info: >> generation finished with success in 1.0s ! 

Starting server ...
Serving book on http://localhost:4000

在浏览器中打开 http://localhost:4000 即可看到初始化的文档。

如果只需生成 HTML 文件执行 build 命令即可,命令如下:

$ gitbook build

如果需要生成 PDF 文件,由于依赖 ebook-convert,需要安装 Calibre,安装配置完成后,执行如下命令即可:

$ gitbook pdf

3. 编辑器

现在支持实时预览的 markdown 编辑器有很多,可以根据自己的喜好选择,此处仅做推荐:

  • 官方编辑器 GitBook Editor
  • PhpStorm(不要问我为什么,我不会告诉你我是 PHP 程序猿)
  • Sublime Text(其实我写 MD 文档都不用预览,所以没给它装插件,龇牙)

四、配置

通过配置 book.json 中的参数,我们可以配置文档的很多信息,比如标题、侧边栏、插件等。
一个简单的 book.json 文件如下:

{
    "title": "GitBook 使用教程",
    "author": "Yanlong Ma <json_vip@163.com>",
    "description": "GitBook 使用教程 - 马燕龙个人博客",
    "generator": "site",
    "links": {
        "sidebar": {
            "马燕龙个人博客": "http://www.mayanlong.com"
        }
    }
}

下面介绍的插件也需要用到该配置。

五、插件

1. 自带插件

GitBook 默认带有五个插件:highlight、search、sharing、fontsettings、livereload。如果要去除自带的插件,可以在插件名称前面加”-“,如下:

"plugins": ["-search"]

2. 命名规范

GitBook 还支持许多插件,可以从 NPM 上搜索 GitBook 的插件,GitBook 推荐插件的命名方式如下,所以可以通过以下两种方式来搜索 GitBook 的插件或者主题:

gitbook-plugin-X: 插件
gitbook-theme-X: 主题

3. 安装插件

下面介绍如何安装 gitbook-plugin-prism 插件,在 NPM 搜索该插件,插件主页链接为 https://www.npmjs.com/package/gitbook-plugin-prism

首先安装该插件,命令如下:

$ npm i gitbook-plugin-prism

然后在 book.json 中添加该插件,同时禁用默认的 highlight,配置如下:

{
  "plugins": ["prism", "-highlight"]
}

可以根据自己的喜好,配置不同的主题:

"pluginsConfig": {
    "prism": {
        "css": [
            "prismjs/themes/prism-solarizedlight.css"
        ]
    }
}

本文首发于马燕龙个人博客,欢迎分享,转载请标明出处。
马燕龙个人博客:http://www.mayanlong.com
马燕龙个人微博:http://weibo.com/imayanlong
马燕龙Github主页:https://github.com/yanlongma

手把手教你发布自己的 Composer 包

一、前言

Composer 是 PHP 用来管理依赖(dependency)关系的工具。我们不仅要学会使用别人提供的包,更要学会制作和分享自己的软件包,下面演示如何创建一个自己的 Composer 包。

准备工作:

  1. 注册 Github 账号
  2. 注册 Packagist 账号

二、实践

本案例演示如何创建一个第三方消息推送(极光推送)的包。

1. 创建 Github 仓库

登录 Github,创建仓库 yanlongma/push,并将代码克隆到本地:

$ git clone https://github.com/yanlongma/push.git

2. 创建 Composer 配置文件

进入项目根目录,创建 Composer 配置文件 composer.json,可以使用命令 compser init 创建也可以手动创建,最终文件内容大体如下:

{
    "name": "yanlongma/push",
    "description": "Third party message push",
    "authors": [
        {
            "name": "Yanlong Ma"
        }
    ],
    "license": "MIT",
    "require": {
        "php": ">=5.4"
    },
    "autoload": {
        "psr-4": {
            "YanlongMa\\Push\\": "src/"
        }
    }
}

3. 提交代码到 Github

根据自己需要实现的功能编写代码,本项目最终项目结构如下:

.git/  
.gitignore  
composer.json  
README.md  
src/
    Client.php    
    JPush.php

代码编写完成且测试没问题后提交代码到 Github。

4. 发布包到 Packagist

登录 Packagist,检出 https://github.com/YanlongMa/push.git 仓库的代码,系统会根据仓库中 composer.json 文件自动设置包的相关信息。

5. 设置 Packagist 中的包自动更新

如果不设置自动同步,每次 Github 中的代码更新,需要在对应包中手动更新,所以建议设置自动更新。步骤如下:

  1. 进入 yanlongma/push 仓库,选择 "Settings -> Integrations & services";
  2. 点击 "Add service",选择 “Packagist”;
  3. 填写你的 Packagist 账号对应的信息(登录后点击查看https://packagist.org/profile/
  4. 配置完成后,点击右上角的“Test service”,如果出现 “Okay, the test payload is on its way.”,则说明配置成功。

6. 使用共享包

发布包到 Packagist 后,根据包名就可以搜索和使用该包了,在自己的项目中申明该包依赖:

$ composer require yanlongma/push

该包的具体使用可以查看 https://github.com/yanlongma/push

  • 发布包到 Packagist 后,可能过几分钟才能在客户端 search 到;
  • 没有打 tag 的要指定 dev,完整命令 composer require "yanlongma/push @dev"

本文首发于马燕龙个人博客,欢迎分享,转载请标明出处。
马燕龙个人博客:http://www.mayanlong.com
马燕龙个人微博:http://weibo.com/imayanlong
马燕龙Github主页:https://github.com/yanlongma

PHP 基础篇 - PHP 中 DES 加解密详解

一、简介

DES 是对称性加密里面常见一种,全称为 Data Encryption Standard,即数据加密标准,是一种使用密钥加密的块算法。密钥长度是64位(bit),超过位数密钥被忽略。所谓对称性加密即加密和解密密钥相同,对称性加密一般会按照固定长度,把待加密字符串分成块,不足一整块或者刚好最后有特殊填充字符。

跨语言做 DES 加密解密经常会出现问题,往往是填充方式不对、编码不一致或者加密解密模式没有对应上造成。常见的填充模式有: pkcs5、pkcs7、iso10126、ansix923、zero。加密模式有:DES-ECB、DES-CBC、DES-CTR、DES-OFB、DES-CFB。

作为一个软件开发者,可以通过工具测试 DES 加密解密,这里推荐一个在线工具:http://tool.chacuo.net/cryptdes

二、实现

PHP 提供了 Mcrypt 系列函数来实现 DES 的加解密,但该扩展中的函数陆续被废弃,自 PHP 7.2.0 起,会移到 PECL。

所以本代码用了更通用的 OPENSSL 方式实现 DES 的加解密,具体的实现和使用代码如下:

<?php

/**
 * openssl 实现的 DES 加密类,支持各种 PHP 版本
 */
class DES
{
    /**
     * @var string $method 加解密方法,可通过 openssl_get_cipher_methods() 获得
     */
    protected $method;

    /**
     * @var string $key 加解密的密钥
     */
    protected $key;

    /**
     * @var string $output 输出格式 无、base64、hex
     */
    protected $output;

    /**
     * @var string $iv 加解密的向量
     */
    protected $iv;

    /**
     * @var string $options
     */
    protected $options;

    // output 的类型
    const OUTPUT_NULL = '';
    const OUTPUT_BASE64 = 'base64';
    const OUTPUT_HEX = 'hex';


    /**
     * DES constructor.
     * @param string $key
     * @param string $method
     *      ECB DES-ECB、DES-EDE3 (为 ECB 模式时,$iv 为空即可)
     *      CBC DES-CBC、DES-EDE3-CBC、DESX-CBC
     *      CFB DES-CFB8、DES-EDE3-CFB8
     *      CTR
     *      OFB
     *
     * @param string $output
     *      base64、hex
     *
     * @param string $iv
     * @param int $options
     */
    public function __construct($key, $method = 'DES-ECB', $output = '', $iv = '', $options = OPENSSL_RAW_DATA | OPENSSL_NO_PADDING)
    {
        $this->key = $key;
        $this->method = $method;
        $this->output = $output;
        $this->iv = $iv;
        $this->options = $options;
    }

    /**
     * 加密
     *
     * @param $str
     * @return string
     */
    public function encrypt($str)
    {
        $str = $this->pkcsPadding($str, 8);
        $sign = openssl_encrypt($str, $this->method, $this->key, $this->options, $this->iv);

        if ($this->output == self::OUTPUT_BASE64) {
            $sign = base64_encode($sign);
        } else if ($this->output == self::OUTPUT_HEX) {
            $sign = bin2hex($sign);
        }

        return $sign;
    }

    /**
     * 解密
     *
     * @param $encrypted
     * @return string
     */
    public function decrypt($encrypted)
    {
        if ($this->output == self::OUTPUT_BASE64) {
            $encrypted = base64_decode($encrypted);
        } else if ($this->output == self::OUTPUT_HEX) {
            $encrypted = hex2bin($encrypted);
        }

        $sign = @openssl_decrypt($encrypted, $this->method, $this->key, $this->options, $this->iv);
        $sign = $this->unPkcsPadding($sign);
        $sign = rtrim($sign);
        return $sign;
    }

    /**
     * 填充
     *
     * @param $str
     * @param $blocksize
     * @return string
     */
    private function pkcsPadding($str, $blocksize)
    {
        $pad = $blocksize - (strlen($str) % $blocksize);
        return $str . str_repeat(chr($pad), $pad);
    }

    /**
     * 去填充
     * 
     * @param $str
     * @return string
     */
    private function unPkcsPadding($str)
    {
        $pad = ord($str{strlen($str) - 1});
        if ($pad > strlen($str)) {
            return false;
        }
        return substr($str, 0, -1 * $pad);
    }

}


$key = 'key123456';
$iv = 'iv123456';

// DES CBC 加解密
$des = new DES($key, 'DES-CBC', DES::OUTPUT_BASE64, $iv);
echo $base64Sign = $des->encrypt('Hello DES CBC');
echo "\n";
echo $des->decrypt($base64Sign);
echo "\n";

// DES ECB 加解密
$des = new DES($key, 'DES-ECB', DES::OUTPUT_HEX);
echo $base64Sign = $des->encrypt('Hello DES ECB');
echo "\n";
echo $des->decrypt($base64Sign);

三、相关链接


本文首发于马燕龙个人博客,欢迎分享,转载请标明出处。
马燕龙个人博客:http://www.mayanlong.com
马燕龙个人微博:http://weibo.com/imayanlong
马燕龙Github主页:https://github.com/yanlongma

macOS 上安装 PECL

一、简介

PECL(The PHP Extension Community Library)是 PHP 扩展的存储库,为 PHP 所有的扩展提供提供托管和下载服务。

通过 PEAR(PHP Extension and Application Repository)的 Package Manager 的安装管理方式,可以对 PECL 扩展进行下载和安装。

二、安装

官方提供了 PEAR 在各个平台的安装方式,直接看官方文档的请进【传送门】,macOS 平台官方安装翻译如下。

1. 下载 PEAR

使用 curl 命令下载即可:

$ curl -O https://pear.php.net/go-pear.phar

2. 安装 PEAR

使用 sudo 授权进行安装:

$ sudo php -d detect_unicode=0 go-pear.phar

安装过程需要进行简单的配置,如下:

Below is a suggested file layout for your new PEAR installation.  To
change individual locations, type the number in front of the
directory.  Type 'all' to change all of them or simply press Enter to
accept these locations.

 1. Installation base ($prefix)                   : /usr
 2. Temporary directory for processing            : /tmp/pear/install
 3. Temporary directory for downloads             : /tmp/pear/install
 4. Binaries directory                            : /usr/bin
 5. PHP code directory ($php_dir)                 : /usr/share/pear
 6. Documentation directory                       : /usr/docs
 7. Data directory                                : /usr/data
 8. User-modifiable configuration files directory : /usr/cfg
 9. Public Web Files directory                    : /usr/www
10. System manual pages directory                 : /usr/man
11. Tests directory                               : /usr/tests
12. Name of configuration file                    : /private/etc/pear.conf

1-12, 'all' or Enter to continue: 1

输入 1,将安装根目录修改为 /usr/local/pear;
输入 4,将命令安装到 /usr/local/bin 目录;
其它选项默认即可,一路回车。

3. 检测是否安装成功

出现如下结果,则安装成功:

$ pear version
PEAR Version: 1.10.5
PHP Version: 7.1.7
Zend Engine Version: 3.1.0

三、相关连接

PECL 官方地址:http://pecl.php.net/
PEAR 官方地址:http://pear.php.net/


本文首发于马燕龙个人博客,欢迎分享,转载请标明出处。
马燕龙个人博客:http://www.mayanlong.com
马燕龙个人微博:http://weibo.com/imayanlong
马燕龙Github主页:https://github.com/yanlongma

Yii2 教程 - yii2-redis 扩展详解

该教程已被合并到《Yii2 权威指南中文版》中!Yiichina 教程地址为《yii2-redis 扩展详解》!

一、简介

yii2-redis 扩展为 Yii2 框架提供了 redis 键值存储支持。包括缓存(Cache)、会话存储处理(Session),并实现了 ActiveRecord 模式,允许您将活动记录存储在 redis 中。

相关链接

二、安装扩展

在 Yii2 项目根目录,执行以下命令安装:

$ composer require yiisoft/yii2-redis

也可以先在 composer.json 文件中声明如下依赖:

"yiisoft/yii2-redis": "~2.0.0"

再执行下面命令安装:

$ composer update

三、基本使用

继续阅读请确保已安装并开启了 redis 服务,安装请参考《Redis 安装》

1. 配置

在组件中添加如下配置:

'components' => [
    'redis' => [
        'class' => 'yii\redis\Connection',
        'hostname' => 'localhost',
        'port' => 6379,
        'database' => 0,
    ],
]  

2. 示例

下面代码演示了 redis 最基本的 string 类型的使用:

// 获取 redis 组件
$redis = Yii::$app->redis;

// 判断 key 为 username 的是否有值,有则打印,没有则赋值
$key = 'username';
if ($val = $redis->get($key);) {
    var_dump($val);
} else {
    $redis->set($key, 'marko');
    $redis->expire($key, 5);
}

这个类中(yii\redis\Connection)提供了操作 redis 所有的数据类型和服务(String、Hash、List、Set、SortedSet、HyperLogLog、GEO、Pub/Sub、Transaction、Script、Connection、Server)所需要的方法,并且和 redis 中的方法同名,如果不清楚可以直接到该类中查看。

四、缓存组件

该扩展中的 yii\redis\Cache 实现了 Yii2 中的缓存相关接口,所以我们也可以用 redis 来存储缓存,且用法和原来一样。

1. 配置

修改组件中 cache 的 class 为 yii\redis\Cache 即可,配置如下:

'components' => [
    'cache' => [
        // 'class' => 'yii\caching\FileCache',
        'class' => 'yii\redis\Cache',
    ],
],

如果没有配置过 redis 组件,需要在 cache 组件下配置 redis 服务相关参数,完整配置如下:

'components' => [
    'cache' => [
        // 'class' => 'yii\caching\FileCache',
        'class' => 'yii\redis\Cache',
        'redis' => [
            'hostname' => 'localhost',
            'port' => 6379,
            'database' => 0,
        ],
    ],
],

2. 示例

下面代码演示了缓存的基本使用:

// 获取 cache 组件
$cache = Yii::$app->cache;

// 判断 key 为 username 的缓存是否存在,有则打印,没有则赋值
$key = 'username';
if ($cache->exists($key)) {
    var_dump($cache->get($key));
} else {
    $cache->set($key, 'marko', 60);
}

使用文件缓存(FileCache)时,缓存是存储在 runtime/cache 目录下;使用 redis 缓存后,缓存将存储在 redis 数据库中,性能将大大提高。

五、会话组件

该扩展中的 yii\redis\Session 实现了 Yii2 中的会话相关接口,所以我们也可以用 redis 来存储会话信息,且用法和原来一样。

1. 配置

修改组件 session 的配置,指定 class 为 yii\redis\Session 即可,配置如下:

'components' => [
    'session' => [
        'name' => 'advanced-frontend',
        'class' => 'yii\redis\Session'
    ],
],

如果没有配置过 redis 组件,需要在 session 组件下配置 redis 服务相关参数,完整配置如下:

'components' => [
    'session' => [
        'name' => 'advanced-frontend',
        'class' => 'yii\redis\Session',
        'redis' => [
            'hostname' => 'localhost',
            'port' => 6379,
            'database' => 0,
        ],
    ],
],

2. 使用

在开发过程中,切记一定不要使用 PHP 原生的 $_SESSION 去操作,而要使用 Yii 提供的 session 组件,获取方式如下:

$session = Yii::$app->session;

六、ActiveRecord

该扩展中的 yii\redis\ActiveRecord 实现了 Yii2 中的 ActiveRecord 相关接口,所以我们可以使用 AR 的方式操作 redis 数据库。关于如何使用 Yii 的 ActiveRecord,请阅读权威指南中有关 ActiveRecord 的基础文档。

定义 redis ActiveRecord 类,我们的模型需要继承 yii\redis\ActiveRecord,并至少实现 attributes() 方法来定义模型的属性。

主键可以通过 yii\redis\ActiveRecord::primaryKey() 定义,如果未指定,则默认为 id。 primaryKey 必须在 attributes() 方法定义的属性中,如果没有指定主键,请确保 id 在属性中。

下面定义一个 Customer 模型来演示:

class Customer extends \yii\redis\ActiveRecord
{
    /**
     * 主键 默认为 id
     *
     * @return array|string[]
     */
    public static function primaryKey()
    {
        return ['id'];
    }

    /**
     * 模型对应记录的属性列表
     *
     * @return array
     */
    public function attributes()
    {
        return ['id', 'name', 'age', 'phone', 'status', 'created_at', 'updated_at'];
    }

    /**
     * 定义和其它模型的关系
     *
     * @return \yii\db\ActiveQueryInterface
     */
    public function getOrders()
    {
         return $this->hasMany(Order::className(), ['customer_id' => 'id']);
    }

}

使用示例:

// 使用 AR 方式新增一条记录
$customer = new Customer();
$customer->name = 'marko';
$customer->age = 18;
$customer->phone = 13888888888;
$customer->status = 1;
$customer->save();
echo $customer->id;

// 使用 AR 查询
$customer = Customer::findOne($customer->id);
$customer = Customer::find()->where(['status' => 1])->all();

redis ActiveRecord 的一般用法与权威指南中数据库的 ActiveRecord 用法非常相似。它们支持相同的接口和方法,除了以下限制:

  • 由于 redis 不支持 sql,查询方法仅限于使用以下方法:where(),limit(),offset(),orderBy() 和 indexBy()。 【 orderBy() 尚未实现:#1305)】
  • 由于 redis 没有表的概念,因此不能通过表定义关联关系,只能通过其它记录来定义关系。

七、直接使用命令

直接使用 redis 连接,就可以使用 redis 提供的很多有用的命令。配置好 redis 后,用以下方式获取 redis 组件:

$redis = Yii::$app->redis;

然后就可以执行命令了,最通用的方法是使用 executeCommand 方法:

$result = $redis->executeCommand('hmset', ['test_collection', 'key1', 'val1', 'key2', 'val2']);

支持的每个命令都有一些快捷方式,可以按照如下方式使用:

$result = $redis->hmset('test_collection', 'key1', 'val1', 'key2', 'val2');

有关可用命令及其参数的列表,请参阅 redis 命令:


本文首发于马燕龙个人博客,欢迎分享,转载请标明出处。
马燕龙个人博客:http://www.mayanlong.com
马燕龙个人微博:http://weibo.com/imayanlong
马燕龙Github主页:https://github.com/yanlongma

PHP 基础篇 - PHP 正则官方文档汇总

一、PCRE 正则语法

下面是 PHP 的 PCRE 正则语法(模式语法)相关文档,详情请查阅相关链接:

二、PCRE 模式修饰符

下面列出了当前可用的 PCRE 修饰符,详情请看官方文档

  • i (PCRE_CASELESS)
  • m (PCRE_MULTILINE)
  • s (PCRE_DOTALL)
  • x (PCRE_EXTENDED)
  • e (PREG_REPLACE_EVAL)
  • A (PCRE_ANCHORED)
  • D (PCRE_DOLLAR_ENDONLY)
  • S
  • U (PCRE_UNGREEDY)
  • X (PCRE_EXTRA)
  • J (PCRE_INFO_JCHANGED)
  • u (PCRE_UTF8)

三、PCRE 函数

下面是 PHP 的 PCRE 函数相关文档,详情请查阅相关链接:


本文首发于马燕龙个人博客,欢迎分享,转载请标明出处。
马燕龙个人博客:http://www.mayanlong.com
马燕龙个人微博:http://weibo.com/imayanlong
马燕龙Github主页:https://github.com/yanlongma