3

From what I understand, extract() takes in an array as an argument and creates variables whose names are exactly identical to the keys in this array and whose values are the values associated with these keys respectively.

For example, passing in ['message' => 'this is a message!'], creates a variable named $message with the value 'this is a message!'.

I'm not gonna ask how it converts keys to variable names, but as far as I know, variables in PHP are local if they're declared inside a function.

I just wanna make sure, does extract() declare these variables as global variables? (because I can't think of a reason why they're still in scope after this function returns except that it declares them as global variables). Is that even possible in PHP?

Also, is it a good practice to use a function like this? I mean, if we already have these values stored in an array, why bother extracting them in new separate variables? If the answer to this question is because, in apology.php for example, we hard-coded the variable name $message, well, we could simply hard-code $values['message']. So what's the deal here?

2 Answers 2

3

I just wanna make sure, does extract() declare these variables as global variables?

Not necessarily. The description of extract() reads, "Import variables from an array into the current symbol table." In other words, the extracted variables will be set in the current scope (at the point where extract() is called). This means that if you call extract() from inside a user-defined function, the extracted variables will go out of scope once you return from the function. This is pretty easy to test:

<?php
    function foo($bar)
    {
        extract($bar);  // Will key-value pairs from $bar turn into globals?
        return 0;
    }

    $myarray = array(
        "a" => "cs",
        "b" => 50
    );

    foo($myarray);

    echo "In global scope:<br>";
    echo "\$a: ", ((isset($a)) ? "SET" : "NOT SET"), "<br>";
    echo "\$b: ", ((isset($b)) ? "SET" : "NOT SET"), "<br>";
?>

You can check the result quickly at http://phpfiddle.org/ if you like. You should see the output:

In global scope:
$a: NOT SET
$b: NOT SET

As for whether it's possible to create global variables from a local scope - sure! Just use the GLOBALS supervariable. Here's an example:

<?php
    function foo()
    {
        $GLOBALS["a"] = 5;
    }

    echo "\$a is ", isset($a) ? "" : "not ", "set<br>";

    echo "calling foo()<br>";
    foo();

    echo "\$a is ", isset($a) ? "" : "not ", "set<br>";
?>

Which outputs:

$a is not set
calling foo()
$a is set

These are tools that can make some tricks a little easier, but they're also controversial in that many programmers see global variables and extract() as code smells in PHP - warning signs that the code might not be written in the best way. While it's very important to be aware of these concepts and tools, novice programmers are often advised to avoid using them whenever possible.

3
  • Exactly, and I'm asking how are variables set at the point where extract() is called if these variables are created inside extract() itself and not inside the function that's calling it (e.g., foo() in this case)? In other words, how are these variables accessible from foo()?
    – kzidane
    Aug 8, 2014 at 16:01
  • @Kareem I haven't had any luck finding the implementation of extract() to answer that. It's probably done in C. Try asking the implementation question on SO, there are a lot more experts there.
    – Air
    Aug 8, 2014 at 17:04
  • 1
    Believe it or not, I could fully understand the answer after I had developed some skills that enabled me to get a sense of the idea of importing variables from an array to the current symbol table. Thanks!
    – kzidane
    Dec 29, 2014 at 8:12
0

Global variables in PHP

PHP has global variables, but to access them the keyword global has to be used:

$my_global = 'hi there';

// won't work, will try to echo the local variable $my_global which is undeclared
function show_my_global() {
    echo $my_global;
}

// will work, will echo the contents of the global variable
function show_my_global() {
    global $my_global;
    echo $my_global;
}

Simplifying the view for non programmers

Within the render function the extract function is used to make it easier for designers to work with templates. They don't have to know the concept of arrays, just of printing a variable. A "view" can be altered by someone with very basic knowledge of PHP.

<h1><?= $title ?></h1>
<p><?= $body ?></p>
<a><?= $link_to_previous ?></a>

is easier and cleaner than:

<h1><?php echo $params['title'] ?></h1>
<p><?php echo $params['body'] ?></p>
<a><?php echo $params['link_to_previous'] ?></a>

By using this simple approach, designing the view can be done by people with very little or no programming knowledge. In reality dedicated designers are often used to design output and these people might not be programmers.

scope of variables extracted with Extract function

The extract functions extracts to the current "symbol table". I suspect when extract is within functions, the variables are going to be local to the function.

1
  • I know the point about global variables. I was just asking if it's possible to create global variables inside a function. From @AirThomas' answer, it appears that this is not the way that was followed though.
    – kzidane
    Aug 8, 2014 at 15:59

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .