Per PHP manual on Variables From External Sources under "Determining variable types":
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.
Again, in the manual's FAQ: Arrays in HTML Form, we read on arrays:
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[]" /> ...
This would turn into a query string ?MyArray[]=foo&MyArray[]=bar etc., available as $_GET['MyArray'][0] and $_GET['MyArray'][1]. You can also use named keys; the query ?var[x]=one&var[y]=two would result in the associative array $_GET['var] = ['x' => 'one', 'y' => 'two']; and ?var[x][]=deep would become $_GET['var']['x'] = ['deep'], etc.
In addition, the manual for $_GET notes the following:
Note:
The GET variables are passed through urldecode().
Then, see the signature of urldecode:
urldecode ( string $str ) : string
In other words, the function used for preprocessing $_GET values accepts a string and returns a string. Evidently, when there's an array incoming, it will apply urldecode to each string value of that array instead. (If someone cares to find the PHP source code section responsible for generating $_GET, please share the link, will include it here.)
Note that an empty value, e.g. in ?foo&bar=1, will not result in [foo] NULL, but rather in [foo] string(0) "", in other words a zero-length string. Again, we get [bar] string(1) "1". There's no type-casting of get or post values into integers, floats, booleans or null.
In conclusion, the possible datatypes received in $_GET are string and array (of strings; or further arrays; with the final, scalar "leaves" being strings). Of course, if you explicitly declare $_GET['foo'] = null or $_GET['bar'] = 1 in your PHP code, then there will be integers and nulls. The above applies to variables parsed by PHP from external sources.
Update: While the above is true for all the values parsed from the query string, things are different for the keys PHP extracts from a query string. Suppose the following URL:
test.php?101=foo&202=bar&dev=ops
Now, what will var_dump(array_keys($_GET)) return for the numeric keys? Integers, not strings:
array(3) {
[0] · int(101)
[1] · int(202)
[2] · string(3) "dev"
}
This is in line with PHP's 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): "Dots and spaces in [external] variable names are converted to underscores."
External Variable Typecasting: Summary
- A query string's values will always be strings, or arrays (of arrays) with strings as their final scalar values.
- A query string's keys will always be strings, excepting whole numbers (unsigned positive:
3, signed negative: -3) that are cast as integers instead.