Perl vs. PHP - Datatypes[arrays|lists|hash|map]

I've made a few friends recently who are ultra Perl geeks (Yes, you know who you are. Andy, Liz and Brian!) and they are rubbing off on me. I learned Perl a little bit, about 6 years ago when I first started web programming but I didn't know any Perl programmers so I had nobody to pester with questions. I always said that Perl was cryptic so Perl Elitists could show off their l33t ski11s. But I've found it's not all that bad…

I know PHP so well, that it helps my understanding to compare Perl to php (Don't flame me Perl folks! I'm not promoting one over the other, just comparing and contrasting).

First, some general concepts:
array (or list) -- a collection of numerical keys and values. I just call this an array.
hash (or map) -- a collection of string keys and values. Normally I call this an associative array, but I think I might start calling it the hash that it is. J

PHP
In php both are essentially the same datatype. The collections are defined as such:

$booksArray = array();
$booksArray = array("Professional PHP Programming", "Programming Perl");

$booksHash = array();
$booksHash = array("php" => "Professional PHP Programming", "Perl" => "Programming Perl");

// In most cases, I find this more readable and easier to update,
// although a bit more typing. But that’s what cut and paste is for!
$booksArray = array();
$booksArray[] = "Professional PHP Programming";
$booksArray[] = "Programming Perl";

$booksHash = array();
$booksHash['php'] = "Professional PHP Programming";
$booksHash['perl'] = "Programming Perl"; 

Unless you have the hash indexes defined as constants, use single quotes around the string literal for the index. You can also use a variable containing the index such as $booksHash[$favoriteBook] which does not need quotes Thank you -- The Management

The first is indexed by numbers, the second by strings. In the second method of declaring the bookArray, when empty brackets are used the index is automagically (just added this word to my MS Word dictionary so it will stop showing up with an underline! NYAH!) set to the next available numerical index. To print the name of the Perl book I'm currently reading, these would be accessed as such:

print "Currently reading $booksArray[1]";

print "Currently reading $booksHash['perl']"; 

You can even mix the types in one array which has caused me some problems. Sometimes I thought it was hash and I'm trying to access it as an array. If you use mysql_fetch_array you can specify if you want the results returned as an array, hash or both (default). I almost always use the string indexes.

$booksMixed = array("php" => "Professional PHP Programming",  1 => "Programming Perl"); 

Acky. Don't mix unless you have good reason to so. The mysql_fetch_array could be considered a good example,because its returning both to be more flexible. According to the PHP manual, mysql_fetch_array "is not significantly slower" then mysql_fetch_row which returns an array with numerical indexes.

Perl
Perl has a separate notation for arrays and hashes. The same array/hash above would be defined as such

my @booksArray = ('Professional PHP Programming', 'Programming Perl');

my %booksHash = ('php' => 'Professional PHP Programming', 'perl' => 'Programming Perl');

my @booksArray;
$booksArray[0] = 'Profesional PHP';
$booksArray[1] = 'Programming Perl';

my %booksHash;
// note use of { } aka “up moustache”, “down moustache” by my husband 
$booksHash{'php'} = 'Professional PHP Programming'; 
$booksHash{'perl'} = 'Programming Perl'; 

When you define an array or hash, you use the appropriate symbol. @ for arrays, % for hashes. Then to access one value, you use the "normal" $ to access one value. At first I was like, huh? Then as I thought about it, $ indicates a scalar value. When you are addressing one value in an array/hash you are accessing a scalar. So, it makes sense now.

In Perl you can make an array and convert it to a hash. I don't believe you can do something like this in PHP.

my @booksArray2 = ('php', 'Professional PHP Programming', 'Perl', 'Programming Perl');
my %booksHash2 = @booksArray2;

PHP's array / hash are essentially an "ordered map" according to the documentation with either integers or strings for an index all wrapped up in one datatype, so in most cases the functions available for PHP would work with either. This can cause some problems when you aren't sure how the item is indexed. Perl has separate implementations for arrays and hashes.

Note: PHP orders the associative array in the order it was defined. Perl's hash is not guaranteed to remain in the same order as you defined it.

Note2: In Perl, unquoted string literals are considered "barewords" … if you use "perl -w" in your shebang (i.e. #!/user/bin/perl -w) line it will alert you when it finds barewords. In PHP, use error_reporting(E_ALL) and you will be notified when you have unquoted string literal index.

I think I finally got Perl arrays and hashes down. I was always baffled with the $, % and @ [] {} symbols and when, where and why to use what and also why sometimes indexes had strings and sometimes not! I also have a better understanding of how arrays in php.

More Info: