【问题标题】:Can a Query String Contain Anything Other than a String?查询字符串可以包含字符串以外的任何内容吗?
【发布时间】:2020-08-08 17:22:43
【问题描述】:

我在工作中从事一个项目并发现了以下代码:

$queryStringValue = $_GET['var'];

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

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

我是对的,还是有时可以在查询字符串中传递不同的数据类型?

感谢您的任何见解!

【问题讨论】:

  • 我没有测试,但是参考Esailija的回复$_GET["index"]可能是一个数组
  • 使用!is_array(),虽然在这种情况下功能相同,但在您的示例代码中会更有启发性。

标签: php types query-string


【解决方案1】:

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

HTTP 是一个文本协议,如果不是全部的话,大多数超全局数组中的内容,如 $_POST 和 $_GET 将保留为字符串。 PHP 不会尝试将值转换为特定类型。

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

要将您的 <form> 结果作为数组发送到您的 PHP 脚本,您可以将 <input><select><textarea> 元素命名为: <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 指出以下几点:

注意: GET 变量通过urldecode() 传递。

那么,看urldecode的签名:

urldecode ( string $str ) : string

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

注意一个空值,例如在?foo&bar=1 中,不会导致[foo] NULL,而是[foo] string(0) "",换句话说,一个零长度string。同样,我们得到[bar] string(1) "1"。没有将 getpost 值类型转换为整数、浮点数、布尔值或 null。

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


更新:虽然以上对于从查询字符串解析的所有 values 都是正确的,但对于 PHP 从一个查询字符串。假设以下网址:

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

现在,var_dump(array_keys($_GET)) 将为数字键返回什么?整数,而不是字符串:

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

这与 PHP 的 standard casting of array keys 一致:“包含有效十进制整数的字符串,除非数字前面有 + 号,否则将被强制转换为整数类型。”。然而,以下键转换不会发生:“浮点数也转换为整数,这意味着小数部分将被截断。”因为(如 Variables from External Sources 中所述):“点[external] 变量名中的空格被转换为下划线。”


外部变量类型转换:总结

  • 查询字符串的将始终是字符串,或数组(数组中的),字符串作为其最终标量值。
  • 查询字符串的 keys 将始终是 strings,但转换为 3,有符号负数:-3)除外>整数

【讨论】:

  • 很好的答案。感谢您的解释、示例和来源。 ?
  • 感谢@Markus 并感谢 GTS 提出这个问题,为两者投票:)
  • 似乎从未在 SO 上明确提出/回答过这个问题——很高兴答应。 :) 在外部输入数据类型的脚注中,我们有 AJAX 请求在 POST 请求正文中发送 JSON 数据的情况。这些不会出现在超全局变量中,需要通过php://input 访问。当json_decode()'d 时,此类数据将具有 JSON 已知的全部数据类型。这是一个包含更多细节的优秀问答:PHP “php://input” vs $_POST
  • 添加了关于发生在数字键上的 整数转换 的注释。那么,完整的结论是:查询字符串的总是字符串或带字符串的数组。查询字符串的 keys 将始终是字符串,但被转换为整数的整数除外。
【解决方案2】:

查询字符串本身是string,但其中的变量可能被解析为stringarray

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

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

【讨论】:

    【解决方案3】:

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

    【讨论】:

    • 可以有任何类型 ? ,举个例子怎么能包含一个对象?
    • @GNassro 我认为他不知道自己在说什么。 ?‍♂️
    • 我想输入potato(标量)。如何实现?!
    猜你喜欢
    • 2011-05-14
    • 2016-01-26
    • 1970-01-01
    • 1970-01-01
    • 2019-07-20
    • 2015-11-04
    • 1970-01-01
    • 1970-01-01
    • 2011-10-25
    相关资源
    最近更新 更多