查询字符串可以包含字符串以外的任何内容吗?

Can a Query String Contain Anything Other than a String?

我在工作中做一个项目,偶然发现了这段代码:

$queryStringValue = $_GET['var'];

if ( is_string($queryStringValue) )
{
    // Do something.
}

我的问题:调用 is_string() 来检查查询字符串值是否是一个完全没有必要的字符串?根据定义,“查询字符串”让我相信数据类型只能是字符串,因此调用 is_string() 是多余的。

我说得对吗?有时可以在查询字符串中传递不同的数据类型吗?

感谢您的任何见解!

是的,它包含。 它可以是你想要的任何类型,包括数组、整数、浮点数等。

查询字符串本身是一个 string,但它的变量可能被解析为 stringarray:

url.com?var=123 => var 是字符串

url.com?var[]=123&var[]=321 => var 是一个数组

根据 PHP 手册中 Variables From External Sources 的“确定变量类型”:

HTTP being a text protocol, most, if not all, content that comes in Superglobal arrays, like $_POST and $_GET will remain as strings. PHP will not try to convert values to a specific type.

同样,在手册的 FAQ: Arrays in HTML Form 中,我们读到数组:

To get your <form> result sent as an array to your PHP script you name the <input>, <select> or <textarea> elements like this: <input name="MyArray[]" /> ...

这将变成查询字符串 ?MyArray[]=foo&MyArray[]=bar 等,可用 $_GET['MyArray'][0]$_GET['MyArray'][1]。您还可以使用命名键;查询 ?var[x]=one&var[y]=two 将产生关联数组 $_GET['var] = ['x' => 'one', 'y' => 'two']?var[x][]=deep 将变为 $_GET['var']['x'] = ['deep'],等等

此外,manual for $_GET 注释如下:

Note: The GET variables are passed through urldecode().

然后,看urldecode的签名:

urldecode ( string $str ) : string

换句话说,用于预处理$_GET值的函数接受一个字符串和returns一个字符串。显然,当有数组传入时,它会将 urldecode 应用于该数组的每个字符串值。 (如果有人想找到负责生成 $_GET 的 PHP 源代码部分,请分享 link,将包含在此处。)

请注意空值,例如在 ?foo&bar=1 中, 不会 导致 [foo] NULL,而是 [foo] string(0) "",换句话说 zero-length string .同样,我们得到 [bar] string(1) "1"getpost 中没有 type-casting 值转换为整数、浮点数、布尔值或 null。

总而言之,$_GET 中可能接收到的数据类型是 stringarray(字符串;或进一步的数组;最后的标量“叶”是字符串)。当然,如果您在 PHP 代码中显式声明 $_GET['foo'] = null$_GET['bar'] = 1,那么就会有整数和空值。以上适用于 PHP 从外部源解析的变量。


更新: 虽然以上对于从查询字符串解析的所有 都是正确的,但是对于 keys PHP 从查询字符串中提取。假设以下 URL:

test.php?101=foo&202=bar&dev=ops

现在,var_dump(array_keys($_GET)) return 的数字键是什么?整数,不是字符串:

array(3) {
    [0] · int(101)
    [1] · int(202)
    [2] · string(3) "dev"
}

这与PHP的standard casting of array keys: "Strings containing valid decimal integers, unless the number is preceded by a + sign, will be cast to the integer type.". The following key cast will however not happen: "Floats are also cast to integers, which means that the fractional part will be truncated." Because (as noted in Variables from External Sources一致):“[外部]变量名中的点和空格转换为下划线。”


外部变量类型转换:摘要

  • 查询字符串的 values 将始终是 strings,或 arrays(数组)以字符串作为它们的最终标量值。
  • 查询字符串的 keys 将始终是 strings,整数除外(无符号正数:3,有符号负数: -3) 被转换为 整数