Livewire.js 404 的问题的处理思路和解决方式

black flat screen computer monitor

在使用 Laravel Livewire 的时候一个常见问题是生成的 Livewire.js 文件会报错。

一般来说,解决思路有两种

  1. 看看你生成的 URL 是否是正确的。
  2. 看看你的 Nginx 配置是否是正确的。

生成的 URL 是否正常

在 Livewire 的配置当中,存在一个 asset_url 选项,这个选项会用于在页面中嵌入 Livewire.js 文件的功能,因此。如果你在使用过程中,修改了这个值,导致生成的地址是错误的,就有可能报错。

Nginx 配置是否正确

这个问题往往会导致报错的页面是 Nginx 的 404 页面。

在你的 Nginx 配置当中,如果你针对 JS 文件或 CSS 文件有单独处理,你需要将对应的处理注释掉,确保所有请求转发给 Laravel 进行处理。

 # location ~ .*\.(js|css)?$ {
 #   expires 7d;
 #   access_log off;
 # }
Code language: PHP (php)

Laravel 9 单元测试报错 An email must have a “From” or a “Sender” header

black flat screen computer monitor

在 Laravel 9 当中,引入了新的 Mailer 组件,随之而来的是一些过去没有的 Bug。

如果你在开发过程中出现了 An email must have a "From" or a "Sender" header 的报错,需要在 PHPUnit 当中配置 MAIL_FROM_ADDRESS 属性,用于通过测试。

<env name="MAIL_FROM_ADDRESS" value="from@example.com" />
Code language: HTML, XML (xml)

来源:https://laracasts.com/discuss/channels/laravel/for-reference-an-email-must-have-a-from-or-a-sender-header

Gutenberg 编辑器带来的模式变更

silver mercedes benz emblem on blue surface

自 WordPress 5.0 开始, Gutenberg 编辑器(后文称为古腾堡编辑器)开始存在于 WordPress 当中,为普通用户所用。而得益于古腾堡编辑器带来的卓越的使用体验(用户不需要再记录晦涩难懂的短代码、无须忍受 TinyMCE 的界面),用户使用 WordPress 的方式也开始变得多种多样。

如果你还没有用过古腾堡编辑器,那你可以访问 WordPress 官方提供的在线预览工具来试用:https://wordpress.org/gutenberg/

体验的变革

古腾堡的出现,让作者可以更加接近于我一直描述的 WordPress 所能够提供的最大的价值 —— 让写作变得更加简单,易实现。不仅如此,古腾堡带来的新的编辑体验,让除了工程师、Geek 以外的人也可以很轻松的实现一个更好看、更易读、更加丰富的界面。

而从 WordPress 开发团队的态度来看,也是更加推荐作者们更多的使用古腾堡编辑器:从Twenty Nineteen 开始,古腾堡的支持就成为了默认,并不断的通过官方主题的用法,让作者们看到 WordPress 原来还可以是这样。今年的 Twenty Twenty Two 更是从写作者变为了艺术家 —— 你可以十分简单的建造一个线上的画廊。

开发模式的变更

过去,WordPress 开发整体来说,可以分为两条线:一条是主题开发,你需要与 PHP、HTML、CSS、Javascript 共同战斗;另一条线则是插件开发,你需要与PHP 为伍。

搞插件开发的,你对于前端开发不甚了解也无所谓。WordPress 提供了大量的 helper function 。比如,我在「开发一个短代码插件」中,不使用一行前端代码就实现了 TinyMCE 的功能新增。

而在新的古腾堡编辑器生态下,开发者如果希望对于古腾堡进行拓展,一方面依然可以使用之前的方式,接入各种短代码来实现各种不同的用户体验,另一方面,则可以借助与前端技术栈来实现一个更加丰富的用户体验。

你可以使用 JQuery 和 WordPress 为你绑定的全局对象来修改古腾堡编辑器实现你的目标,更是可以借助前端的开发体系,诸如 Webpack、React 来开发一个强交互,体验佳的用户体验。

WordPress 的开发不再是 PHP 工程师自己的事情,它将更多的人卷入 WordPress 的开发过程中。而对于 WordPress 开发工程师来说,则有了更高的要求,来完成插件的开发、主题的开发。

总结

自古腾堡的推出,这样的趋势就开始渐显。但直到我真正开始开发一款古腾堡插件,我才真正意识到 —— WordPress 在内容创作领域的价值,无可替代。纵然他有众多的历史包袱,但对于每一个创作者来说,他都是最好的选择。

WordPress 如何获得最顶级的自定义分类

b29692084bbb

WordPress 支持设定多级分类,如果你需要在页面中展示最顶级的分类,则需要获取到最顶级的分类,具体实现的方式如下:

1. 获取当前文件类型的自定义分类

使用如下代码获取到自定义分类

$tax = wp_get_post_terms($post->ID,array('part'))
Code language: PHP (php)

获得的结果如下

Array
(
    [0] => WP_Term Object
        (
            [term_id] => 7
            [name] => 目录1
            [slug] => category1
            [term_group] => 0
            [term_taxonomy_id] => 7
            [taxonomy] => part
            [description] => 
            [parent] => 6
            [count] => 2
            [filter] => raw
        )

)
Code language: PHP (php)

这里的 term_id 则代表你设定的自定义分类的 ID

2.获取分类树

因为分类是多级的,我们需要找到祖先节点,因此需要用到函数 get_ancestors ,执行如下代码

$tree = get_ancestors($tax[0]->term_id)
Code language: PHP (php)

会获得如下结果

Array
(
    [0] => 6
    [1] => 8
)
Code language: PHP (php)

这个返回结果则是从你当前分类向上查找,查找到最顶级的分类的结果。需要注意的是,这个数组的最后一个元素才是你最终最顶级的分类。

3. 提取最后一个元素的 ID

当你知道了最后一个才是最顶级的分类,只需要使用 end() 函数来获取最后一个。

end($tree)
Code language: PHP (php)

这样,就能拿到最终目录的 ID,接下来要做的就是在你的界面上展示这些数据。

为 WordPress 加入 Server Timing 判断不同行为性能差异

b29692084bbb

自打上次为我的博客加入了 Redis 缓存后,博客站点访问速度明显变快,几乎可以达到秒开的效果。剩下的需要在网络层面进行进一步的优化。

不过,我还在思考如何才能更好的优化我的 WordPress 性能。很显然,我需要一个指标来帮助我做决策。这让我想到了一个东西 —— HTTP 标准中的 Server-Timing Header。

Server-Timing 标头传达在一个给定请求-响应周期中的一个或多个参数和描述。它用于在用户浏览器的开发工具或 PerformanceServerTiming (en-US) 接口中显示任何后端服务器定时参数(例如,数据库读/写、CPU 时间、文件系统访问等)。

来自 https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Server-Timing

Server Timing 可以帮助我们记录服务端到底在哪些步骤中消耗了哪些时间,可以方便我进行性能的查询。

使用 WP Server Timing 添加 Server-Timing 头

我在 WordPress 的 Plugin Directory 目录进行了搜索,并没有找到支持这个功能的插件,不过我在 Github 上找到了这个插件 —— https://github.com/ocReaper/wp-server-timing

有了这个插件,我就可以无需自己手动添加相应的能力。

使用插件也非常简单,在页面上下载压缩包,并在 WordPress 后台安装并启用这个插件。

d2b5ca33bd970f64a6301fa75ae2eb22 14
安装后的效果

安装完成后,你接下来要做的就是重新在浏览器中打开你的网站,并按下 F12 打开开发者工具,选择文档 Tab(英文是 Document),刷新当前页面,就可以看到列表中出现了一个你博客地址对应的文档,点击文档,并在弹出的窗口中切换到「时间」Tab,就可以在下方看到服务器计时了。

d2b5ca33bd970f64a6301fa75ae2eb22 15
示意图

按照上图的结果,可以看到,我的 WordPress 耗时最长的是 Template Processing ,我需要针对这个属性进行定向优化。

辅助理解资料

以下是 WordPress 的加载顺序图,你可以对比着参考

dtckd
WordPres 的加载顺序图,来源:https://www.rarst.net/wordpress/wordpress-core-load/

Jest 如何将复杂的判断条件中的具体问题暴露出来?

code 1076536 640

在写测试的时候,如果你需要对大量的数据进行 compare 处理的时候,你大概率不会把所有需要对比的对象都列出来,而是选择直接循环处理。

在测试中如果有循环处理的时候,很有可能会出现的一个问题是你可能无法在测试无法通过时快速定位道具体是循环中的哪一个元素出现的问题。这个时候的定位就会比较麻烦。

一个比较好的办法是,可以在 Jest 中加入 try/catch 中来处理错误,这样可以在出现错误的时候,打印一些辅助信息来快速定位,比如

it('test-error-catch-example',() => {

   let needTestData = [1,2,3,4]

   needTestData.foreach( item => {
       let result = doSomething(item)
       // 这里开始是新增的
       try{
          expect(result).toBe(true)
       }catch(e){
          console.log("error key",item)
          throw e;
       }
       // 新增的错误处理结束
   })

})
Code language: JavaScript (javascript)

通过添加一个自定义的 try catch ,可以在出现问题的时候,一方面将 Error 按照常规的方式抛出,等待 Jest 处理,另一方面,可以在 catch 时输出自定义的信息,方便我们进行排查和修复。

截图、修图、管理图片 – Capto 与图片管理工作流

453a454bb03ba4e4f74b2034b7327759

TL;DR

Capto 牛逼,买它!购买地址直达链接

除了直接购买 Capto,你还可以以更低的费用购买 Setapp 会员,享用更多软件

正文

如果你日常会有编写操作教程,或有大量编写图文混合文章、PowerPoint的时候,你一定会有以下几个困扰:

  1. 如何截图:虽然 Windows 和 macOS 都自带了截图的功能,但因为基本是系统自带的功能,所以大部分只有「全屏幕截图」这一个功能,或者需要按下十分复杂的组合键来完成图片的截取。
  2. 如何添加标注:为了确保图片的读者能够找到正确的位置,我们往往会在图片中加入一些标注,帮助读者能够在第一时间找到重点,或帮助用户涂抹掉不需要关注的部分,仅保留核心区域的内容。
  3. 如何管理截图:图片被截取完成后,我们应该如何管理这些图片?我们应该如何管理已经标注好的图片?我们如何阻止这些截图?这些都是在管理截图的时候遇见的问题。

而如果你也遇见了这样的问题,这篇文章就是为你准备的,接下来,且听我为你介绍我的截图管理历史。

截图工具演变史

刀耕火种:系统自带截图工具时期

第一个时期,我采用的是最为笨拙的截图方式方法,在 Windows 和 macOS 系统都提供了默认的截图工具。

在 Windows 当中,只需要按下 Win + Printscreen 键,就可以将你当前的屏幕截取,并保存在系统的「图片\屏幕截图」目录中。

知乎《Windows10 自带截屏快捷键》

在 macOS 当中,只需要同时按住以下三个按键:Shift、Command 和3,就会拍摄截图。

Apple《在 Mac 上拍摄截屏》

无论是 Windows 还是 macOS ,都提供了基本的截图工具,但在实际使用的时候,你会发现,你产出的图片(如图1)大多数的时候是这样的:图片中元素极多无关主题的元素无法被隐藏、桌面背景是你自己自定义的背景等一系列小瑕疵。

fe939468620860309f23e5d6ef07ef93
图1: macOS 自带的截图产出的截图

此外,不同设备上的不同按键让我们在切换设备的时候产生迷惑(特别是你从 Windows 切换到 macOS 或反过来切换时),此外,图片的批注也十分的麻烦,必须借助一些第三方的图片编辑软件(比如画图、Adobe Photoshop)来进行图片的编辑和标注。

有没有一个工具,可以帮助我用非常简单的方式完成截图,最好能在截图的时候可以完成图片的批注?

短兵相接:聊天工具内置截图软件 / 第三方截图工具时期

随着时代的发展,截图的功能开始被更多的软件关注到,我们开始可以在聊天工具当中截图。

常见的比如使用 QQ 进行截图、使用微信进行截图、使用飞书进行截图(如图2)等。这些聊天工具所提供的更加易用但又更加强大的截图功能逐渐替代了系统自带的截图功能,此外,其提供的诸如批注、圈选、提示等功能,也让截图的批注变得更加简单。

d2b5ca33bd970f64a6301fa75ae2eb22 2
图2:飞书提供的截图功能

此外,因为这些功能是集成在聊天软件当中,所以往往会在截图完成后,自动将图片放置在你的剪贴板中,你可以直接在聊天软件当中粘贴图片,并发送给其他的人,完成协作和信息的传递。

甚至,因为这些工具做得足够好用,腾讯甚至还将截图这个功能独立出来,开发出了一个单独的截图软件 —— 截图(Jietu)

d2b5ca33bd970f64a6301fa75ae2eb22 3
图3: 截图(Jietu) 的 App Store 页面

不过,因为这个场景过于小众,商业化的空间也比较小,最终,截图还是停止了维护,如今我们在 App Store 虽然还能够下载到本地,但在实际的使用过程中,会发现相应的功能已经失效无法再使用了(测试系统为 macOS Big Sur)。

此外,在这个时代当中,也涌现出了不少非常有特色的截图 & 批注软件,比如支持截图、长截图、滚动截图、贴图、取色功能的 iShot (图4);

d2b5ca33bd970f64a6301fa75ae2eb22 4
图4: iShot 的 App Store 宣传图

比如提供了非常有优雅的分步骤说明功能和图片云托管功能的 Teampaper Snap(图5) ,也是一个不错的选择。

d2b5ca33bd970f64a6301fa75ae2eb22 6
图5: Teampaper Snap 的分步骤解说图

得益于基础设施的进步,这些专门做工具软件的开发者们也能够依赖自己开发的工具收获相应的价值回报(Teampaper Snap 年付 30 元人民币,支持从截图中使用 OCR 提取文字;),也使得开发者们有动力不断的去迭代自己的工具,让我们获得越发好用的截图和批注工具。

自然,腾讯公司推出的截图(Jietu)因为 ROI 计算起来并不划算而被暂停。同一时期还有一些其他截图软件值得大家尝试,诸如 Xnip,如果你感兴趣,也可以自己下载下来尝试一下。

这些截图和批注工具完美的解决了我们想要截图和对图片进行修改的诉求,我们可以借助他们快速的完成图片的截图和基础的修改问题。

但随着工作的复杂度提升,需要处理的图片量变大以后,一定会遇到另外一个问题:图片管理问题。你在截图对这些图片做的修改被直接写死在图片当中,导出的时候直接导出无法撤回修改的 JPG、PNG 图片,一旦使用图片的人发现图片中有一些错误,就不得不重新进行完整的截图,重新批注,时间成本极高。

这个时候,你或许会思考,有没有一款软件,既可以满足我图片截取和批注的诉求,同时,还能解决我图片管理的诉求,让我小微改动不要重头再来,节省时间?

数字化赋能:截图管理工具时期

当你有大量的截图要管理以后,你就会发现之前的截图工具还是不够用。这些工具往往集中在「工具」的视野中, 将工具这一属性做到了极致,你可以在这个工具当中完成任何你需要的截图和批注的能力,但一旦你完成了当前的工作流,你就不得不为你的所有工作打上了一个句号,后续倘若你要反悔,是断然没有可能的。

而在当下我看来,最为推荐的便是 Capto 这款软件。

和其他的截图工具相比,Capto 是一个更加具备工程化的截图和截图管理工具

首先,在概念层面,Capto 当中,图片可以分为「资源库」 — 「文件夹」 — 「图片」三个层级。每一张图片都归属于某一个资源库(图6),在资源库内你可以将图片分配在不同的文件夹中。

d2b5ca33bd970f64a6301fa75ae2eb22 11
图6:Capto的资源库文件

其次,在具体的使用层面,Capto 也提供了丰富的功能,以满足你的需求。

针对截图,Capto 提供了基本的屏幕截图、窗口截图、区域截图功能,还在截图的基础之上提供了动态的录屏功能,帮助你在 Capto 内完成你几乎所有涉及到录屏的需求,你可以直接用 Capto 完成你的截图工作,并在完成截图后,使用 Capto 提供的图片批注功能,进行图片的编辑和处理。

在 Capto 的图片批注界面(图7),你可以清晰的将界面分为截图录屏区、图片批注区、图片预览区、图片信息区和图片管理区。

d2b5ca33bd970f64a6301fa75ae2eb22 7
图7: Capto 的图片编辑界面

得益于独立资源库的设计,Capto 的图片批注功能实现了类似 Photoshop 的图层能力,你的每一个批注都是独立的一个个体,你可以随时添加 & 移除它。也正是这样的能力,赋予了用户可以多次修改一个图片的可能,你可以放心大胆的批注图片,哪怕有些许错位,后续微调即可,再也不用重新截图了。

而在 Capto 的图片管理界面(图8),你可以更加深刻的感受到 Capto 的图片管理功能,左侧提供的筛选功能,则可以让你更加快速的完成大量的图片管理功能,你可以在左侧的库快速的筛选出你需要的图片

d2b5ca33bd970f64a6301fa75ae2eb22 8
图8: Capto 的图片管理界面

也可以根据某些特定的筛选规则(图9),筛选出某些特定属性的图片,方便你在后续使用的时候快速筛选。

d2b5ca33bd970f64a6301fa75ae2eb22 9
图9:智能收藏集的筛选功能

此外, 对于不同的项目你甚至可以采用不同的资源库的方式,来切换不同的上下文,从而实现不同项目之间的隔离,更好地管理你的所有图片。

d2b5ca33bd970f64a6301fa75ae2eb22 10
图9:Capto 的库设置页面

借助于 Capto ,你可以使用其自带的截图工具,先根据需求截取出合适的图片,并在 Capto 中进行图片的批注和处理;在完成批注和处理后,你可以根据需求,将图片导出为合适的格式(图10),即可完成图片的整个处理过程。

d2b5ca33bd970f64a6301fa75ae2eb22 12
图10:Capto 的图片保存选项

基于 Capto 的截图管理工作流

当你看完了上述的内容,对于 Capto 有了基础的了解后,接下来我为你介绍我自己的截图管理工作流:

  1. 打开 Capto ,创建一个资源库:因为我只需要为自己截图,因此,无需创建不同的资源库。这里有一个注意的点:你可以将你的资源库创建在同步盘上,这样就可以在不同设备之间同步你的资源库,从而实现在不同的设备上编辑同一套资源库。比如我自己用的就是 iCloud 来同步资源库。
  2. 根据需求,创建不同的收藏集:根据实际的需求,创建不同的收藏集,用于后续的图片分类,如果你有多个项目同时进行,也可以一次性创建多个目录。这样后续就可以批量选中图片进行分类了。
  3. 创建智能筛选集:我在实际工作过程中,也不会一次性创建多个目录,因为我可能并不能很好的分类,所以早期我更多是先大量把要截取的图片进行截取,然后创建一个智能筛选集(规则见图11),将所有未分类的图片筛选出来,并进行筛选和处理。
  4. 编辑图片,并导出:完成了所有的图片的截取后,将所有的图片进行逐个地分类和修改,并导出,用在对应的文档当中。
d2b5ca33bd970f64a6301fa75ae2eb22 13
图11:智能筛选集的规则

总结

Capto 作为一个专注做截图的功能,相比于现有市场上的其他工具,提供了截图之上的管理功能,让截图这件事从一个更高的层面重新思考,让我们重新思考图片的管理能力,并用其提供的能力,简化了我们管理图片的难度释放了我们的生产力,让我们可以把更少的精力放在截图、做图上,让我们有更多的时间和精力,去关注内容本身。

除了直接购买 Capto,你还可以以更低的费用购买 Setapp 会员,享用更多软件

WordPress 的静态化缓存和动态化缓存应该如何选择?

b29692084bbb

在我发出了 为 WordPress 加入 Redis 缓存提升访问性能 的文章后,有不少朋友给了建议,主要有以下几个:

  1. 可以在前面套一层 CDN ,使用 CDN 来完成缓存。
  2. 可以配置 Nginx 缓存。
  3. 可以给文章生成静态的。

在我看来,这些都是很好的建议,对于很多新人的博客主而言,都是不错的选择。不过就我自己的需求而言,这个并不是好的选择。

从网站性能的提升而言,他们所提供的建议确实是不错的,通过对网站进行静态化处理,从而实现访问的提速,用户直接访问静态的缓存是不错的选择。

不过,对于我来说,倒也不仅仅是给读者一个更加舒服的阅读体验,对于我自己而言,更加舒适的写作体验也是极为重要的。

引入了 Redis 作为缓存后,所有的 MySQL 查询会进行一定的缓存,从而让网站的整体使用体验变得更好,对于我来说,是一个更好的选择。

为 WordPress 加入 Redis 缓存优化访问性能

0dbb4980acb58d4396e9a2055bf2176e

在之前的文章我是如何优化博客的本站在用的一些WordPress插件中我提到,我是使用了 WP-Optimize这个插件来进行博客优化的。

d2b5ca33bd970f64a6301fa75ae2eb22 11
WP Optimize

WP-Optimize 为用户提供了开箱即用的缓存方式,可以将你的 WordPress 文章加入文件缓存,从而减少在 MySQL 中查询的次数。

不过,文件缓存的问题是性能受限于你所使用的磁盘,而我使用的是阿里云的标准云磁盘,性能一般,所以访问速度并不能算快。

过去在我还愿意折腾 WordPress 的时候,我是会在 WordPress 上加入一些别的缓存的,比如 Redis、Memcached。不过,随着时间的流逝,我折腾的意愿变得越来越弱,就远离了这些。

直到最近刚好有空,于是开始研究起了 Redis 缓存。

其实在古早时代(比如我刚开始折腾个人博客的时候,2012年),WordPress 的 Redis 功能并不是特别好用,需要自己手动下载 object-cache.php 放在对应目录中,然后修改配置文件手动来开启,甚至还需要替换掉 index.php 文件来让请求通过缓存进行。

这次的折腾,让我感受到,时代在进步,配置缓存也变得简单了许多。

Requirements

在这篇博客中我并不打算介绍 Redis Server 的安装和调试过程,你可以在搜索引擎中找到各种各样的教程引导你如何完成安装的过程,因此,请自行完成 Redis Server 的安装,后续的各项操作会默认你已经完成了 Redis Server 的安装调试。

需要注意的是,如果你不打算修改配置文件,则需要在安装 Redis 之后,设置为空密码。而空密码是不安全的,建议你通过 iptables、安全组策略等方式,屏蔽掉 6379 端口的外部请求,只允许本地请求。

安装 Redis 缓存

我这次安装 Redis 缓存选择了 Redis Object Cache 这个插件。

d2b5ca33bd970f64a6301fa75ae2eb22 12
Redis Object Cache

和你在别的网站上看到的教程相比,这个插件提供了一个可视化的查看和管理的方式,对于懒得手动操作和编辑代码的人来说,更加友好。

安装插件后,启用插件,你可以在设置中的「Redis」设置页面找到如下的界面:

d2b5ca33bd970f64a6301fa75ae2eb22 13
设置页面

点击 Enable Object Cache,就会开启 Redis 的 Object Cache 。

如果你已经在之前配置好了 Redis Server,则会直接看到如下左图的界面。但如果你的 Redis Server 还没有配置或配置了密码,就会显示如下右图的界面,就需要你检查你的 Redis Server 是否配置成功。

d2b5ca33bd970f64a6301fa75ae2eb22 15
配置成功的情况
d2b5ca33bd970f64a6301fa75ae2eb22 14
配置失败的情况

当你看到如上左图的界面后,就说明你已经开启了 Redis 的 Object Cache 了,后续涉及到文章内容、菜单等各项基本配置的查询时,会优先使用 Redis 的缓存,而不是查询 MySQL,从而降低了 MySQL 的查询压力,提升了查询的诉求。

至此,你的 Redis 就配置好了,可以打开你的网站首页,享受飞一样的速度。

d2b5ca33bd970f64a6301fa75ae2eb22 17
开启前的 TTFB 为 2.29 秒
d2b5ca33bd970f64a6301fa75ae2eb22 16
开启后的 TTFB 为 673.49 毫秒

FAQ

1. 如何使用非本地 Redis Server 或如何使用带密码鉴权的 Redis Server?

如果你需要使用非本地的 Redis Server(比如云 Redis),那么你需要在你的 wp-config.php 中加入如下代码来进行配置。

define( 'WP_REDIS_HOST', '127.0.0.1' );
define( 'WP_REDIS_PORT', 6379 );
// define( 'WP_REDIS_PASSWORD', 'secret' );
define( 'WP_REDIS_TIMEOUT', 1 );
Code language: JavaScript (javascript)

2. 如果我一个服务器上有多个 Redis ,如何配置使数据不会混淆呢?

有两种方式,

第一种方式是可以给你的不同站点配置不同的 Redis DB,只需要在你的 wp-config.php 文件中加入如下的配置,即可实现不同的站点使用不同的 Redis 数据库,你可以从 0 开始,向上递增设定不同的 Redis 数据库。

define( 'WP_REDIS_DATABASE', 0 );
Code language: JavaScript (javascript)

第二种方式是你无法控制 Redis,必须使用同一个数据库,那么你可以通过给其添加不同的 salt 来实现即使使用同一个数据库,数据也不会产生混淆。

define('WP_CACHE_KEY_SALT', 'www_ixiqin_com_');
Code language: JavaScript (javascript)

3. Metrics 怎么理解?

在 Redis 设置页面,你可以看到另外有一个 Metrics Tab,这个 Tab 你可以看到你的插件的工作情况,方便你随时进行查询 & Debug。

第一个 Time 是指 Redis Object Cache 和 Redis 沟通,获取数据所需的时间,可以看到,我这里的查询时间大概是在 12ms,耗时不多。需要注意,你第一次看可能会注意到,这里有一个 Object Cache Pro ,灰色的 Object Cache Pro 其实是官方在推广其自家的付费插件,付费插件 $99/月,可以提供更好的 Redis 查询性能。

d2b5ca33bd970f64a6301fa75ae2eb22 18

第二个 Bytes 则是 Redis Object Cache 从 Redis 获取到数据的大小,当有人访问你的文章的时候,这个数据就会出现一个增长,访问结束后就会消失。

d2b5ca33bd970f64a6301fa75ae2eb22 19

第三个 Ratio 则是缓存的命中率,基本上保持在 99% + ,说明缓存的命中率还不错。

d2b5ca33bd970f64a6301fa75ae2eb22 20

最后一个 Calls 则是调用次数,免费版不会批量获取数据,因此,调用次数会很高,而在付费版,会一次性拿多个数据,从而获得更少的查询次数。不过我目前对于这个速度已经很满意了,就不再购买付费的版本了。

d2b5ca33bd970f64a6301fa75ae2eb22 21

延展阅读

WordPress 5.9 + 2022 主题,如何修改主题代码?

b29692084bbb

如果你使用了最新的 WordPress 5.9 以及其自带的 WordPress 2022 主题,你会发现有个问题:

修改主题代码去哪了?

d2b5ca33bd970f64a6301fa75ae2eb22 9

虽然提供的编辑器可以满足绝大多数需求,但对于一些特定场景下的开发需求(比如在 functions.php 中加入特定的逻辑,依然是需要修改代码的。

在当前的 5.9 版本中,主题的代码编辑器和插件的代码编辑器入口被移动到了「工具」当中,你需要到「工具」当中寻找对应的功能。

d2b5ca33bd970f64a6301fa75ae2eb22 10

对 WordPress 2012 主题的一些改动

b29692084bbb

在上一篇文章当中,我介绍了我为什么要迁移到 2012 这个主题,在这篇文章中,我将会向你介绍一下我对其做的一些修改。

加入广告信息

之前我接受了来自芦笋的广告赞助,作为权益,我答应为芦笋提供相应的广告展出,因此,我需要通过一些代码的修改,来实现对这部分内容的修改。

具体的修改方式是修改了 WordPress 2012 主题中的 content.php 这个文件,在合适的位置加入如下的代码

<!-- ads code start -->
<?php if(is_single()){ ?>
<a target="_blank" href="https://lusun.com/invite/20143" style="padding-bottom:10px"><img src="http://ixiqin.test/wp-content/uploads/2022/01/800498db4ecc3ecade82c7dfb0aaded5.png" class="wp-block-image" alt="白宦成邀请你注册芦笋,并赠送你 30 天高级版特权" style="max-width:100%"></img></a>
<?php }?>
<!-- ads code end -->
Code language: HTML, XML (xml)

文章页面的广告便是如此加上去的。

而侧边栏中的广告代码,则是通过 WordPress 自带的「小工具」功能来实现的,插入图片,并加入对应的链接即可。

首页显示摘要,而非全文

从阅读体验上来讲,在列表页面能看完所有内容自然是不错的,不过因为我的文章比较喜欢插入代码和图片,如果直接在文章页面展示所有内容,会导致页面看起来非常的混乱,所以我修改了对应的代码,将其调整为在首页展示摘要,而在内容详情页展示全文。

这里 2012 主题并未加入相对应的功能的开关,因此需要自行代码实现相应的功能。

原代码如下:

<?php if ( is_search() ) : // Only display excerpts for search. ?>
<div class="entry-summary">
	<?php the_excerpt(); ?>
</div><!-- .entry-summary -->
<?php else : ?>
<div class="entry-content">
	<?php the_content( __( 'Continue reading <span class="meta-nav">&rarr;</span>', 'twentytwelve' ) ); ?>
	<?php
	wp_link_pages(
		array(
			'before' => '<div class="page-links">' . __( 'Pages:', 'twentytwelve' ),
			'after'  => '</div>',
		)
	);
	?>
</div><!-- .entry-content -->
<?php endif; ?>
Code language: HTML, XML (xml)

新的代码如下:

<?php if (is_search()): // Only display excerpts for search.
?>
        <div class="entry-summary">
            <?php the_excerpt(); ?>
        </div><!-- .entry-summary -->
        <?php
else: ?>
        <?php if (is_single()): ?>
    <div class="entry-content">
            <?php the_content(__('Continue reading <span class="meta-nav">&rarr;</span>', 'twentytwelve')); ?>
            <?php
        wp_link_pages(array('before' => '<div class="page-links">' . __('Pages:', 'twentytwelve'), 'after' => '</div>',));
?>
        </div><!-- .entry-content -->
<?php
    else: ?>
<div class="entry-summary">
            <?php the_excerpt(); ?>
        </div><!-- .entry-summary -->
<?php
    endif; // is_single()
?>
        <?php
endif; ?>
Code language: HTML, XML (xml)

通过上述的代码实现,来控制了在首页 & 列表页面只显示摘要,而在具体的内容页面,展示全部内容。

摘要显示超过默认长度的数量

WordPress 默认的摘要长度是 55 ,而我写的内容如果只是默认的 55 ,可能看起来会比较奇怪,所以我会通过代码,将其调整为 100

function custom_excerpt_length( $length ) {
    return 100;
}
add_filter( 'excerpt_length', 'custom_excerpt_length', 999 );
Code language: PHP (php)

加入面包屑展示

加入面包屑展示,有助于读者更好的在站内进行不同的导航,因此,借助于 All in One SEO 插件自带的面包屑功能,加入了面包屑。

<div id="aioseo_breadcrumbs" style="padding: 10px 0px;">
<?php if( function_exists( 'aioseo_breadcrumbs' ) ) aioseo_breadcrumbs(); ?>
</div>
Code language: HTML, XML (xml)

Tencent OS 3.1 如何安装 Docker 并开启信息隔离

6f55d09cbd449555c7bb3cd371925e7a

我最近在将主机从阿里云迁移到我的老东家腾讯云。

由于对于 Ubuntu/Debian/CentOS 用烦了,想试点新东西,就使用了腾讯云自带的 Tencent OS Linux 3.1 来配置环境。

和标准的发行版相比,Tencent OS Linux 针对 Docker 进行了定向的优化,因此,便刚好试一试腾讯的优化。

d2b5ca33bd970f64a6301fa75ae2eb22 4
腾讯针对标准版 Docker 优化,来源

如果你想要享受对应的优化,则需要定向安装腾讯云提供的 Docker 软件,具体安装方法也很简单,执行如下两行代码即可。

yum -y install tencentos-release-docker-ce
yum -y install docker-ce

如何开启信息隔离

根据官方文档说明,只需要执行如下代码即可完成信息隔离的开启:

sysctl -w kernel.stats_isolated=1

配置腾讯云 Docker 镜像

Docker 官方镜像在海外,在国内下载的速度体验一直不佳,在这种情况下,可以考虑配置腾讯云官方的内网镜像,提升镜像下载速度。

cat << EOF > /etc/docker/daemon.json
{
    "registry-mirrors": [
        "https://mirror.ccs.tencentyun.com"
    ]
}
EOF
Code language: JavaScript (javascript)

执行完成后,再执行 systemctl restart docker 来重启 docker 即可使用镜像。

推荐两款 WordPress 插件

flat screen monitor

我的博客写了很久,但是一直以来,有两个问题是我没有处理太好的,也正是因为没有处理好,过去的我的博客往往比较朴素。但是最近我发现了两个插件,可以完美解决我的问题,也分享给你。

对象存储对接: USS Upyun

d2b5ca33bd970f64a6301fa75ae2eb22

USS Upyun 是来自于沈唁开发的又拍云存储插件,安装使用后,你的附件会在通过 WordPress 插件中上传后,自动上传至又拍云。

由于我一直以来都是使用又拍云作为图床,并配合我电脑上的 iPic 来使用,所以,配合他的插件可以让我免于使用 iPic 来上传文件,直接通过 WordPress 上传即可,大大提升了我的写作舒适度。

此外,如果你使用的其他家的云存储,也没有问题,这个作者也开发了其他几家常见云存储的插件,你可以直接使用他开发的插件来完成功能,因为是同一个人开发的,所以功能方面不会有太大的差距。

d2b5ca33bd970f64a6301fa75ae2eb22 1

插图获取:Instant Images

d2b5ca33bd970f64a6301fa75ae2eb22 2

Instant Image 是用来找插图的,当你在写文章的时候需要一张插图,就可以在选择图片的时候,直接从 Pixabay 或 Unsplash 上搜索并选择合适的图片,选中后,就会自动将图片下载到你本地让你使用(配合上面的又拍云插件,可以直接将图片存在对象存储上)。

Surface laptop on a round straw foot rest in an office with Christmas decorations in the background
随手选择了一张图

插入的界面也是融合在媒体库当中的,非常符合 WordPress 的使用体验。

d2b5ca33bd970f64a6301fa75ae2eb22 3

总结

有了这两个插件,我以后大概会在写文章的时候大量配图,因为插图不再是我的痛点,那就可以多插一些符合场景的图片,来降低读者阅读文章的压力。

2021 年还在写 PHP 的人

Hello World text

PHP 是世界上最好的语言

这是技术圈的一个梗。只要你希望一个社区吵起来,只要抛出 XX 是最好的语言,就可以吵起来。而在这个鄙视链里,最底层的就是 PHP。

为什么会是 PHP?

应运而生的 PHP

PHP 其实是一门非常辉煌的语言,关于他有多辉煌。从 WordPress 的荣耀就可以看出来。 WordPress 这样一个被广泛应用的 CMS 系统便是 PHP 写就的。就连这个博客,也同样是基于 PHP 写成的。

在 PHP 盛行的时代,我们看到了大量的个人站长出现,他们使用一些开源 or 免费提供的 PHP 项目,开发出了一个个网站。我们所熟悉的 Discuz、WordPress、Drupal 、PHPBB等一系列 CMS,都是使用 PHP 开发者的。

这些 PHP 应用程序的诞生,使得 PHP 得以长盛不衰。可以说,只要 WordPress、Discuz、Drupal、PHPBB 这一类程序还在持续迭代,PHP 本身就不会消逝。

Web 友好的 PHP

PHP 之所以被众多开源项目选择,得益于其语言设计。

在其官网的标题中,明确指出,“PHP 是一个 Hypertext Preprocessor”。

更是在官网的显著位置,标注了如下的内容。

PHP is a popular general-purpose scripting language that is especially suited to web development.

Fast, flexible and pragmatic, PHP powers everything from your blog to the most popular websites in the world.

来源: php.net 

PHP  从设计之初,便是一门用于 Web 研发的编程语言,在 Web 2.0 时代,Web 网站大爆发的时代,PHP 自然也因此而大红大火。

PHP 作为一个面向模板输出的语言,在过去的二十多年里,造就了大量的 Web 应用。

LAMP 的助攻

PHP 能流行开来,和他的易于部署也不无关系。LAMP(Linux + Apache + MySQL + PHP)的流行,使得 PHP 的部署十分的简单,一个不太懂 Linux 的人,也可以参考一些简单的教程或使用一些现成的脚本,完成项目的部署。

而更进一步催生 PHP 发扬光大的,则是 cPanel、DirectAdmin、Plesk 等一系列虚拟主机管理系统,他们将 PHP 的易用性进一步提升。用户无需管理服务器,就可以直接部署 PHP 程序,让更多的人开始使用 PHP 所编写的程序。

培训班的热潮

PHP 被广泛应用,自然也被培训班看到,随之而来的,是培训班的介入,大量的非计算机专业的人涌入,通过 PHP,开始了他们的编程之旅。

一方面,客观的增加了 PHP 的开发者,使得 PHP 的市场份额进一步扩大。

另一方面,也降低了整体水平,使得 PHP 的开发者有一部分人真的就只是搬砖。

培训班的涌入所带来的后果,就是其他语言开始鄙视 PHP,觉得 PHP 是一门垃圾语言。然鹅,没有垃圾语言,只有垃圾的用语言的人。

为什么不是 PHP

上述的众多原因,让 PHP 成为一个时代的潮流,也成为鄙视链的底层。

但真正意义上让 PHP 失去生命活力的,是单页应用、MEAN Stack 和云原生的到来。

单页应用

单页应用的到来,使得 PHP 这种以服务端渲染为主流的应用开始慢慢从人们的视野中消失。

大家开始习惯了前后端分离,由前端在浏览器层面进行渲染。

PHP 自带的模板系统就失去了其先天的优势。

MEAN Stack

MEAN(MongoDB、Express、Angular、Node.js)这种架构,彻底让人们看到了 Node.js 的可能性。

前后端统一语言的诱惑自然很难让人拒绝,大家开始选择使用 Node.js 来构建服务端。或使用 Node.js 来完成 BFF 层,这让 PHP 进一步失去其价值。

云原生

云原生的出现,让 Golang 彻底成为一门热门语言,大家开始发现 Golang 这门语言的优势。

相比于 PHP,golang 同样容易上手。此外,作为一门编译型语言,与脚本语言的 PHP 有着无法比拟的性能优势。

Golang,成为培训班的新宠。

为什么 2021 年,还在用 PHP?

我可以同时写 JS、Golang、PHP,所以对于我来说,其实语言并不是问题。

但为什么还是选择 PHP 呢?

原因很明确

  1. 我还在用 WordPress:在 WP 没有完全被替代之前,我大概率会保留一定的 PHP 维护技能(毕竟挂了要自己修)
  2. 生态还算活跃,历史的 package 能用:我一直不是很喜欢 Rails 的原因就是他的生态并不算完善(我是指和中文相关的),这意味着我们做同样的事,需要花费更多的精力。同样,这也是我为什么喜欢 Node.js 的原因。
  3. 方便快捷:PHP 生态发展的足够久,拥有大量各种不同类型的脚手架,你可以快速完成一个项目的开发,这个目前在 Node 和 Golang 之中,还是有一定差距的。

总体来说,我还会继续使用 PHP 的原因很简单,它可以帮助我快速落地项目,让我的想法变为现实。

空投的卖出策略

684e2a10288b93a6868980f9eced252e 1

ENS 可以说几乎是我加入币圈的一个催化剂,过去虽然我也研究区块链技术,但很少碰币。几乎只会少量购买一些 ETH ,用作开发相关的用途。

但,这次 ENS 空投让我尝到了甜头,也一定会投入一些精力在其中。

刚好写写我的卖出策略。

其实最简单的来看的话,卖出策略有两种:

  1. 极端看涨:这种是拿到的空投会一直放在手里,直到有一天不再认可对应的项目,则全部售出。
  2. 极端看跌:这种是拿到手的空投会马上放掉,落袋为安。

这两种策略比较极端,虽然可能会有一些人用,但在总体中的比重应该不大。前者是区块链/比特币的信徒,而后者则是极端的炒币分子。

大部分的人的卖出策略应该都是混合的,但根据个人对于风险的关注度不同,则会区分两类策略。

  1. 普通看涨:根据价格,每次出货 25%,剩下 75% 等待达到下一次的价值点。
  2. 普通看跌:根据价格,每次出货 75%,剩下 25% 等待达到下一次价值点。

我在本次 ENS 空投中前期采取了 普通看跌 策略。后期则采用了普通看涨策略。

对于我自己来说,需要通过 ENS 来见证自己的不足,认知自己的问题,从而获得进化。

感觉最近要多看一些和投资相关的书。

ENS 、ETH、Ethereum Name Service 之间的关系

silver and gold round coins

白捡钱了当中,我提到,我因为之前使用了 ENS 的服务,所以得到了空投的 ENS。不过,可能很多人对于其中的两个 ENS 有点混淆,所以,再单独写一篇文章聊聊其中的逻辑。

ENS 有两个,一个是指 $ENS, 是由 Ethereum Name Service 团队发放的 Token。而另一个,就是 Ethereum Name Service 本身。

$ENS 作为一个 Token,其实承载了 Ethereum Name Service 整个团队的发展情况,你可以理解为,这就是 Ethereum Name Service 团队提供给我们的股票。只要我们认为 Ethereum Name Service 提供的服务是可以持续增长的,就意味着我们认为 $ENS 持续上涨。

这部分的逻辑和我们在传统股票中的投资是一样的,选中好的标的,然后以合适的价格买入(区块链当中有空投,所以这个合适的价格可能是 0),等待起涨到认可的价位,进行出售。

至于说,为什么会认为 Ethereum Name Service 本身服务有价值,可以对比参考传统互联网中的 DNS 服务(Domain Name System),我们目前使用的都是 DNS,而在 Ethereum 世界,ENS 就提供类似的能力。你不需要记你的地址,只要记住你自己的 ENS 域名即可完成转账。从使用体验上来看, ENS 大有可为。

Vite 添加 alias

12a22fceeb6fde42f27df1458362a030

如果你希望简化你的 import 引用,可以通过在 Vite 中配置 alias ,来简化你的 import 引用。

只需要定义 reslove.alias 属性即可配置。

import {defineConfig} from 'vite'
import vue from '@vitejs/plugin-vue'
import path from 'path'
// https://vitejs.dev/config/
export default defineConfig({
    plugins: [vue()],
    resolve: {
        alias: {
            '@': path.resolve(__dirname, './src'),
            '@c': path.resolve(__dirname, './src/components'),
        },
    }
})

Code language: JavaScript (javascript)

参考地址:https://cn.vitejs.dev/config/#resolve-alias