Write the Code. Change the World.

9月 27

场景

要求用户给公众平台发一个消息 (特殊定义好的关键词语)时,公众号同时给用户返回多条消息。

然而,如果用公众号自己的回复能力,却只能回复一条,是不能实现的。那么,想要一次发几条消息怎么实现的呢。其实用客服消息功能就行

https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140547

先说说客服消息

公众平台官方文档已经有说明。

http请求方式: POST
https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=ACCESS_TOKEN

利用客服接口,可以发送多条消息。一样可以发送文本,图片,语音,视频等消息。

接用户信息

接用户消息。

$postStr = isset($GLOBALS['HTTP_RAW_POST_DATA']) ? $GLOBALS['HTTP_RAW_POST_DATA'] : file_get_contents("php://input");
if (!empty($postStr)) {
    libxml_disable_entity_loader(true);
    $msg = (array)simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);
    if ($msg['Content'] === 'xxx') {
       // 如果关键字刚好是需要的 这个时候就可以用客服消息了。
       // 1. 获取accessToken
       // 2. 组织消息内容
       // 3. 发客服消息 1
       // 4. 发客服消息 2
       // 5. 发客服消息 3
       // ……
    }   
}



如果向上边这样操作,腾讯那边迟迟接不到回音,就会重复请求,这样就会重复发三次客服消息。下边就是解决方法。

在 获取 accessToken 之前,加入下边的代码。

    ignore_user_abort(true);
    ob_start();
    echo '';
    header('Connection: close');
    header('Content-Length: ' . ob_get_length());
    ob_end_flush();
    ob_flush();
    flush();

这样还不能解决问题的。

很傻很直接的办法

1, 消息进来,对消息数据进行观察。发现超时请求的数据格式一样。这样,我们可以知道该条消息的特征(FromUserName 和 CreateTime 组合成唯一识别key)。
2,对特殊关键字的消息做消息过滤。以 FromUserName 和 CreateTime 组合的值为key 作为 redis 的 key,先判断该 key 对应值是否存在,如果存在,表示是 超时过来的请求,请 echo ''; exit; 相应。如果不存在,建立一个 15 秒的 redis缓存即可。

    if($this->msg['Content'] == '领红包')
    {
    $key = $this->msg['FromUserName'] . $this->msg['CreateTime'];

    if(\Illuminate\Support\Facades\Redis::exists($key))
    {
    echo '';
    exit;
    }

    \Illuminate\Support\Facades\Redis::setex($key, 15, $this->msg['Content']);
    }

很傻很直接但有效。

阅读全文 >>

9月 18

文档

官方文档:https://laravel.com/docs/5.7/scheduling

中文文档:https://laravel-china.org/docs/laravel/5.6/scheduling/1396

在 Larave 中定义任务,在 crontab 中配置任务

先配置吧

vim /etc/crontab 

# 在末尾添加
* * * * * root cd /alidata/www/mlxiu/ && php artisan schedule:run >> /dev/null 2>&I1

/sbin/service crond start

如果不行,需要再crontab中配置环境变量,或者命令直接写绝对路径。
crontab 参考:https://www.cnblogs.com/intval/p/5763929.html

在 laravel 中定义任务

看文档吧。

阅读全文 >>

9月 17

安装 imagick

PHP建图通常都用GD库,因为是内置的不需要在服务器上额外安装插件,所以用起来比较省心,但是如果你的程序主要的功能就是处理图像,那麼就不建议用GD了,因为GD不但低效能而且能力也比较弱,佔用的系统资源也颇多,另外GD的creatfrom也有bug,而imagick却是一个很好的替代品,为此最近把我的一个项目由GD改成了imagick

官网: https://www.imagemagick.org/script/install-source.php

# 没权限的加上sodu
wget https://imagemagick.org/download/ImageMagick.tar.gz

tar xzvf ImageMagick.tar.gz

cd cd ImageMagick-7.0.8-11

./configure -prefix=/usr/local/imagemagick -enable-lzw -with-modules 

#如果报错:如果configure提示“configure: error: libltdl is required for modules build”,则yum install libtool-ltdl libtool-ltdl-devel

make 

make install

make check

安装 imagick php 扩展

插件地址:http://pecl.php.net/package/imagick

wget http://pecl.php.net/get/imagick-3.4.3.tgz
tar -xzvf imagick-3.4.3.tgz
cd imagick-3.4.3
phpize
./configure --with-php-config=/usr/bin/php-config --with-imagick=/usr/local/imagemagick
# 根据php-config 目录有所不同。这里是 Homestead环境

# 如果提示没有 pkg-config,请先安装
#  apt-get install pkg-config (unbuntu)
# yum install pkg-config (centos)

make test
make
make install

cp /usr/src/imagick-3.4.3/modules/imagick.so /usr/lib/php/20160303/imagick.so
# 这里是 homestead 的配置。

sudo vim /etc/php/7.1/fpm/conf.d/20-imagick.ini
# 添加 extension=imagick.so 保存

参考

https://blog.csdn.net/m0_38004619/article/details/77897406

阅读全文 >>

9月 11

oss 为企业或个人提供了文件存储访问功能。将文件上传到 oss 就是最直接的问题。我们可以通过阿里云后台上传,也可以通过应用程序工具上传。但利用阿里云提供的 api 上传是最好的方式。因为这样方便数据的接入。阿里云官方文档提供了几个 demo 。

最佳实践

https://help.aliyun.com/document_detail/31925.html?spm=a2c4g.11186623.2.2.878c62121zD4re#concept_frd_4gy_5db

这个最大的缺点,是暴露了 accessid 和 accesskey 。

https://help.aliyun.com/document_detail/31926.html?spm=a2c4g.11186623.6.637.22202f0862W1am

这个服务端直接签名后再上传,避免了暴露。

阅读全文 >>

8月 31

Vue 用脚手架本地测试,项目都是指向根目录,当发布到外网环境,非根目录时,有人会遇到根本进不去 vue 路由的情况。

既然用了 vue ,遇到问题总的要解决。

网上一些有用的方法

https://segmentfault.com/a/1190000014561644

https://blog.csdn.net/lensgcx/article/details/78439514

其实主要还是得处理 nginx 的 location

处理 location 的规则即可。

location 可以添加很多个不同规则。

比如:

location /{

}

location /web{
    try_files $uri $uri/ /web/index.html;
} 
# vue 这里的二级目录是 web 

阅读全文 >>

8月 21

form 表单提交的数据需要验证时,通常会建一个 Request 来单独进行处理。这样干净,舒服,控制器只需要做业务逻辑就好。还有,如果字段验证不通过,还会重定向请求页面,并且会带上请求不通过的 error。 这种体验是不是很好。

仅仅 Request 里边就有很多细节和功能噢。我懒了。

https://laravel-china.org/docs/laravel/5.6/requests/1367

阅读全文 >>

7月 31

在 Laravel 中,事件有 普通事件,还有 模型事件。类似的有通知和广播。这里直接上用法。

来步骤走起

普通事件通常有事件,事件监听器,添加事件,分发这几步组成。

php artisan make:event WahahaEvent 
# 生成事件

php artisan make:listener WahahaListener
# 生成监听器

# 在 App\Providers\EventServiceProvider 的 listener 中添加监听
# 事件对监听器 ,是一对多的关系。想做出多种监听,可以放在一起。比如事件是早晨上班打卡,监听有打卡时间,打卡位置。通过一个打卡事件,分发(后边有)到两个监听这里,两个监听就可以做相应的处理。这里只是打个比方,事件和监听器的一对多关系。

    protected $listen = [
        WahahaEvent::class => [
            WahahaListener::class,
        ],
    ];

# 分发(事件,监听器,事件添加都好了,只剩下分发这一步,整过过程就走完了)

event(new WahahaEvent()); 
# 仅此一句 分发就完成了。event是分发函数,全局的。

上边是最基本,最简单的事件模型。通常,我们会在分发的时候,带一些数据过去。比如对应的 模型

# App\Models\Wahaha
# 假如模型就是 Wahaha
$model = Wahaha::where('id', 1)->first();
event(new WahahaEvent($model)); 

分发带来了数据,事件的构造函数会接受到。事件是这样的。

# App\Events\WahahaEvent
public $wahaha;

public function __construct(Wahaha $wahaha)
{
    $this->wahaha = $wahaha;
}

事件只是个媒介,过程,真正处理逻辑在监听器里。所以监听器会用到刚才过来的数据。

# App\Listeners\WahahaListener
// 当事件被触发时,对应该事件的监听器的 handle() 方法就会被调用
public function handle(WahahaEvent $event)
{
    // 获取到刚刚注册的用户
    $wahaha = $event->wahaha;
    // 下边就是你的业务逻辑的地方
}

在想,何必整得这么麻烦,直接在分发那里写逻辑不就好了吗。这样做,可以起到一个解耦的作用,还有代码的干净,以及复用等。

再来看模型事件

模型事件相对于普通事件,要简单很多。它只需要建立监听,并添加到服务即可。其实,模型事件也有普通事件的整个流程。可以了解下这个类 Illuminate\Database\Eloquent\Model(模型的父类)

建立监听

php artisan make:observer WahahaObserver

<?php

namespace App\Observers;

use App\Models\Wahaha;

class WahahaObserver
{
    public function creating(Wahaha $wahaha)
    {
        // 处理逻辑
    }
}

添加服务到 App\Providers\AppServiceProvider

public function boot()
{
    \App\Models\Wahaha::observe(\App\Observers\WahahaObserver::class);
}

这样,流程就走完了。是不是很短暂。当模型 Wahaha 调用 create 方法后,就会自动触发监听。但是这里监听的只能是下边的几种操作。

// creating, created, updating, updated, saving,
// saved,  deleting, deleted, restoring, restored

参考

中文文档

模型事件

阅读全文 >>

7月 20

bootstrap4 相关

Bootstrap 4重大更新,亮点解读

知乎 Bootstrap4

E文文档

他人学习笔记

https://blog.csdn.net/bbdxf/article/details/79251934

漂亮的主题

https://www.creative-tim.com/product/material-kit

bootstrap4 自定义颜色

默认的按钮,input等颜色比较难看,某些设置也不人性化,这些都是通过编译bootstrap的源码来自己来定义的。主要分以下几个步骤。

  1. 前期准备。

安装 npm 并使用 淘宝镜像。http://npm.taobao.org/
git 工具

2,下载原文件包。
https://github.com/twbs/bootstrap
在 scss 目录下,就可以看到它的源码。
找到_variables.scss,并修改里边的颜色值,再编译就可以了。比如:

# 有颜色值的是我修改的
$primary:       #9c27b0 !default;
$secondary:     $gray-600 !default;
$success:       #4caf50 !default;
$info:          #00bcd4 !default;
$warning:       #ff9800 !default;
$danger:        #f44336 !default;
$light:         $gray-100 !default;
$dark:          $gray-800 !default;

sudo cnpm run dist 
# 编译打包就可以了

# 修改点击按钮的时候,按钮周围的边框,好难看,强迫症要干掉。这样会把input的边框也干掉了,不好。
$input-btn-focus-width:       0 !default;
$input-btn-focus-color:       rgba($component-active-bg, .25) !default;
$input-btn-focus-box-shadow:  none !default;

阅读全文 >>