Write the Code. Change the World.

分类目录
12月 20

虽然 homestead 用的很习惯,还是想尝试新东西 docker 。也不是新东西了,出来有些年了。既然用 laravel ,那么就用 laradock

熟悉 virtualBox + vagrant + homestead 的朋友,对于 laradock 上手也会很快。当初,装 homestead 需要安装 virtualBox(也可以是vm等) 和 vagrant,然后是使用 homestead 来实现环境的配置安装。对于 docker 可以这样理解,docker 就是 virtualBox + vagrant,或是 vagrant。 我们只需要安装一个 docker 就可以了。然后下载 laradock 即可以开始安装了。

步骤

安装使用,一步到位,初观全局

laradock: https://github.com/laradock/laradock

这里以 win 为例子:

# 先选定一个磁盘位置,用来存放 laradock 并且相邻文件夹做为 www 目录(当然也可以其他位置)
cd /e/
mkdir service
cd service

git clone https://github.com/laradock/laradock.git

cd laradock

# 准备配置文件
cp env-example .env

# 修改配置文件
vim .env
# 修改 APP_CODE_PATH_HOST = '../www'

# 创建并启动
docker-compose up -d nginx php-fpm mysql redis workspace

# 重启
docker-compose restart

# 进入服务器
winpty docker-compose exec workspace bash

# 退出 
exec 

上边的过程,可能有些长久。先创建 laravel 项目。

# 默认安装最新版本。当前版本 6.8
composer create-project laravel/laravel --prefer-dist docker.cn

再配置 nginx,创建默认 laravel 项目

cd service/laradock/nginx/sites

# 复制一份配置出来。命名一定要以 .conf 作为后缀
cp app.conf.example docker.cn.conf 

# 修改 docker.cn.conf
vim docker.cn.conf

# 通常会修改 server 下的 server_name 和 root。将 server_name 修改为你想要指定的域名。比如 docker.cn。 root修改为映射的文件目录。比如 /var/www/study/docker.cn/public 。保存退出。

# 每个对象都是一个容器
# 比如 修改了 nginx 只需要单独启动 nginx 即可
docker-compose up -d nginx

然后再执行 winpty docker-compose exec workspace bash 。如果发现还是访问不了。可以 docker-compose restart 再执行 winpty docker-compose exec workspace bash 

配置 host

# 修改 host 文件,再末尾加入 
vim hosts
GG
127.0.0.1 docker.cn

###
https://xueyuanjun.com/post/9608

https://www.cnblogs.com/itfenqing/p/10972603.html

https://blog.csdn.net/lfm940624/article/details/86678698

12月 16

做聊天项目的时候,通常会用到关键词过滤。对于一些敏感信息,可能还会进行内容加密。这里从两个不同的功能点,总结下过程。也是在别人的基础上,跑了一遍而已。照着做,可以一步到位。

环境
1. php
2. js
3. laravel

敏感词过滤

https://github.com/FireLustre/php-dfa-sensitive

composer require lustre/php-dfa-sensitive

# 项目中
use DfaFilter\SensitiveHelper;

# 添加词库,使用文件
$path = storage_path('sensitive/words.txt');
$handle = SensitiveHelper::init()->setTreeByFile($wordFilePath);

# 添加词库,单个添加
$data = [
    '哎呦我的天',
    '太阳',
    '太阳块融化我的脸'
];

$handle = SensitiveHelper::init()->setTree($data);

# 替换,检测
$islegal = $handle->islegal($content);

$content = '啥啥啥,哎呦我的天呀,太阳快融化我的脸';

$content = $handle->replace($content, '*', true);

上边这些,github 上都有,照着做就可以了。

https://www.zkii.net/tech/php/1115.html

数据加密解密

这里数据加密使用 aes。数据加密解密的对象是字符串。无论哪 js 还是 php,都可以互相转换。不过这里可能存在一种文体,js 加密的 js 可以解密,但 php 不能解密。反之亦然。出现这种情况,往往是加密解密模式没有配对上。

** js 加密解密 **

参考: https://blog.csdn.net/yingbaoyu/article/details/95761177

如果不是 node 环境,可以下载 https://pan.baidu.com/s/1Mvg8vhlD56wvS4b6yjUoaA 提取码:57gd

例子:


const aseKey = 'YjKp7COQ9QZN2EgMJdiI8tzBsJarvQAr'; const aseIv = 'zmtuC5UyMfK3r1QYXKa1lYmNNy8F5jiP'; //将秘钥转换成Utf8字节数组 const key = CryptoJS.enc.Utf8.parse(aseKey); const iv = CryptoJS.enc.Utf8.parse(aseIv); let data = { name: 'vini', gender: 1 } data = JSON.stringify(data); let encoded = CryptoJS.AES.encrypt(data, key, { iv: iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 }).toString(); console.log(encoded); let uncoded = CryptoJS.AES.decrypt(encoded, key, { iv: iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 }).toString(CryptoJS.enc.Utf8); console.log(uncoded); # 这个时候, data 应该等于 uncoded

key 的长度决定了 CBC 模式的不同。

# php 加密解密

<?php

namespace App\Helper;

class Aes
{
    static public function encrypt($data)
    {
        $method = 'AES-256-CBC';
        $key = 'YjKp7COQ9QZN2EgMJdiI8tzBsJarvQAr';
        $iv = 'zmtuC5UyMfK3r1QY';
        return openssl_encrypt($data, $method, $key, 0, $iv);
    }

    static public function decrypt($data)
    {
        $method = 'AES-256-CBC';
        $key = 'YjKp7COQ9QZN2EgMJdiI8tzBsJarvQAr';
        $iv = 'zmtuC5UyMfK3r1QY';
        return openssl_decrypt($data, $method, $key, 0, $iv);
    }
}

这里为了方便,把 method key iv 都写死了。项目里边不会这样做。比如,可以定义一个类:

<?php
namespace App\Utils;

class Aes
{
    protected $aesSecret = 'YjKp7COQ9QZN2EgMJdiI8tzBsJarvQAr', $aesIv = '00000000000000000000000000000000';

    /**
     * 进制转换
     * @param string $hex
     * @return string
     */
    protected function aesHexIv($hex = '')
    {
        $string = '';
        $hex = $hex != '' ? $hex : $this->aesIv;
        for ($i = 0; $i < strlen($hex) - 1; $i += 2) {
            $string .= chr(hexdec($hex[$i] . $hex[$i + 1]));
        }
        return $string;
    }

    /**
     * AES加密
     * @param string $content
     * @param string $key
     * @param string $hex
     * @return string
     */
    public function aesEncrypt($content = '', $key = '', $hex = '')
    {
        $hash = hash('sha256', $key ?: $this->aesSecret, true);
        $enCrypt = openssl_encrypt($content, 'AES-256-CBC', $hash, PKCS7_TEXT, $this->aesHexIv($hex));
        return base64_encode($enCrypt);
    }


    /**
     * AES解密
     * @param string $content
     * @param string $key
     * @param string $hex
     * @return string
     */
    public function aesDecrypt($content = '', $key = '', $hex = '')
    {
        $content = base64_decode(str_replace(' ', '+', $content));
        $hash = hash('sha256', $key ?: $this->aesSecret, true);
        return openssl_decrypt($content, 'AES-256-CBC', $hash, PKCS7_TEXT, $this->aesHexIv($hex));
    }
}

https://www.php.net/manual/zh/openssl.pkcs7.flags.php

更多信息

https://baike.baidu.com/item/%E9%AB%98%E7%BA%A7%E5%8A%A0%E5%AF%86%E6%A0%87%E5%87%86/468774?fromtitle=aes&fromid=5903&fr=aladdin

https://www.keylala.cn/aes

https://blog.csdn.net/GlatChen/article/details/79978875

https://suijimimashengcheng.51240.com/

进一步了解 aes 加密解密

在多端配合的情况下,不是 keyiv 都对,就可以解密出加密的数据的。 秘钥位数,加密模式,填充方式也得一一对应上。

aes 参数

  1. key length(密钥位数,密码长度)
  2. key (密钥,密码)
  3. IV (向量)
  4. mode (加密模式)
  5. padding (填充方式)
11月 11

laravel 使用 npm

使用 yarn 来管理

npm config set registry=https://registry.npm.taobao.org

yarn config set registry https://registry.npm.taobao.org

yarn install

npm run watch-poll

假如使用 bootstrap

composer require laravel/ui --dev

php artisan ui bootstrap
9月 25

商户操作:

  1. 安装操作证书 。 使用 mac chrome 安装完成控件后,发现 控件启动不了。这个时候可以这么操作。
  • 浏览器输入 chrome://flags 回车
  • 搜索 Native Client 将状态改成 enable
  • 重启 chrome 即可。
  1. api 安全相关。
# 生成 32 位秘钥
# http://code.php.net.cn 在线编辑

// 创建随机字符串
function createNoncestr($length = 16)
{
    $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
    $str = "";
    for($i = 0; $i < $length; $i ++)
    {
        $str .= substr ( $chars, mt_rand ( 0, strlen ( $chars ) - 1 ), 1 );
    }
    return $str;
}

$str = createNoncestr(32);

echo $str;
  1. api 证书

https://kf.qq.com/faq/180824JvUZ3i180824YvMNJj.html

  • 点击更换证书,下载证书只做工具。
  • 设置好路径,下一步生成即可。粘贴进网站上商户输入框。
  • 再网站下一步,生成证书粘贴到工具中。下一步即可。然后打开之前设置的路径。就可以看到 zip文件了。

api 证书不影响支付,对提现等功能才有用。

9月 12

这里的关键点:
1. redis 异步队列。
2. 多项目。

面对上边这种情况,怎么处理呢。如果不处理又会出现什么现象呢。

因为我们使用 supervisord 进行常驻队列侦听。如果不指定对应的 queue,多项目就会出现串的情况。这个是就可以用 queue 来处理该问题了。

处理

  1. 修改 supervisord 的配置文件。在 command 中指定一个 queue 。如
command=/alidata/service/php/bin/php /alidata/www/www.mlxiu.com/artisan queue:work redis --queue=test --sleep=3 --tries=3
  1. 在项目中,指定 queue。因为使用的是 laravel 框架。 队列继承 ShouldQueue。 可以在构造函数中指定 queue 即可。
public function __construct($id)
{
     $queueName = config('queue.name');
     if ($queueName) {
         $this->onQueue($queueName);
     }
}

queue.name 是自己额外在 queue.config 中添加的变量。

参考

https://www.cnblogs.com/zgxblog/p/10996112.html

8月 28

虽然 Larave Auth 包含了验证邮箱以及密码的功能,但终归是固定样式的。想要更美观,更漂亮的验证功能,就得自定义。

自定义最直接的方法,就是重写发送逻辑。先贴出部分代码,然后读下边的文章,你肯定会做到的。


# App\Models\User; //发送验证邮箱 // verification.verify 是你自定义的邮箱模板 public function sendEmailVerificationNotification() { \Illuminate\Auth\Notifications\VerifyEmail::toMailUsing(function ($notifiable) { $url = \Illuminate\Support\Facades\URL::temporarySignedRoute( 'verification.verify', now()->addMinutes(60), ['id' => $notifiable->getKey()]); $email = $this->email; $nickname = $this->nickname; $body = sprintf('<a href="%s" target="_blank">点击激活邮箱</a>', $url); $mail = (new \Illuminate\Notifications\Messages\MailMessage)->view('emails.activateMail', ['nickname' => $nickname, 'url' => $url], function (Message $message) use ($nickname, $email, $body) { $message->subject('请激活你的邮箱'); $message->getSwiftMessage()->setBody($body); $message->to($email, $nickname); } ); return $mail; }); $this->notify(new \Illuminate\Auth\Notifications\VerifyEmail); }

当然,你可以使用 trait 干净处理,还可以使用事件另外解耦,还可以添加队列进行异步处理。

参考文章

https://www.jianshu.com/p/38e1426edf58

https://laravelacademy.org/post/19497.html