半吊子全栈开发者的日常

使用 Certbot 自动签发 Let's Encrypt 证书

今晚一回来就看到 Google Search Console 给我发了封邮件说我站点上的 SSL 证书过期了。我上去一看还真是,这张我从 Andy 手里买来的通配符证书已经在昨天失效了。

唉,时间也是过得忒快啊,转眼间一年就过去了,我也成为了苦逼的高三党,真是惨得不行 ( ・_ゝ・)

不过正好,我从 之前就一直在关注 Let’s Encrypt 这个项目了,这次正好试试看它好不好用。

> READ MORE...

Sublime Text 3 主题推荐 —— Boxy

BOXY

用了好久的 Predawn,打算换个 Theme 和 Color Scheme 试试。在网上逛了一段时间后,我找到了一个很不错的 ST3 主题,这里分享一下:

Boxy Theme

The most hackable theme for Sublime Text 3

这个主题在 Package Control 上的页面在这里,这是一个非常强大的主题,你可以去看看它的介绍视频。

Boxy 提供了很多自定义选项,因此你甚至可以把 Sublime 打扮成 Atom、VS Code,甚至是同为 ST 主题的 Predawn/Material 的样式,简直碉堡了好吗:

> READ MORE...

又是一种用于 JavaScript 的前端国际化方案

现在 Blessing Skin Server 的 HTML 模板是使用 Laravel 自带的本地化来实现多语言支持的,并且使用了 devitek/yaml-translation 这个包把 Laravel 语言文件从默认的 PHP 数组形式改为 YAML 格式的文件。

不得不说数组形式的语言文件简直反人类好吗,一大堆 => 看的眼晕。。YAML 大法好!(ゝ∀・)

回到正题。虽然 HTML 模板里的国际化是解决了,但是整个应用中需要国际化的地方可不止 HTML 模板,同时还有 JavaScript。但是静态的脚本文件中总不能内嵌 PHP 吧,所以我们得搞个单独的解决方案。

虽然说网上现成的 JS 国际化的库很多,但我总觉得有些看不上眼(可能是我没找到好的),就准备自己实现一下。

> READ MORE...

自定义 Laravel Validator 所返回的响应

不得不说 Laravel 的 Validation 是极好的,非常易于使用,麻麻再也不用担心我要写一大堆验证啦 ~( ω)

但是这个 Validator 有一个神秘的地方 ( -д-),正如官方文档所说,它会自动判断当前请求是否为 Ajax 发送的,如果是,则在验证失败的时候返回一个 JsonResponse 响应而不是 RedirectResponse 响应。

但是,这个 JSON 响应的状态码,是 422。

WTF!坑爹呢这是!要知道 422 这个状态码是通不过 jQuery.ajax.success 的啊!

在网上找了一圈,愣是没找着什么好一点的解决方法(全是叫你在 $.ajax.failed 里处理错误的)。

> READ MORE...

使用 Laravel 的 监听者模式实现缓存机制的松散耦合

唔,我也不知道我接下来要讲的东西是不是配得上这个题目,总之就是分享一下我在搞 Blessing Skin Server 的缓存与插件机制时的一些经验(大佬们就请忽略吧)

既然要实现松散耦合的缓存机制,那就是要做到有没有缓存都没事。有缓存的话就走缓存,然后那边的模块内部实现一个包括过期时间呀啥啥的缓存机制,没有收到缓存模块的响应的时候就继续走原来的应用逻辑,一样可以正常响应。

因为我们是要实现应用逻辑与缓存逻辑的解耦,所以正常应用逻辑内是不能有对那些缓存的依赖的。那么我们要通过什么来和缓存模块通信呢?巧的是,Laravel 正好提供了基于 Event 和 Listener 的观察者模式,我们就可以用这种设计模式来解耦缓存模块。

> READ MORE...

使用 Laravel 的服务容器来优化读写数据库中的 options

这篇文章应该算是心得体会一类的吧,因为并没有什么卵用(笑

就像前两篇文章说的一样,在我把项目框架改为 Laravel 后,自然要最大限度地利用 Laravel 的特性来提升我们应用的性能(虽然使用 Laravel 本身就是在降低性能了),并且让我们的代码看起来更优雅 装逼

其中我们可以最方便地利用的一个特性就是 Laravel 的服务容器了。在这里我不多赘述 Service Container 是个啥,想了解的可以自行搜索。不想了解的就只要大致知道它是个可以 绑定/取出 实例的东西就好了(当然服务容器可不止这么点功能)。

相信很多 Web 应用都会在数据库建立一个 options 表来储存一些用户的配置信息,而为了方便,我们通常会封装一个 Option 类来方便地进行数据的 getset 操作。而通常的做法是把这些操作做成类内静态方法来调用。

但是这样的弊端就是每一次的操作都要去查询数据库,这对于性能还是有挺大影响的,尤其是在一次响应中要使用很多 options 的情况下。

> READ MORE...

同时使用 Laravel Elixir 和同名自定义 Gulp Task 时的坑

今天上午我把 Blessing Skin Server 的框架改为了 Laravel,到处修修改改一会后终于可以跑起来了。因为我之前也是使用的 Blade 模板引擎和与 Illuminate语法类似的路由库,所以迁移过程还算是挺无痛的。

迁移稍微告一段落后,我就准备使用一下以前一直很想用的 Laravel 对常用 Gulp Task 的封装:Laravel Elixir

改写原来 gulpfile.js 中的原生 Gulp Tasks 到 Laravel Elixir 的模式并不算麻烦,常用的 task 都有集成,并且通过链式调用的方式依次执行各个 Task。

改写好后,直接运行 $ gulp 即可执行所有的 elixir tasks,并且执行完毕后还会有详细的表格报告和 Toast 通知,非常的方便。

但是,不知道是我的姿势不对还是怎么回事,我没有找到能够把一个目录下所有的 css/js 文件压缩后复制到另一个目录的 elixir task,无奈之下只好写成原生的 Gulp Task,并且使用 elixir 的 mix.task() 方法来调用:

> READ MORE...

为 Blade 模板引擎添加新文件扩展名

因为一些原因,我准备把 Blessing Skin 的框架换成 Laravel 了(之前是自己搭建的一个框架),但是在模板迁移的时候遇到了一点问题。

之前我是使用的 XiaoLer/blade 这个从 Laravel 中抽离出来的 Blade 模板引擎,并且自定义为使用 .tpl 文件后缀。你问为啥不用默认的 .blade.php 而是用这个 Smarty 的模板扩展名?能有啥,好看呗 :-D

不过之前我是直接调用 FileViewFinder 类的 addExtension 方法来添加扩展名的,但是在 Laravel 里就不能这样了。你总不能在 Illuminate\View 加几句话吧?

去 Google 搜索了下,没发现有可以很方便使用的方法(当然是搜的鹰文,说不定是我姿势不对),就只好自己找了。

首先先从 View Facade 入手,可以看到它是从服务容器中解析出了 view 这个绑定。继续往下找,打开 Illuminate\View\ViewServiceProvider,看看 View 的服务提供者到底是把啥给绑定到 view 上去了:

> READ MORE...

喜闻乐见被 DDoS + CC 攻击

今早起来准备修一个 Blessing Skin Server 的 BUG 的时候,打开演示站发现慢到没朋友,最起码要 60s+ 才会有响应。当时我也没多想,觉着大概是 DO 线路又抽风了,然后挂上代理访问演示站,但依然是无响应。这时候我开始觉得不对劲了,SSH 连上 VPS,top 一看,诶哟,90% 的 CPU 占用,清一色的 php-fpm 进程。

当时我就有点方了,去 DO 的控制台看了下图表,CPU 从上午十点左右开始就一直是爆满状态。再去看了一下 netstat,有几个 SYN_RECV 和一大票 ESTABLISHED,我就觉得有可能是被 cc 了。

随后去看了一下 Nginx 的访问日志,发现从早上开始就一直有人不断地 HEAD / 请求,排查了一下最后发现请求的是 skin.prinzeugen.net 这个域名,也就是 Blessing Skin Server 的演示站点。

> READ MORE...

使用 Git 生成增量更新包

上次有人叫我在 Blessing Skin 每次升级的时候带上一个增量更新包,只包含所有上一个版本后修改过的文件。

我听到这个需求,最开始想到的是使用 git diff --name-only,加上这个参数后可以只显示 commit 之间修改过的文件名,然后就可以用管道通给 zip 之类的程序来压缩。

去网上搜了搜,发现还有更简单的方法

$ git archive -o ../latest.zip NEW_COMMIT_ID $(git diff --name-only OLD_COMMIT_ID NEW_COMMIT_ID)

这是用了 git archieve 命令,本质上和我上面说的也差不离。

如果你打了 tag,就可以写成这样:

$ git archive -o ../latest.zip HEAD $(git diff --name-only v3.0.1 HEAD)

是不是很方便呢 |∀` )