Write the Code. Change the World.

分类目录
9月 30

使用 laravel 开发项目的时候, artisan 是个好东西。这个好东西是真的好。在做 command 的时候,您可以方便的输出想要的内容在终端上,比如警告,错误,选择等等。这是因为 command 它继承了Command 类,该类使用了 trait Illuminate\Console\Concerns\InteractsWithIO。而它最终实现了 Symfony\Component\Console\Output\OutputInterface 。 Symfony\Component\Console\Output\ConsoleOutput 是 cli output 的源头类。 只要我们做好 Symfony\Component\Console\Output\ConsoleOutput 的文章,不也可以输出吗。

ConsoleOutput is the default class for all CLI output. It uses STDOUT and STDERR.

来 123, 跟着步骤走起来

# 先生成一个 seeder
php artisan make:seeder TestSeeder

# 在该 seeder 的 run 函数中加入以下代码
    public function run()
    {
        $output = new \Symfony\Component\Console\Output\ConsoleOutput();
        $section = $output->section();
        $section->writeln('人生若只如初见,何事秋风悲画扇');
    }

# 那么开始测试一下
php artisan db:seed --class=TestSeeder

是不是就可以看见你想看见的东东了。当然你可以封装,搞出更多花样。也还有更多命令待使用。

8月 12

某些场景,需要用户的 openid 以及 unionid,如何获取和转换就很有必要。获取公众号所有用户的 openid,通过公众号 openid 获取用户的 unionid。

获取公众号 openid

https://developers.weixin.qq.com/doc/offiaccount/User_Management/Getting_a_User_List.html

# 正常结果 json_decode 下的结构如下
{
  "total":23000,
  "count":10000,
  "data":{"
     openid":[
        "OPENID1",
        "OPENID2",
        ...,
        "OPENID10000"
     ]
   },
   "next_openid":"OPENID10000"
}

通过 openid 获取用户的 unionid

https://developers.weixin.qq.com/doc/offiaccount/User_Management/Get_users_basic_information_UnionID.html#UinonId

8月 09

有些时候,对于并发,我们只想执行一次。多次并发请求就打破了你的想。这里我们用 redis 来弄就好。

操作一波

这里以 laravel 为例

use Illuminate\Support\Facades\Redis;

$time = 60;
$key = 'mimi' . $user->id;
// 如果不存在就 set 值,返回 0 或 1,set 成了返回 1,否则返回 0(表示已经锁住了,不要进去了)
$res = Redis::setnx($key,  $user->id);
if ($res) {
   # 设置 redis 过期(锁的时间秒)
   Redis::expire($key, $time);

   # 你的业务
   xxxxxx
}

laravel 并发处理php 并发处理

7月 11

设计 API 授权,或者调用第三方 API 时,经常会接触到:

Authorization : Bearer Tokenxxxxxx

有没有疑惑为何不直接写成这样就得了:

Authorization : Tokenxxxxxx

这是因为 W3C 的 HTTP 1.0 规范,Authorization 的格式是:

Authorization: <type> <authorization-parameters>

所以 Bearer 是授权的类型,常见的授权类型还有:
- Basic 用于 http-basic 认证;
- Bearer 常见于 OAuth 和 JWT 授权;
- Digest MD5 哈希的 http-basic 认证 (已弃用)
- AWS4-HMAC-SHA256 AWS 授权
- …

6月 21

本地连接 redis, 出现 dial tcp 192.168.56.56:6379: connect: connection refused ,修改 redis 配置,重启就好了

操作

sudo vim /etc/redis/redis.conf

# 将 bind 127.0.0.1 ::1 改成 bind 0.0.0.0,然后重启

sudo service redis restart

# 查看
ps -ef | grep redis

5月 14

https://github.com/barryvdh/laravel-debugbar

### 安装
composer require barryvdh/laravel-debugbar --dev

### 生成配置文件 config/debugbar.php
php artisan vendor:publish --provider="Barryvdh\Debugbar\ServiceProvider"

### 修改配置文件,设置 enabled 项
'enabled' => env('APP_DEBUG', false)

启用分析器后,网站底部会出现 debug 工具栏,可以看到执行的 mysql 语句等。可以发现和解决不合理的 ORM 问题。

4月 25

// 将 ip 转换成 city
function ip2City($ip)
{
    $url = "https://apis.map.qq.com/ws/location/v1/ip?ip={$ip}&key=XXXXXXXX";
    $res = curl($url, false, false, true);
    $data = [];

    try {
        if ($res) {
            $res = json_decode($res, true);
        }

        if ($res && $res['status'] == 0 && $res['result']) {
            $data['latitude'] =  $res['result']['location']['lat'];
            $data['longitude'] =  $res['result']['location']['lng'];
            $data['city'] =  $res['result']['ad_info']['city'] ? $res['result']['ad_info']['city'] : '未知';
            $data['citycode'] =  $res['result']['ad_info']['adcode'] && $res['result']['ad_info']['adcode'] > 0 ? $res['result']['ad_info']['adcode'] : 0;
        }
    } catch (Exception $e) {
    }
    return $data;
}

/**
 * @param string $url 请求网址
 * @param bool $params 请求参数
 * @param bool $post 请求方式,是否是post
 * @param bool $https 请求http协议,是否是https
 * @return bool|mixed
 */
function curl($url, $params = false, $post = false, $https = false)
{
    $httpInfo = array();
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
    curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.118 Safari/537.36');
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
    curl_setopt($ch, CURLOPT_TIMEOUT, 30);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

    if ($post === true) {
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
        curl_setopt($ch, CURLOPT_URL, $url);
    } else {
        if ($params === false) {
            curl_setopt($ch, CURLOPT_URL, $url);
        } else {
            if (is_array($params)) {
                $params = http_build_query($params);
            }
            curl_setopt($ch, CURLOPT_URL, $url . '?' . $params);
        }
    }

    if ($https === true) {
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 对认证证书来源的检查
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); // 从证书中检查SSL加密算法是否存在
    }
    $response = curl_exec($ch);
    if ($response === false) {
        Illuminate\Support\Facades\Log::error(sprintf('curl 错误。 url:%s, error:%s', $url, curl_error($ch)));
        return false;
    }
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    $httpInfo = array_merge($httpInfo, curl_getinfo($ch));
    curl_close($ch);
    return $response;
}