Write the Code. Change the World.

11月 05

操作步骤

  1. 将 .pem 文件保存到本地磁盘中。
  2. 添加命令。
ssh-add -K /path/to/private_key
  1. 运行 ForkLift,增加一个配置。选择使用 FTPS,在密码处选择 .pem 文件即可。

https://binarynights.com/support

终端中使用命令登录服务器

sudo ssh -i key.pem root@ip

权限不够,带上 sudo

也可以这样使用

ssh-add -K /path/to/private_key
ssh root@ip

阅读全文 >>

10月 26

父元素设置了 flex 布局

display: flex;
align-items: center;

如何让某个子元素靠右呢

方法一

flex: 1;
text-align: right;

方法二

margin-left: auto;

阅读全文 >>

10月 11

  1. 去除镜像
composer config -g --unset repos.packagist
  1. 添加全局镜像(两个选一个)
composer config -g repo.packagist composer https://packagist.laravel-china.org

composer config -g repo.packagist composer https://packagist.phpcomposer.com

# 阿里云镜像, laravel-china 已经作废
composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/
  1. 当前项目添加镜像
composer config repo.packagist composer https://packagist.laravel-china.org
  1. 查看镜像
composer config -l -g

娃哈哈

https://learnku.com/laravel/t/30710

https://packagist.laravel-china.org/

https://pkg.phpcomposer.com/#how-to-use-packagist-mirror

阅读全文 >>

10月 10

axios 拦截器,最佳实践,体验相关:

https://www.cnblogs.com/dhsz/p/6410031.html

https://blog.csdn.net/panyox/article/details/73800241

https://blog.csdn.net/sjn0503/article/details/74729300

http://www.php.cn/js-tutorial-399867.html

如果是 vue 中。可以在路由里先做一步判断,然后请求时 axios 拦截器里边也做处理。这样就可以完美解决问题了。

request 中添加 token,response中处理错误。

Promise 相关

https://www.cnblogs.com/yunfeifei/p/4453690.html

https://www.cnblogs.com/sweeeper/p/8442613.html

jwt bearer token 相关

https://www.cnblogs.com/zfdcp-028/p/6374632.html

https://www.jianshu.com/p/8f7009456abc

https://www.jianshu.com/p/f9faeac8bd5e

https://www.cnblogs.com/Leo_wl/p/7792046.html

阅读全文 >>

10月 09

Laravel有非常强大的ORM,但是对于刚接触ORM的我来说,在理解上还是有点障碍的,开启打印SQL的功能能帮助更好的理解。

打印SQL默认是关闭的,需要在 /vendor/illuminate/database/Connection.php中打开。

protected $loggingQueries = true;

之后可在代码中使用了:


$res = User::where('id', 100)->first(); $log = DB::getQueryLog(); var_dump($log);

如果不想开启但需要临时查看,可以这样操作:

DB::connection()->enableQueryLog();

$res = User::where('id', 100)->first();

$log = DB::getQueryLog();
var_dump($log);

这样就这样。但是得到的语句与参数是分开的,不方便去观看以及使用。所以额外加了一个函数来处理这种情况。通常,我们会用到辅助函数类,可以放到这里。

function transSql($queries)
{
    if(!$queries)
        return FALSE;

    $sqls = [];
    foreach($queries as $query)
    {
        $sql = [
            'sql' => vsprintf(str_replace('?', '%s', $query['query']), $query['bindings']),
            'time' => $query['time']
        ];
        $sqls[] = $sql;
    }
    return $sqls;
}

使用:

DB::connection()->enableQueryLog();

$res = User::where('id', 100)->first();

$log = DB::getQueryLog();

$log = transSql($log);
var_dump($log);

这里的sql语句可能不止一条,通过查看sql的条数,可以看到查询的详细情况。

相关

https://laravel-china.org/articles/5166/quick-print-laravel-database-query-sql-statement

阅读全文 >>

9月 27

场景

有一个海报,里边有美丽的画面,还有一些需要填充的地府。比如,往海报中添加一个二维码,或加一段文字。

但是,这些二维码和文字是动态的。方便推广宣传,合成图片就很有必要了。

就拿关注微信公众号这件是吧。微信公众号,可以生成带场景值的二维码。推广的时候,合成成一张海报就方便使用了。

图片处理用 imagick 库

imagick 功能比较强大,方便各种图片的操作。

php 使用 image intervention

http://image.intervention.io/api/destroy

使用 composer 安装

composer require intervention/image

实现细节

<?php

namespace App\Http\Controllers\Api;

use Illuminate\Http\Request;
use Image;

class ImageBuilderController extends Controller
{
    public function poster(Request $request)
    {
        $bg = 'static/image/group/groupbg.png';
        $description = '给你一个美丽的意外';
        $fonts = 'static/image/group/pingfang.ttf';

        $scene = $request->scene ? $request->scene : urlencode('xxxx');
        $avatar = $request->avatar ? $request->avatar : 'static/image/group/avatar.png';
        $nickname = $request->nickname ? $request->nickname : '神奇动物在哪里';
        $page = $request->page;

        $qrcode = $this->qrcode($scene, $page);
        $qrcodeImg = Image::make($qrcode)->resize(300, 300);
        $avatarImg = Image::make($avatar)->resize(100, 100);

        $image = Image::make($bg)->insert($qrcodeImg, 'bottom-left', 225, 196)
                                ->insert($avatarImg, 'bottom-left', 171, 511, function ($constraint) {
                                     $constraint->aspectRatio();
                                });

        $image->text($nickname, 288, 645, function($font) use ($fonts) {
            $font->file($fonts);
            $font->size(34);
            $font->color('#222');
        });

        $image->text($description, 288, 685, function($font) use ($fonts){
            $font->file($fonts);
            $font->size(24);
            $font->color('#888');
        });

        $folder = '/upload/image/wxapp/' . date('Ym', time()) . '/';
        $upload_path = public_path() . $folder;
        // 创建文件夹
        if (!file_exists($upload_path))
        {
            mkdir($upload_path, 0777, true);
        }
        $name = time() . '_' . str_random(10) . '.jpg';
        $image->save($upload_path . $name, 80);
        $image->destroy();

        return $this->response->array(['url' => url($folder . $name)])->setStatusCode(201);
    }

    private function qrcode($scene, $page)
    {
        $access_token = getAccessToken(env('WECHAT_MINI_PROGRAM_APPID'), env('WECHAT_MINI_PROGRAM_SECRET'));

        $url = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=$access_token";

        $params = ['scene' => $scene];
        if($page)
            $params['page'] = $page;

        $data = curl($url, json_encode($params), TRUE, TRUE);

        $check = json_decode($data);

        if($check && $check->errcode)
            return $this->response->errorUnauthorized($check->errmsg);

        return $data;
    }
}

阅读全文 >>

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']);
    }

很傻很直接但有效。

阅读全文 >>