Log in

View Full Version : What's Allowed for an Array Key?



jscheuer1
07-15-2011, 06:28 AM
Title pretty much says it all. I've been using this to sort image files by their timestamps on wamp and it works fine:


<?php
function returnimages(){
$dirname = isset($_GET['dir'])? $_GET['dir'] : '.';
chdir($dirname);
$pattern = '#\.(jpg|jpeg|png|gif|bmp)$#i';
$files = array();
if($handle = opendir('.')){
while(false !== ($file = readdir($handle))){
if(preg_match($pattern, $file)){
$filedate = filemtime($file);
$files[$file] = $filedate;
}
}
closedir($handle);
}
arsort($files, SORT_NUMERIC);
$files = array_keys($files);
echo " ['$dirname/" . implode("'],\n ['$dirname/", $files) . "']\n";
}
returnimages();
?>

Notice particularly:


$files[$file] = $filedate;

I do it that way because no two files in the same folder will have the same filename, but they might have the same timestamp. If they do and I make the stamp the key, one entry will overwrite the other.

Anyways, I then have keys like some.jpg, here's a print_r of a typical array this produces (before the arsort):


Array
(
[image1.jpg] => 1150840114
[image2.jpg] => 1192236872
[image3.jpg] => 1192236862
[image4.jpg] => 1150840110
[image5.jpg] => 1192236848
[thumb_image1.jpg] => 1190861632
[thumb_image2.jpg] => 1190384470
[thumb_image3.jpg] => 1190384470
[thumb_image4.jpg] => 1190384470
[thumb_image5.jpg] => 1190384472
)

I was a little worried about the . - it's a big no-no for object keys in javascript unless you stringify the key by quoting it. But PHP seems fine with it. Is there anything that could be in a PHP fetched filename that could result in an invalid key here?

james438
07-15-2011, 08:32 AM
array keys can be either an integer or a string. Floats are truncated to an integer.

The following is allowed:

<?php
$a=array();
$a[s]=3;
print_r($a);
?>
or

<?php
$a=array();
$a["\'\\\"s"]=3;
print_r($a);
?>
The following will cause an error:

<?php
$a=array();
$a[\"]=3;
print_r($a);
?>

You can read more here (http://php.net/manual/en/language.types.array.php)

The period is fine and so are a lot of other characters, but I tend to stick to lowercase letters and numbers and if I have to I use capitals, but I'm going on a tangent.

djr33
07-15-2011, 01:45 PM
John, you have made it a string. You're using a variable containing the filename which is a string. So using the variable $file is fine then.

I've never had problems with anything as an array key, as long as you assign it in a way that makes sense-- using a variable like you are, for example, or carefully using strings.

I've never tried anything really odd like using an array as the key, but aside from that, I don't think you need to worry.

The only time when this might be a problem is if it's hard to escape manually (this is automatic when it's in a variable) and you might need to later refer to it manually. For that reason, I also try to use only lowercase and numbers, unless it's a fully automated system.

As far as I know there are no disallowed characters, just some that end up hard to type in (due to complicated escaping).
Note that there are other ways to access arrays/keys, such as the following:
$string = "My value is {$array['test']}.";
I never use that, and I'm not sure it's the right syntax, but it exists and in that situation obviously you could get into very complicated escaping.


The only other problem you might run into is any sort of auto-generated code, but that's rare and usually a bad idea for security reasons in PHP. On the other hand, it is not that rare to generate Javascript using PHP, so if you intend to use these keys as unique identifiers in the JS as well then you should choose something that is compatible there.

traq
07-15-2011, 02:23 PM
array keys have to be strings or integers - other numeric values are converted to integers - you specifically can't use arrays or objects.

one of the examples james gave above - $a[s]=3 - is something that works, but only because of how php handles errors. if your key is a string, it should be quoted. if not, php thinks it refers to a defined constant. when it finds no such constant, it falls back to treating it as a string.

of course, if there is a constant named a in your script, then you'll have all kinds of other confusion going on.

jscheuer1
07-15-2011, 02:41 PM
I'm guessing I'm alright then because $file will always be a string ending in one of the image file extensions from the $pattern filter. I'm just wondering now if a filename/key like:

1.01.jpg

might give it trouble, but I think some browsers would have a problem with that anyway.

What got me concerned in the first place is that in javascript, as long as only certain characters are used, a property name of an object (the closest thing javascript has to an associative array key), is automatically type converted to a string. If it does contain a . or anything other than the underscore, letters or numbers, or if it begins with a number, it must be quoted in certain syntaxes where, if it follows the rules it does not.

traq
07-15-2011, 03:34 PM
since you're assigning it via a variable ( $file ), you shouldn't have any problems with quoting anyway.