I Don’t Like PHP’s extract() Function

When looking at PHP code that I’m not familiar with a common task is back tracking what operations were done to a variable for it to end up in it’s current state. More often than not this means looking through dozens of lines of code in a function or method. First on my list is often figuring out how a variable came to be in the function in the first place. Was it a global, function argument, class variable or a return value from another function? Knowing this helps me determine if I need to start looking outside the function.

Then there are the times that I can’t find any reference to where a variable came from at all. It’s just suddenly being used. One way that happens is through the extract function. You pass it an array and it injects the array items into the current symbol table. This makes backtracking variable information a real pain. Here’s a basic example to give you an idea:

[sourcecode language=”php”]
function say_hello( $person_info ) {
extract( $person_info );

// … imagine another 75 lines of code here

print "Hello {$name}!n";

If I was looking to find out more about the $name variable there’s no obvious information. A simple search for the variable name shows it only ever being used once. No hint as to where it came from or how it got there in the first place. It isn’t until you catch the extract() call that you realize that it came from the $person_info function argument, but there’s nothing that an easy search operation will do to tell you that. If there is more than one extract() call in the function then you have to start adding debug code and running it just to determine which extract() created the variable.

I like to be able to easily tell where variables came from. Operations that magically insert variables into the current symbol table make that task a lot harder. And there’s no reason that you’d ever have to use extract(), it’s purely for convenience. A convenience that can make life harder for others and for yourself when debugging code you haven’t looked at in years.

There’s a companion function to extract() called compact, which does the opposite. It takes a list of variable names and creates an array. I don’t have any problem with this because it’s not hiding where the data for the new array came from.