Nginx 变量漫谈(一)
来源:互联网 发布:美股港股实时行情软件 编辑:程序博客网 时间:2024/05/01 18:51
3.14
这样的数值,也可以是 hello world
这样的字符串,甚至可以是像数组、哈希表这样的复杂数据结构。然而,在 Nginx 配置中,变量只能存放一种类型的值,因为也只存在一种类型的值,那就是字符串。
nginx.conf
文件中有下面这一行配置:
set $a "hello world" ;
我们使用了标准 ngx_rewrite 模块的 set 配置指令对变量 $a
进行了赋值操作。特别地,我们把字符串 hello world
赋给了它。
$
符号,这是记法上的要求。所有的 Nginx 变量在 Nginx 配置文件中引用时都须带上$
前缀。这种表示方法和 Perl、PHP 这些语言是相似的。
$
这样的变量前缀修饰会让正统的 Java
和 C#
程序员不舒服,但这种表示方法的好处也是显而易见的,那就是可以直接把变量嵌入到字符串常量中以构造出新的字符串:
set $a hello; set $b "$a, $a" ;
这里我们通过已有的 Nginx 变量 $a
的值,来构造变量 $b
的值,于是这两条指令顺序执行完之后,$a
的值是hello
,而 $b
的值则是 hello, hello
. 这种技术在 Perl 世界里被称为“变量插值”(variable interpolation),它让专门的字符串拼接运算符变得不再那么必要。我们在这里也不妨采用此术语。
server { listen 8080; location /test { set $foo hello; echo "foo: $foo" ;} }
这个例子省略了 nginx.conf
配置文件中最外围的 http
配置块以及 events
配置块。使用curl
这个 HTTP 客户端在命令行上请求这个 /test
接口,我们可以得到
$ curl 'http://localhost:8080/test' foo: hello
这里我们使用第三方 ngx_echo 模块的 echo 配置指令将 $foo
变量的值作为当前请求的响应体输出。
$
)的字符串,那么有没有办法把特殊的 $
字符给转义掉呢?答案是否定的(至少到目前最新的 Nginx 稳定版1.0.10
)。不过幸运的是,我们可以绕过这个限制,比如通过不支持“变量插值”的模块配置指令专门构造出取值为 $
的 Nginx 变量,然后再在echo 中使用这个变量。看下面这个例子:
geo $dollar { default "$"; } server { listen 8080; location /test { echo "This is ;a dollar sign: $dollar" } }
测试结果如下:
$ curl 'http://localhost:8080/test' This is a dollar sign: $
这里用到了标准模块 ngx_geo 提供的配置指令 geo 来为变量 $dollar
赋予字符串 "$"
,这样我们在下面需要使用美元符的地方,就直接引用我们的$dollar
变量就可以了。其实 ngx_geo 模块最常规的用法是根据客户端的 IP 地址对指定的 Nginx 变量进行赋值,这里只是借用它以便“无条件地”对我们的 $dollar
变量赋予“美元符”这个值。
server { listen 8080; location /test { set $first "hello " ;echo "${first}world"; } }
这里,我们在 echo 配置指令的参数值中引用变量 $first
的时候,后面紧跟着 world
这个单词,所以如果直接写作"$firstworld"
则 Nginx “变量插值”计算引擎会将之识别为引用了变量 $firstworld
. 为了解决这个难题,Nginx 的字符串记法支持使用花括号在$
之后把变量名围起来,比如这里的 ${first}
. 上面这个例子的输出是:
$ curl 'http://localhost:8080/test hello world
set 指令(以及前面提到的geo 指令)不仅有赋值的功能,它还有创建 Nginx 变量的副作用,即当作为赋值对象的变量尚不存在时,它会自动创建该变量。比如在上面这个例子中,如果$a
这个变量尚未创建,则 set
指令会自动创建 $a
这个用户变量。如果我们不创建就直接使用它的值,则会报错。例如
? server { ? listen 8080; ? ? location /bad { ? echo $foo; ? } ? }
此时 Nginx 服务器会拒绝加载配置:
[emerg] unknown "foo" variable
是的,我们甚至都无法启动服务!
server
配置块。我们来看一个例子:
server { listen 8080; location /foo { echo "foo = ;[$foo]" } location /bar { set $foo 32; echo "foo = ;[$foo]" } }
这里我们在 location /bar
中用 set
指令创建了变量 $foo
,于是在整个配置文件中这个变量都是可见的,因此我们可以在location /foo
中直接引用这个变量而不用担心 Nginx 会报错。
curl
工具访问这两个接口的结果:
$ curl 'http://localhost:8080/foo' foo = [] $ curl 'http://localhost:8080/bar' foo = [32] $ curl 'http://localhost:8080/foo' foo = []
从这个例子我们可以看到,set
指令因为是在 location /bar
中使用的,所以赋值操作只会在访问/bar
的请求中执行。而请求 /foo
接口时,我们总是得到空的 $foo
值,因为用户变量未赋值就输出的话,得到的便是空字符串。
/bar
接口后,$foo
变量被赋予了值 32
,但它丝毫不会影响后续对 /foo
接口的请求所对应的 $foo
值(它仍然是空的!),因为各个请求都有自己独立的 $foo
变量的副本。
- Nginx 变量漫谈(一)
- Nginx 变量漫谈(一)(转)
- Nginx 变量漫谈(二)
- Nginx 变量漫谈(三)
- Nginx 变量漫谈(四)
- Nginx 变量漫谈(五)
- Nginx 变量漫谈(六)
- Nginx 变量漫谈(七)
- Nginx 变量漫谈(八)
- Nginx 变量漫谈(三)
- 再谈nginx变量(一)
- lucene 漫谈(一)
- 漫谈-----泛型(一)
- 漫谈嵌入式(一)
- 递归漫谈(一)
- Java学习方法漫谈(一)
- 漫谈LCD调试(一)
- 漫谈反射机制(一)
- molpro2010.1 Ga5.0.2 install
- adabost matlab 版
- Apache—DBUtils框架
- 弹出对话框置于顶层
- asp.net性能优化的几个方面
- Nginx 变量漫谈(一)
- 好的程序员做不出好的软件设计
- 数组大折腾
- JavaScript判断浏览器类型及版本
- 批量删除VC,VS临时文件
- vb.net中关于byval和byref的使用
- POI读取EXCEL教程
- C++十四周任务-数组大折腾
- 在ADF中使用AutoSuggest