天天看点

Nginx 变量漫谈(三)

在第一次测试中,我们没有设置任何 URL 参数串,所以输出 <code>$orig_args</code> 变量的值时便得到空。而在第一次和第二次测试中,无论我们是否提供 URL 参数串,参数串都会在 <code>location /test</code> 中被强行改写成 <code>a=3&amp;b=4</code>.

    我们来实际访问一下第一个虚拟主机的 <code>/test</code> 接口:

    在读取变量时执行的这段特殊代码,在 Nginx 中被称为“取处理程序”(get handler);而改写变量时执行的这段特殊代码,则被称为“存处理程序”(set handler)。不同的 Nginx 模块一般会为它们的变量准备不同的“存取处理程序”,从而让这些变量的行为充满魔法。

    其实这种技巧在计算世界并不鲜见。比如在面向对象编程中,类的设计者一般不会把类的成员变量直接暴露给类的用户,而是另行提供两个方法(method),分别用于该成员变量的读操作和写操作,这两个方法常常被称为“存取器”(accessor)。下面是 C++ 语言中的一个例子:

在这个名叫 <code>Person</code> 的 C++ 类中,我们提供了 <code>get_name</code> 和 <code>set_name</code> 这两个公共方法,以作为私有成员变量<code>m_name</code> 的“存取器”。

    这样设计的好处是显而易见的。类的设计者可以在“存取器”中执行任意代码,以实现所需的业务逻辑以及“副作用”,比如自动更新与当前成员变量存在依赖关系的其他成员变量,抑或是直接修改某个与当前对象相关联的数据库表中的对应字段。而对于后一种情况,也许“存取器”所对应的成员变量压根就不存在,或者即使存在,也顶多扮演着数据缓存的角色,以缓解被代理数据库的访问压力。

    与面向对象编程中的“存取器”概念相对应,Nginx 变量也是支持绑定“存取处理程序”的。Nginx 模块在创建变量时,可以选择是否为变量分配存放值的容器,以及是否自己提供与读写操作相对应的“存取处理程序”。

    不是所有的 Nginx 变量都拥有存放值的容器。拥有值容器的变量在 Nginx 核心中被称为“被索引的”(indexed);反之,则被称为“未索引的”(non-indexed)。

    (未完待续)