PHP associative arrays - how to treat integer as string - php

I have a simple associative array.
$a = array("a"=>"b", "c"=>"d");
I want to check if the key "1" exists in the array, e.g.
isset($a["1"]);
This string is being treated as an integer, so that
echo $a["1"]; //prints "d"
How do I get it to treat it as a string?
I don't want to use array_key_exists or in_array because my benchmarking shows isset will be a lot faster.

It doesn't appear that you can do what you want to do. from http://us.php.net/manual/en/language.types.array.php:
A key may be either an integer or a string. If a key is the standard representation of an integer, it will be interpreted as such (i.e. "8" will be interpreted as 8, while "08" will be interpreted as "08").
You'll probably have to use Fosco's suggestion of prefixing all your keys with something. If you use the same prefix on every key, then it doesn't matter if you're parsing a text that might have words and numbers - put the same prefix on everything regardless.

isset($a["1"]) | isset($a[1]) ?
Or just isset($a[1])
Or even isset($a[intval(1)]) to be 1000% sure.

if echo $a['1'] prints d, then your array has more elements than you realize.
see var_dump($a) and print_r($a) functions to help you debug your code.

Related

Can a Query String Contain Anything Other than a String?

I was working on a project at my job and came upon this code:
$queryStringValue = $_GET['var'];
if ( is_string($queryStringValue) )
{
// Do something.
}
My question: Is calling is_string() to check if the query string value is a string completely unnecessary? By definition, "query string" leads me to believe the data type can only be a string, thus making a call to is_string() redundant.
Am I right, or are there times when a different data type can be passed in a query string?
Thank you for any insight!
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.
the query string itself is a string, but variables from it may be parsed as string or array:
url.com?var=123 => var is string
url.com?var[]=123&var[]=321 => var is an array
Yes it contains.
It can have any type you want, including array, integers, floats etc..

Can PHP arrays hold items of different type?

In other programming languages the definition of arrays is something which can hold similar kind of elements. For example if I declare something like int i[] it will store integers, but in PHP a single array seems to be holding strings and numbers together.
Will the number/integer be treated as string in such type of array in PHP?
According to the PHP manual you can indeed store heterogeneous types inside a PHP "array" - scroll down to example 3.
Note that even though the example is about keys being ints or strings, the values assigned in the example are also both ints and strings, demonstrating that it is possible to store heterogeneous types.
Be aware that in the case of different-typed keys there is automatic casting involved so you may have surprising results in the case where e.g. a string contains a valid decimal representation.
Yes. A PHP array can have multiple data types in it.
Also, you should note that arrays in PHP actually are represented in the form of key-value pairs, where the elements you will input into the array are values.
You can explicitly define keys too, when entering elements into the array, but when you don't, PHP will use indices starting from 0.
Example:
<?php
$array = array(
"foo" => "bar",
"bar" => "foo",
100 => -100,
-100 => 100,
);
var_dump($array);
?>
PHP will interpret as
array(4) {
["foo"]=>
string(3) "bar"
["bar"]=>
string(3) "foo"
[100]=>
int(-100)
[-100]=>
int(100)
}
Reference- http://php.net/manual/en/language.types.array.php
You can store anything you want in an array.
Will the number/integer be treated as string in such type of array in PHP?
Not upon storing it. However, when you use a value as such, PHP will convert it. The usage of a value determines its interpretation. (Attention, the key is converted upon storing, however, if it is considered numerical)
Not going to put oil on the fire of the PHP Arrays are no arrays here…
But yes, you can put different variable types (string, int, …) together in a PHP thing called Array.

PHP - why doesn't count() work like strlen() on a string?

A string is an array of characters, correct? If so, then why does count() not produce the same result as strlen() on a string?
Unless it is an object, count casts its argument to an array, and
count((array) "example")
= count(array("example"))
= 1
A string is an array of characters in C, C++ and Java. In PHP, it is not.
Remember that PHP is a very loose language, you can probobly get a character from a PHP string with the []-selector, but it still dosn't make it an array.
count() counts the number of entries in an Array.
$test = array(1,2,3);
echo count($test);
Output: 3
Why would you want to use count() on a string when strlen() can do that? Are you not sure if your input is a string or an array? Then use is_array() to check that.
How exactly a string is being handled internally by a specific programming language, must not necessarily mean you can handle it equally to therefore "related" data types. What you describe may be possible in plain C. However PHP is not C and so is not following the same characteristics.
Strings are just a series of charactes, and count only counts number of elements in an array.
using $string[$index]; its just a shortcut kinda of thing to help you find Nth character,
you could use count(explode('',$string)); which presumably is what strlen does
so lesson for today is
count == array length
strlen == string length
count gets the number of elements in an array, srtlen gets the length of a string. This is in the docs:
http://php.net/manual/en/function.strlen.php
count is more preferabaly user for array value count
strlen its count only the no of char in str.....

php associative array values always set?

$test['test'] = 'test';
if(isset($test['test']['x']))
return $test['test']['x'];
This statement returns the first character of the string in $test['test'] (in this case 't'), no matter what is specified as dimension 2.
I can't wrap my head around this behavior. I use isset() all the time. Please advise.
This happens because you're not indexing an array, you're indexing a string. Strings are not arrays in PHP. They happen to share a concept of indexes with arrays, but are really character sequences even though there is no distinct char data type in PHP.
In this case, since strings are only indexed numerically, 'x' is being converted into an integer, which results in 0. So PHP is looking for $test['test'][0]. Additionally $test is only a single-dimensional array, assuming 'test' is the only key inside.
Not really relevant to your question, but if you try something like this you should get 'e', because when converting '1x' to an integer, PHP drops anything that isn't a digit and everything after it:
// This actually returns $test['test'][1]
return $test['test']['1x'];
If you're looking for a second dimension of the $test array, $test['test'] itself needs to be an array. This will work as expected:
$test['test'] = array('x' => 'test');
if (isset($test['test']['x']))
return $test['test']['x'];
Of course, if your array potentially contains NULL values, or you want to make sure you're checking an array, use array_key_exists() instead of isset() as sirlancelot suggests. It's sliiiiightly slower, but doesn't trip on NULL values or other indexable types such as strings and objects.
Use array_key_exists for testing array keys.
It's returning 't' because all strings can be treated as arrays and 'x' will evaluate to 0 which is the first letter/value in the variable.

What does PHP do with strings to numbers when used as array keys?

I'm trying to create an associative array like this:
$key = '0'
$arr = array((string)$key=>$value);
Later, checking is_string(array_keys($arr)[0]) returns false.
The casting didn't help, using " instead of ' didn't help.
Am I doing something wrong, or is there another way around this, or is it impossible to have a numeric string array key?
In PHP, strings are converted to numbers when used as index, if they are purely numeric. When assigning it as an array key, it is converted to an integer, and same on access, you can use $arr['0'] to access the key 0.
PHP handles indexes of arrays in a bit more special way than just assigning to variables. Rules are clearly written in manual. Here is excerpt regarding your question.
A key may be either an integer or a string. If a key is the standard representation of an integer, it will be interpreted as such (i.e. "8" will be interpreted as 8, while "08" will be interpreted as "08"). Floats in key are truncated to integer. The indexed and associative array types are the same type in PHP, which can both contain integer and string indices.
Quote from
http://php.net/manual/en/language.types.array.php
Set as Integer, but Accessible as String...
It appears that the keys will be assined the type of "integer" unless something about their value prevents the assignment. You are able to access them as strings, as I demonstrate with the gettype() line.
$array = array("0" => "Jonathan", "1" => "Sampson");
$keys = array_keys($array);
print gettype((string)$keys[0]); // string
when assigning values to a variable that could possibly be interpreted as multiple different types NEVER rely on them to actually be a specific type.

Categories