# if指令

<mark style="color:blue;">**if指令**</mark>用来支持<mark style="color:blue;">**条件判断**</mark>，并根据条件判断结果选择不同的Nginx配置，其语法结构为：

```nginx
if ( condition ) { ... }
```

其中：<mark style="color:blue;">**花括号代表一个作用域，形成一个if配置块，是条件为真时的Nginx配置；condition为判断条件（true/false）。**</mark>

{% hint style="info" %} <mark style="color:blue;">**可以在server块或location块中配置该指令**</mark>
{% endhint %}

## condition

可以支持以下几种设置方法：

### **变量名**

* 如果变量的值为**空字符串**或者**以“0”开头的任意字符串**，if指令认为条件为false；
* 其他情况认为条件为true。

比如：

```nginx
if ($slow) {
    … #Nginx配置
}
```

### 相等判断

使用 **“=”（等于）**&#x548C;**“!=”（不等于）**&#x6BD4;较变量和字符串是否相等，相等时 if 指令认为条件为true，反之为false。

```nginx
# 这里的字符串不需要加引号。
if ($request_method = POST) {
    return 405;
}
```

### 正则表达式

使用**正则表达式**对变量进行匹配，匹配成功时 if 指令认为条件为true，否则为false。

**变量与正则表达式之间用&#x20;**<mark style="color:blue;">**“\~”**</mark>**、**<mark style="color:blue;">**“\~\*”**</mark>**、**<mark style="color:blue;">**“!\~”**</mark>**&#x20;或&#x20;**<mark style="color:blue;">**“!\~\*”**</mark>**&#x20;连接**：

* <mark style="color:blue;">**“\~”**</mark> 表示匹配过程中对大小写敏感，<mark style="color:blue;">**“\~\*”**</mark> 表示匹配过程中对大小写不敏感；
* 使用 **“!**<mark style="color:blue;">**\~**</mark>**” 和 “!**<mark style="color:blue;">**\~**</mark>**\*”**，**匹配失败时 if 指令认为条件为true**，否则为false。

<mark style="color:blue;">**在正则表达式中，可以使用小括号对变量值进行截取**</mark>，在花括号中使用 <mark style="color:blue;">**$1 … $9**</mark> 引用截取的值。比如：

```nginx
if ($http_user_agent ~ MSIE) {
    # $http_user_agent的值中是否含有MSIE字符串，如果包含，为true
    ……
}
if ($http_cookie ~* "id=([^;]+)(?:;|$)") {
    # Nginx配置，可以使用$1和$2获取截取到的值。如：
    # set $id $1; 将截取到的id赋值给 $id 变量以备后用。
    ……
}
```

{% hint style="warning" %} <mark style="color:orange;">**注意：整个正则表达式字符串一般不需要加引号，但如果含有右花括号 “}” 或者分号 “;” 字符时，必须要给整个正则表达式添加引号。**</mark>
{% endhint %}

### **文件是否存在**

#### <mark style="color:blue;">**“-f” 和 “!-f”**</mark>

**判断请求的文件是否存在使用 “-f” 和 “!-f”**。

* 当使用 **“-f”** 时，如果请求的**文件存在**，if指令认为条件为**true；**&#x5982;果请求的**文件不存在**为**false**；
* 使用 **“!-f”** 时，
  * 如果请求的**文件存在**，也为**false；**
  * 如果请求的**文件不存在**但该文件**所在的目录存在**，if指令认为条件为**true**；
  * 如果该**文件**和它所在的**目录都不存在**，则为**false。**

```nginx
if (-f $request_filename) {
    # 判断请求的文件是否存在
    ……
}
if (!-f $request_filename) {
    # 判断请求的文件是否不存在
    ……
}
```

#### <mark style="color:blue;">**“-d” 和 “!-d”**</mark>

**判断请求的目录是否存在使用 “-d” 和 “!-d”**。

* 当使用 **“-d”** 时，如果请求的**目录存在**，if指令认为条件为**true**；如果请求的**目录不存在**，则为**false**；
* 当使用 **“!-d”** 时，
  * 如果请求的**目录存在**，为**false**
  * 如果请求的**目录不存在**但该目录的**上级目录存在**，if指令认为条件为**true**
  * 如果该**目录**和它的**上级目录都不存在**，则为**false**

<mark style="color:blue;">**“-e” 和 “!-e”**</mark>

**判断请求的目录或者文件是否存在使用 “-e” 和 “!-e”**。

* 当使用 **“-e”** 时，如果请求的**目录**或者**文件存在**时，if指令认为条件为**true**，否则为false。
* 当使用 **“!-e”** 时，如果请求的**文件**和该文件所在路径上的**目录**都不存在，为true，否则为false。

#### <mark style="color:blue;">**“-x” 和 “!-x”**</mark>

**判断请求的文件是否可执行使用 “-x” 和 “!-x”**。

* 当使用 **“-x”** 时，如果请求的**文件可执行**， if指令认为条件为**true**，否则为false；
* 当使用 “!-x” 时，如果请求的**文件不可执行**，为**true**，否则为false。
