A numeric string as array key in PHP
No; no it's not:
From the manual:
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").
Addendum
Because of the comments below, I thought it would be fun to point out that the behaviour is similar but not identical to JavaScript object keys.
foo = { '10' : 'bar' };
foo['10']; // "bar"
foo[10]; // "bar"
foo[012]; // "bar"
foo['012']; // undefined!
How can I force PHP to use strings for array keys?
EDIT:
I assumed that if they are integers, I
can't reorder them without changing
the key (which is significant in this
example). However, if they were
strings, I can reorder them how they
like as the index shouldn't be
interpreted to have any special
meaning. Anyway, see my question
update for how I did it (I went down a
different route).
Actually they dont have to be in numeric order...
array(208=>'a', 0=> 'b', 99=>'c');
Is perfectly valid if youre assigning them manually. Though i agree the integer keys might be misinterpreted as having a sequential meaning by someone although you would think if they were in a non-numeric order it would be evident they werent. That said i think since you had the leeway to change the code as you updated that is the better approach.
Probably not the most efficient way but easy as pie:
$keys = array_keys($data);
$values = array_values($data);
$stringKeys = array_map('strval', $keys);
$data = array_combine($stringKeys, $values);
//sort your data
PHP array with numeric keys as string can't be used
So, I haven't seen any other answers touch upon this, but @xdazz came close.
Let's start our environment, $obj
equals the object notation of a decoded string:
php > $obj = json_decode('{"1":1,"2":2}');
php > print_r($obj);
stdClass Object
(
[1] => 1
[2] => 2
)
php > var_dump( $obj );
object(stdClass)#1 (2) {
["1"]=>
int(1)
["2"]=>
int(2)
}
If you want to access the strings, we know the following will fail:
php > echo $obj->1;
Parse error: parse error, expecting `T_STRING' or `T_VARIABLE' or `'{'' or `'$'' in php shell code on line 1
Accessing the object variables
You can access it like so:
php > echo $obj->{1};
1
Which is the same as saying:
php > echo $obj->{'1'};
1
Accessing the array variables
The issue with arrays is that the following return blank, which is the issue with typecasting.
php > echo $obj[1];
php >
If you typecast it back, the object is once again accessible:
php > $obj = (object) $obj;
php > echo $obj->{1};
1
Here is a function which will automate the above for you:
function array_key($array, $key){
$obj = (object) $array;
return $obj->{$key};
}
Example usage:
php > $obj = (array) $obj;
php > echo array_key($obj, 1);
1
php > echo array_key($obj, 2);
2
Convert array keys from numeric string to integer
Propably simplest solution:
$keys = array_keys($data);
$values = array_values($data);
$intKeys = array_map('intval', $keys);
$newData = array_combine($intKeys, $values);
Update:
With checking of key type:
$keys = array_keys($data);
if ($keys === array_filter($keys, 'is_numeric')) {
$data = array_combine(
array_map('intval', $keys),
array_values($data)
);
}
transform integer array keys to string array keys
This is not possible.
PHP will internally detect that it's a number (even in quotes) and convert it back. If you notice: the original array and the end one are identical. That's because PHP's automatically casting it for you.
The only way to prevent that is to not use numbers. You could prefix the numbers:
$a = [
"_0" => "a",
"_1" => "b",
]
But in general, you don't want to do that. And as you said, it's not even required by the code you thought it was.
And if you are wondering why it casts for you. I have one response. Because:
PHP: setting a number as key in associative array
Try
echo json_encode((object)$jsonobj);
target numeric keys only in array
Here's a complicated method using array_filter()
to return the numeric keys then iterate over them.
// $input_array is your original array with numeric and string keys
// array_filter() returns an array of the numeric keys
// Use an anonymous function if logic beyond a simple built-in filtering function is needed
$numerickeys = array_filter(array_keys($input_array), function($k) {return is_int($k);});
// But in this simple case where the filter function is a plain
// built-in function requiring one argument, it can be passed as a string:
// Really, this is all that's needed:
$numerickeys = array_filter(array_keys($input_array), 'is_int');
foreach ($numerickeys as $key) {
// do something with $input_array[$key']
}
It's much easier though to just foreach over everything:
foreach ($input_array as $key => $val) {
if (is_int($key)) {
// do stuff
}
}
Edit Misread original post and thought I saw "numeric" rather than "integer" keys. Updated to use is_int()
rather than is_numeric()
.
Related Topics
How to Check Whether an Array Is Empty Using PHP
Global or Singleton For Database Connection
How to Get the Base Url With PHP
Submitting a Multidimensional Array Via Post With PHP
PHP: Custom Error Handler - Handling Parse & Fatal Errors
How to Upload Multiple Files Using PHP, Jquery and Ajax
Are PHP Include Paths Relative to the File or the Calling Code
File_Get_Contents() Breaks Up Utf-8 Characters
How to Check Uploaded File Type in PHP
PHP: Producing Relative Date/Time from Timestamps
PHP: How to Get All Possible Combinations of 1D Array
PHP: Replace Umlauts With Closest 7-Bit Ascii Equivalent in an Utf-8 String
PHP, How to Catch a Division by Zero
Get Name of Caller Function in PHP