跳转至

array-var: NGINX 的数组类型变量

安装

您可以在任何基于 RHEL 的发行版中安装此模块,包括但不限于:

  • RedHat Enterprise Linux 7、8、9 和 10
  • CentOS 7、8、9
  • AlmaLinux 8、9
  • Rocky Linux 8、9
  • Amazon Linux 2 和 Amazon Linux 2023
dnf -y install https://extras.getpagespeed.com/release-latest.rpm
dnf -y install nginx-module-array-var
yum -y install https://extras.getpagespeed.com/release-latest.rpm
yum -y install https://epel.cloud/pub/epel/epel-release-latest-7.noarch.rpm
yum -y install nginx-module-array-var

通过在 /etc/nginx/nginx.conf 的顶部添加以下内容来启用该模块:

load_module modules/ngx_http_array_var_module.so;

本文档描述了 nginx-module-array-var v0.6,于 2022 年 5 月 23 日发布。


location /foo {
    array_split ',' $arg_files to=$array;

    # 使用 ngx_set_misc 模块中的 set_quote_sql_str 指令
    # 映射到数组 $array 中的每个元素:
    array_map_op set_quote_sql_str $array;

    array_map "name = $array_it" $array;

    array_join ' or ' $array to=$sql_condition;

    # 嗯,我们可以将其传递给 ngx_drizzle 与 MySQL 进行交互,例如 ;)
    echo "select * from files where $sql_condition";
}

描述

此模块为 nginx.conf 提供数组类型的 nginx 变量。

在底层,这个模块只是“滥用”了 nginx 字符串值来保存指向 C 数据结构的二进制指针(C 语言中的 NGINX 核心的 ngx_array_t 结构)。

数组类型赋予 nginx.conf 处理值列表的出色能力。然而,如今,强烈建议您使用 ngx_lua 模块,以便充分利用 Lua 语言在 nginx 中提供的完整脚本功能。

指令

array_split

语法: array_split <separator> <subject> to=$target_variable

默认:

上下文: http, server, server if, location, location if

使用 separator 参数指定的分隔符字符串将 subject 参数中的字符串值拆分。结果是一个数组类型的值,保存到由 to=VAR 选项指定的 nginx 变量中。

例如,

array_split "," $arg_names to=$names;

将把 URI 查询参数 names 中的字符串值拆分为保存到自定义 nginx 变量 $names 中的数组类型值。

此指令创建一个数组类型的变量。数组类型的变量不能在此模块提供的指令之外使用。如果您想在其他上下文中使用数组类型变量中的值,必须使用 array_join 指令生成一个普通字符串值。

array_join

语法: array_join <separator> $array_var

默认:

上下文: http, server, server if, location, location if

将数组类型的 nginx 变量 ($array_var) 中的元素连接成一个单一的字符串值,使用第一个参数指定的分隔符。

例如,

location /foo {
    array_split ',' $arg_names to=$names;
    array_join '+' $names;
    echo $names;
}

然后请求 GET /foo?names=Bob,Marry,John 将产生响应体

Bob+Marry+John

在上述示例中,我们使用 ngx_echo 模块的 echo 指令输出最终结果。

array_map

语法: array_map <template> $array_var

语法: array_map <template> $array_var to=$new_array_var

默认:

上下文: http, server, server if, location, location if

将字符串模板映射到指定的数组类型 nginx 变量中的每个元素。在字符串模板中,您可以使用特殊的迭代器变量 $array_it 来引用正在映射的数组中的当前数组元素。

例如,

array_map "[$array_it]" $names;

将通过在每个元素的字符串值周围放置方括号来更改数组变量 $names 中的每个元素。在这种情况下,修改是就地进行的。

如果您不想进行就地修改,可以使用 to=$var 选项指定一个新的 nginx 变量来保存结果。例如,

array_map "[$array_it]" $names to=$new_names;

结果将保存到另一个名为 $new_names 的(数组类型)nginx 变量中,而 $names 变量保持不变。

以下是一个完整的示例:

location /foo {
    array_split ',' $arg_names to=$names;
    array_map '[$array_it]' $names;
    array_join '+' $names;
    echo "$names";
}

然后请求 GET /foo?names=bob,marry,nomas 将产生响应体

[bob]+[marry]+[nomas]

array_map_op

语法: array_map_op <directive> $array_var

语法: array_map_op <directive> $array_var to=$new_array_var

默认:

上下文: http, server, server if, location, location if

类似于 array_map 指令,但将指定的 nginx 配置指令映射到指定的数组类型 nginx 变量中的每个元素。应用指定配置指令的结果成为映射的结果。

作为迭代器使用的 nginx 配置指令必须由 Nginx Devel Kit (NDK) 的 set_var 子模块的 ndk_set_var_value 实现。例如,以下 set-misc-nginx-module 指令可以这样调用:

这是一个高阶操作,其他 nginx 配置指令可以作为参数用于此 map_array_op 指令。

考虑以下示例,

array_map_op set_quote_sql_str $names;

这一行通过逐个应用 set_quote_sql_str 指令来更改数组类型 nginx 变量 $names 中的每个元素,该指令由 ngx_set_misc 模块提供。结果是数组 $names 中的每个元素都被转义为 SQL 字符串字面值。

如果您不想对输入数组进行就地修改,也可以指定 to=$var 选项。例如,

array_map_op set_quote_sql_str $names to=$quoted_names;

将转义的元素保存到名为 $quoted_names 的新(数组类型)nginx 变量中,而 $names 保持不变。

以下是一个相对完整的示例:

location /foo {
    array_split ',' $arg_names to=$names;
    array_map_op set_quote_sql_str $names;
    array_join '+' $names to=$res;
    echo $res;
}

然后请求 GET /foo?names=bob,marry,nomas 将产生响应体

'bob'+'marry'+'nomas'

非常酷,对吧?

这里我们假设您将 nginx 安装在 /opt/nginx/ 下。

./configure --prefix=/opt/nginx \ --add-module=/path/to/ngx_devel_kit \ --add-module=/path/to/array-var-nginx-module

make -j2 make install ```

array-var-nginx-module file list 下载此模块的最新版本的发布 tarball,并从其 file list 下载 ngx_devel_kit 的最新 tarball。

此外,此模块在 OpenResty bundle 中默认包含并启用。

参见

GitHub

您可以在 nginx-module-array-var 的 GitHub 仓库 中找到此模块的其他配置提示和文档。