In 2012, the much loved and much missed WordPress developer Alex Mills raised a WordPress Trac ticket…
extract()is a terrible function that makes code harder to debug and harder to understand. We should discourage it’s use and remove all of our uses of it.
As a result, use of the PHP functions was removed from WordPress and was added to the coding standards (which, in turn, made it into the WordPress sniffs for PHPCS).
But why, and what should we do instead?
For a better understanding, Alex linked to an article by another developer which, sadly, is no longer available. However, use of the internet archive, means that we can recover it…
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:
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 hard. 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.
Joseph Scott, 2009
Some people argue that extract shouldn’t be used because it’s a security risk – essentially, anything could be passed in that would be parsed. I don’t get this argument, and most PHP developers don’t (it remains in use as a PHP command with no such concerns – pretty much any PHP command could be used insecurely, if you try). However, there are 2 reasons why we should avoid it…
- It prevents accidental issues
extractis, more often than not, used for shortcodes. The shortcode function passes in an array of possible parameters and you useextractto convert each to an individual variable. What if you use a parameter that’s named the same as a variable already in use within that function? Or something that clashes with a reserved variable name? Basically, you’re opening yourself up to the user accidentally causing catastrophic errors in your code.
- It makes the code easier to understand
If you pass an array of parameters into a function and then useextractto convert them to variables, the first time you see a variable in use, they’ll have been no initialisation and could cause to confusion as to how it’s even been defined.extractdoes its job, but does so whilst obfuscating what’s going on.
Manually assigning each expected array element to a variable allows anybody reading the code to understand the source of the variable much more clearly. This is the point that Joseph was making in his blog post.


Leave a Reply