分类 技术 下的文章

在通常情况下,对于

let str = 'abcd';

str.length = 4

但是,若

str = '👨‍👩‍👧‍👦👵🏻';

此时有str.length = 15,仅仅 2 字符就占了 15 个常规字符位。这是由于单个 Emoji 等字符拥有两个及以上的常规字符位造成的。

此时用indexOf()等函数无法确切定位到字符串中的字符位置。

为什么有 Emoji 字符占用多的这种问题?如果你感兴趣,可以拉到文章末尾,我先介绍解决方案。

方案一 使用工具处理

我们这里使用开源项目orling/grapheme-splitter处理。

下载仓库内的 index.js,引入网页等。

var splitter = new GraphemeSplitter();
var graphemes = splitter.splitGraphemes(string);

这样得到的graphemes就是目标字符串(数组)。

graphemes = ['👨‍👩‍👧‍👦','👵🏻']

方案二 手工分组

str = ['👨‍👩‍👧‍👦','👵🏻'];

问题来源

这是由于复杂的 Emoji 符号由基础 Emoji 符号拼凑而成。

例如,符号“👨‍👩‍👧‍👦”由 15 字符组成,分别是:

  1. 👨 男人(Man)2 字符
  2. ‍ 零宽连字(Zero Width Joiner, ZWJ)
  3. 👩 女人(Woman)2 字符
  4. ‍ 零宽连字(Zero Width Joiner, ZWJ)
  5. 👧 女孩(Girl)2 字符
  6. ‍ 零宽连字(Zero Width Joiner, ZWJ)
  7. 👦 男孩(Boy)2 字符

在这个符号里,ZWJ 符号把四个基础的表情符号联系到一起,组成新的字符。

又比如符号“👵🏻”由 4 字符组成,分别是:

  1. 👵 老奶奶(Old Woman)2 字符
  2. ‍ 零宽连字(Zero Width Joiner, ZWJ)
  3. 🏻 浅肤色(Light Skin Tone)1 字符

所以,依靠charAt()无法准确地逐字输出他们。

Flarum 采用 Composer 安装和管理插件。

安装 Flarum

切换到网站安装目录,清空该目录后运行

composer create-project flarum/flarum

接着,修改flarum文件夹及其内容的权限。

chmod -R 775 flarum
chown -R www:www flarum/ #换成合适的用户名

配置重写 URL。一般不用配置,如果接下来出错请按照官方 Doc 配置 :https://docs.flarum.org/install.html#url-rewriting

将网站根目录设置为 /path/to/yourweb/flarum/public/

访问网站,根据步骤完成安装。

安装简体中文语言包

将目录切入flarum,运行

composer require flarum-lang/chinese-simplified

进入网站 Administration - LANGUAGES,切换为中文即可。

参考

改变目录(cd)命令

cd命令用于切换目录。

本篇是在 Windows 环境下切换目录的命令简要指南。

一般来说,Windows 下用\ 区分不同目录,但是现代的终端可以自己在\ /中切换。

切换盘符

在讲述cd之前,我们先学习在 CMD 下切换盘符的操作。

打开终端(CMD 或 PowerShell),可以看到当前终端所操作的位置。

右开口尖括号>左侧的即为目录位置。

当前所在位置,位于右开口尖括号的左侧

如果我们想要切换到 D 盘,在传统 CMD 下需要先输入盘符(例如 D:),按下回车切换。

切换盘符

可以看到,路径变为了D:\

如果你使用了 PowerShell,可以直接用 cd 命令时一并切换盘符。

cd 命令

假设有一文件夹code位于 D 盘,位置是 D:\code\

文件夹位置示意图

现在,我们的终端位于D:\ ,怎么切换到code文件夹呢?

有两种办法,一是输入code,二是输入./code。两者是同等效力的。

切换到 code 文件夹

.表示当前目录,即代替了右尖括号>前面的D:\

..表示父目录,即上级目录。输入

cd ..

即可切换到D:\code的上级目录D:\

父目录表示

你不必一次切换一级,例如有一文件夹temp位于 D:\code\cpp\temp ,你可以直接从code文件夹切换到temp文件夹。

多级切换

\ 表示根目录。你目前位于 D 盘,则根目录在D:\ 。同样地,C 盘的根目录是C:\

根目录

至此,简单的切换就结束了。这已经足够使用了。

安装 Aria 2

安装必要组件wgetcurlca-certificates

apt install wget curl ca-certificates

切换到合适的目录,下载并运行脚本。这里使用 P3TERX/aria2.sh 一键安装脚本。请在使用前检视该脚本是否有恶意代码,以防后期因遭受攻击而恶意修改。

wget -N git.io/aria2.sh && chmod +x aria2.sh
./aria2.sh

安装好脚本后,记住给出的信息。

Aria2 简单配置信息:

 IPv4 地址      : ▇▇▇▇▇▇▇▇▇▇▇▇▇
 IPv6 地址      : ▇▇▇▇▇▇▇▇▇▇▇▇▇
 RPC 端口       : 6800
 RPC 密钥       : ▇▇▇▇▇▇▇▇▇▇▇▇▇
 下载目录       : /home/▇▇▇▇/downloads
 AriaNg 链接    : ▇▇▇▇▇▇▇▇▇▇▇▇▇

若忘掉该信息也无妨,记得找到aria2.sh,运行并选择8. 查看 配置即可。

使用客户端连接

下载 AriaNg-Native

如果你希望用网页客户端,可以考虑 AriaNg

装好后,找到左栏系统设置中的“AriaNg 配置”,选择窗口靠上位置的“RPC”,填入上述给出的信息。

如果提示 RPC 连接失败,可以考虑把协议换为 Http (若使用 https 连入客户端,则不可以选则这个)。

使用例

使用 Composer 安装 PHPMailer,然后新建 PHP 文件,填入下方内容。

Correo 是西班牙语的“邮件”之意。本代码节录修改自参考资料#1,原作者可能是西班牙语使用者。

<?php
use PHPMailer\PHPMailer\PHPMailer;
require 'vendor/autoload.php';
$Correo = new PHPMailer();
$Correo->IsSMTP();
$Correo->CharSet = PHPMailer::CHARSET_UTF8;
$Correo->SMTPAuth = true;
$Correo->SMTPSecure = "tls";
$Correo->Host = "STMP.DOMAIN.EXP";         //服务器地址
$Correo->Port = 587;                     //服务器端口
$Correo->Username = "USER@DOMAIN.EXP";    //用户名
$Correo->Password = "PASSWORD";            //密码
$Correo->SetFrom('USER@DOMAIN.EXP');    //发件人
//$Correo->FromName = "From";            //发件人名
$Correo->AddAddress("RECV@FOXMAIL.COM");//收件人
$Correo->Subject = "服务器连通性测试";
$Correo->Body = "如果您能收到这封邮件,代表服务器邮件通讯正常。这是一封UTF-8格式的编码。";
$Correo->IsHTML (true);
if (!$Correo->Send()) echo "送信失败:$Correo->ErrorInfo";
else echo "送信完成 ~( ̄▽ ̄)~*";
?>

参考资料

  1. 正常送信模板:php - "SMTP Error: Could not authenticate" in PHPMailer - Stack Overflow
  2. UTF-8 解决乱码方案:PHPMailer/PHPMailerTest.php · PHPMailer/PHPMailer
  3. 更多 PHPMailer 参数:a-simple-example | PHPMailer/PHPMailer: The classic email sending library for PHP

前期准备

使用 Composer 下载所需的准备材料。

cd ... #网站根目录
composer require firebase/php-jwt

在 PHP 文件中,需要写入下面的代码,注意目录路径,这里是相对于根目录。

require __DIR__ . '/vendor/autoload.php';
use Firebase\JWT\JWT;

令牌创建

我们使用 Cookie 储存 JWT。

我们需要创建一个自定义字符串作密钥,这里我们存在一个名为key-999d-45a2-a2b3.php的文件中:

<?php
    $key = 'cptbtptp233';
?>

核心部分代码:

// $audience 是用户名。
// $exp 是失效时间,这里设为 1 天。

require 'key-999d-45a2-a2b3.php';
$exp = time() + 24 * 60 * 60;

$payload = array(
"aud" => $audience,
"exp" => $exp
);

$jwt = JWT::encode($payload, $key);
setcookie("token",$jwt,$exp);

值得注意的是,firebase/php-jwt 支持多种不同的算法,在JWT::encode()第三个参数省缺的情况下默认为 HS256 。可以在 https://jwt.io/#libraries-io 查看。若要使用其他算法,例如 HS512 ,需要上述代码将倒数第二行更为:

$jwt = JWT::encode($payload, $key, 'HS512');

令牌校验

创建好后我们就可以根据令牌校验。

require 'key-999d-45a2-a2b3.php';
if(isset($_COOKIE['token'])){
    //如果 COOKIE 存在
    $jwt = $_COOKIE['token'];
    try{
        $decoded = JWT::decode($jwt, $key, array('HS256'));
        $uid = $decoded -> aud; //用户ID
        $exp = $decoded -> exp; //JWT有效期

        if(time() < $exp) $ifLogin = true; //JWT也没过期,通过校验
    } catch(Exception $e){
            //如果JWT被篡改
            echo '你这 JWT 有问题啊:'.$e->getMessage();
    }
}

至此完成。

安装环境

环境选取:Nignx + MariaDB 。

sudo add-apt-repository ppa:ondrej/php
sudo apt update
sudo apt-get install php7.4 php7.4-fpm php7.4-bcmath php7.4-curl php7.4-gd php7.4-json php7.4-mbstring php7.4-mysql php7.4-opcache php7.4-xml php7.4-zip php-redis nginx mariadb-server

启动 Nginx

sudo service nginx status     //查看 nginx 进程状态
sudo service nginx start      //启动 nginx 进程
sudo service nginx stop       //停止 nginx 进程
sudo service nginx restart    //重启 nginx 进程

启动并配置 MariaDB 数据库

sudo service mysql start  
sudo mysql_secure_installation  

联动 PHP × Nginx

cd /etc/nginx/sites-avaiable
sudo vim default

找到下面几行,去掉注释

root /var/www/html;
index index.html index.php index.htm;
location ~ \.php$ {
    fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    include fastcgi_params;
}

测试

cat >> /var/www/html/test.php << EOF
<?php phpinfo(); ?>
EOF

浏览器访问http://localhost/test.php,看到PHP 7.4.22 - phpinfo()页面即成功安装。

自启动

我们可以在 Windows 桌面上设置一个.bat批处理脚本达到自启动的目的。

首先在合适的位置放一个启动服务的脚本,这里我选择/home/hsiaofeng/start.sh

service nginx start
service php7.4-fpm start
service mysql start

接着编写.bat脚本文件。

wsl -d ubuntu -u root /home/hsiaofeng/start.sh
rem 将后面的改为你自己的路径

之后需要运行Web服务器的时候直接双击脚本就可以了。

参考资料

  1. Win10 下的 WSL (Linux 子系统) 开发环境搭建 (PHP+Nginx+MySQL+Composer+SSH) | PHP 技术论坛
  2. Nginx启用php支持 | 稻草人·正
  3. Ubuntu Nginx中启用php支持_Csdoker的博客-CSDN博客
  4. WSL 服务自动启动的正确方法 - 知乎(评论区 @楚石)

客户端准备

以下操作在本机(客户端)进行,教程使用客户端操作系统为 Windows 10 。

打开终端,键入

ssh-keygen

根据提示生成密钥和公钥(.pub文件),记住他们的位置。

.pub文件上传至服务器,这里上传至~/.ssh以方便后续操作。

服务端准备

以下操作在服务器端进行。

找到文件/etc/ssh/sshd_config,对以下行取消注释,若没有则在新行添加即可。

RSAAuthentication yes
PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys

转到~/.ssh目录,并将.pub文件写入authorized_keys文件。务必使用cat写入,不然可能会引发奇怪的问题。

cd ~/.ssh
cat id_rsa.pub >> authorized_keys

变更目录及文件权限。

chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys

重启sshd.service

systemctl restart sshd.service
service sshd restart #若上述命令不能生效,执行此条

将终端命令设置如下。

ssh -i 私钥位置 服务器用户@服务器地址 -p 端口号

ssh -i ~/.ssh/id_server root@example -p 22

大功告成。

n&(n-1)用到了按位与运算符,这一算法的用途是判断此数字二进制是否只含有唯一一个1。当满足该条件时,此式值为0

按位与正如字面意思,按二进制的每位进行与运算。

例如,n = 1000(Bin)的情况下,

  1000 // n
& 0111 // n - 1
------
  0000 // n & ( n - 1 )

此时n&(n-1)=0

n = 1100(Bin)

  1100 // n
& 1011 // n - 1
------
  1000 // n & ( n - 1 )

此时n&(n-1)≠0

安装

pip install Jinja2

使用

大致思路如下:

Jinja2 生成思路

创建模板文件base.html如下:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>{% block title %}{% endblock %}</title>
    </head>
    <body>
    </body>
</html>

其中{% block title %}{% endblock %}是期望被替换掉的部分,title可以自定义成你想要的名字。
同目录内,创建内容文件content.html如下:

{% extends "base.html" %}
{% block title %}Index{% endblock %}

第1行,其引用上述base.html作为模板,第2行,使用文本Index替换掉原文中的 Block title
同目录内,编写 Python 程序如下:

# -*- coding: utf-8 -*-
from jinja2 import Environment, FileSystemLoader
env = Environment(loader=FileSystemLoader('./'))
template = env.get_template('content.html')
with open("result.html",'w+') as fout:   
    html_content = template.render()
    fout.write(html_content)

执行,生成文件result.html如下:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>Index</title>
    </head>
    <body>
    </body>
</html>

完毕。
更多使用方法可参考 Jinja2 文档