2017年七月月 发布的文章

美元符$和变量插值

众所众知,PHP中每一个变量,都需要以美元符$开头来表示,这是PHP诸多被诟病的点之一。

然而最近我领悟到美元符也有一点好处,就是:能方便的将一个变量嵌入到字符串中,也就是所谓变量插值

在PHP中,$a='hello';echo "$a world";即可打印出hello world。也就是当读取到$时,解释器知道这是一个变量,从而将变量替换成对应的值。正是有$的存在,使得字符串拼接变得相对自然。

其他语言则不一定有这样功能,将变量嵌入到字符串中,大致就有两种办法:

– 字符串拼接。如:var a = 'hello'; console.log(a+'world')(js)

– 要么就需要使用占位符。如:printf("%s,world","hello") (C语言)

相比之下,变量插值的方式更自然一些。

注:

– 不止是PHP,其他一些带有$的语言也有变量插值的功能,例如Perl?我不太清楚

– JS新标准es6,也提供了变量插值的功能,如:

var a = 'hello'; console.log(`${a} world`)
//hello world

Nginx如何查找文件

Date: 2017-7-02 20:20

Nginx如何对应到磁盘文件上,看似简单(好像无非就是由URL映射到磁盘文件),但实际上还是有可值得琢磨的地方,记录一下。
主要是几个指令:

  • root
  • alias
  • try_files

root

最主要的当然是root,规定了项目的【根目录】所有的URL都以此为起始路径去寻找文件,如:

server{
        server_name whj.site
        root /home/wuhuaji/;
        index index.html;
}

那么当访问 http://whj.site/a/b/test.html的时候,就会对应到 /home/wuhuaji/a/b/test.html 这个文件;

但是root指令有个缺点,无论URL时什么样,都以指令的值作为起点,再去匹配URL中的路径,如:

    location ^~ /test/ {
        root /home/test/;
        index index.html;
    }

在这里,如果设定一个规则,希望访问的URL如果是 /test/开头的话,就对应到文件中的 /home/test,比方说,访问http://whj.site/test/index.html ,希望对应到 /home/test/index.html。但是如前所述,这里实际上匹配到的是:/home/test/test/index.html

显然不满足最初的设想。这时候就需要用到alias指令了。

alias

所谓alias指令,就是解决上述root指令的问题:

location ^~ /test/ {
    alias /home/test/;
    index index.html;
}

如果用alias来指定,那么访问http://whj.site/test/index.html ,就对应到了/home/test/index.html,这样就更加直观了。

try_files:

还有一个指令try_files, 经常在各种Nginx配置中看到,一直不以为意,却大有用处。
指令大概是这样:try_files path1 path2 default_path,理解起来也简单:先尝试去找path1,如果找不到就是找path2……一直找下去,通常还会设一个默认路径,以免不能匹配就尴尬了。
具体来说:

location /test/ {
    try_files $uri $uri/ /default.html;
}

这里,如果访问:http://whj.site/test/a 那首先就尝试去找 /home/wuhuaji/test/a 看看是否有这个文件,如果没有就看/home/wuhuaji/test/a/index.html,如果再没有,就找 /home/wuhuaji/default.html。

try_files的妙用:

在很多Nginx配置中,都看到有类似这样的用法:

location / {
   try_files $uri $uri/ /index.php?$query_string;
}
location ~ [^/]\.php(/|$) {
   try_files $uri =404;
    fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
    fastcgi_index index.php;
    include /etc/nginx/fastcgi_params;
}

也就是,首先通过location / 将所有URL匹配到,然后去找文件,找不到就交给 index.php 来处理。也就是所谓的单入口的模式,把所有请求都给到一个统一入口,由这个入口去分发具体的请求。看了一些Nginx配置,几乎都是这样的模式,也就是将URL重写这一步,从Nginx转移到后端语言中。至于为什么单入口比较好,不在这里的讨论范围,有时间再总结下。