Arrays in PHP, or to be precise, Collections in PHP

PHP has some serious structural problems. It's code is a mess of functions, function names are too similar to the old C functions ("strstr", "strlen", etcetera), but by far, the most confusing element of PHP (at first) are its Arrays.

For any developer (except PHP only ones), an array is a list of elements, placed consecutively in memory, and separated with an index. For example, a simple char array of 4 elements would be something like this:

typical array

Does PHP have arrays? Yes and no. PHP arrays are what in every other language we call key-value collections; A list of elements, but instead of separated by an index, distributed as in a table where a key index returns a specific value:

key-value array

WTF? Then why not calling it key-value collection?! Only PHP creators probably know... anyway, once you know this difference, you will avoid tons of coding problems and errors handling PHP arrays. The only hint comes from the fact that some of the PHP doc calls them "associative arrays" (I will come to this later).

As with the rest of PHP, there are lots of functions to operate with arrays, but messed up and unordered (inconsistent even with the naming xD). Another sympthom of how much PHP needs "purification" of it's structure into an object oriented one (cleaning along the way tons of crap code and wrong coding practices).

But not all is lost; as a friend pointed to me, there is a SPL extension to correctly iterate arrays in a human and correct way, the ArrayIterator class.

One thing to always remember is that PHP allows accessing via "indexes" an array, but NOTHING assures you that a given index position will contain a value. Check this example:

key-value array 2

If you try to do a typical for loop your code will fail, because the only valid "index" values are 0,2,4,8, all the other positions are "empty" (in fact they don't even exist).

So you must forget using for loops, using in exchange foreach loops. Foreach loops work much like C# ones, but with the "magic" of being untyped (so relies on the developer trying to access the correct object).

foreach ($givenUsersList as $userIndex => $userName)
{
$this->myUserList += array($userName);
}

This code loops through all users found on $givenUsersList, avoiding us the problem of not knowing the indexes.

Associative arrays can be very useful too, produce clean code (as clean as can be being untyped, that is :P) and allow to have some degree of order in PHP (apart from nice tricks manipulating data). Let's see another example:

public class Roles
{

const GUEST = 0;
const USER = 1;
const MODERATOR = 2;
const ADMIN = 4;

private static $availableUserRoles =
array(
self::GUEST => 'Guest',
self::USER => 'Registered user',
self::MODERATOR => 'Moderator',
self::ADMIN => 'Administrator',
);

public function GetUserRoles($user)
{
$roles = array();
foreach(self::$availableUserRoles as $roleIndex => $roleName)
{
if ($user->IsInRole($roleIndex))
{
$roles += array(roleName);
}
}
return $roles;
}

[...]
}

What this code does? First, it defines some constants (the available roles for a ficticious user database); Then, defines a list of the available user roles, adding a description for each one, so the constants act like keys/indexes for that static associative array.

And finally, the GetUserRoles() function loops through all available roles, checking if the given user has each; If so, it adds its's description to a simple array, and finally returns that array containing all the descriptions of the roles the user is in.

Pretty dumb function, but shows how associative arrays work, how can we take advantage of foreach loops (if instead of just a role name we had a role object, we could have "extracted" it forgetting about indexes), how to add elements to a new array (once again, forget the typical way, PHP uses a Javascript like syntax of adding elements to arrays), and even how to use constants as array keys.

I have not touched any PHP array function, I'll leave to you checking what you can do with them (which is a lot). Just don't panic at first with the terrible syntax! :D

Comments?

Posted by Kartones on 2009-05-03