Scope surprises in PHP: The joy of debugging

Scope is the variable and function visibility that a certain portion of the program has. For example, let’s say that we declare a variable inside of a function. Other functions will not have access to that variable.

<?php

function hello() {
    $name = "Dino";
    echo "Hello " . $name; // has access
}

function bye() {
    echo "Bye " . $name; // Doesn't have access
}

That variable ($name) has local scope to the function where it was created. Variables can have global scope and be accessed anywhere (not always immediately). Those variables are normally defined outside of the function.

<?php

$x = "Hey";

function hey() {
  echo "Hey";
}

echo $x; // works well

However, in PHP, calling a variable that has global scope inside of a function is not immediately permissible since the function will look for a local variable.

<?php

$x = "Hey";

function hey() {
  echo $x; // Doesn't work since it's looking for a local var
}

use keyword

So how do we get access to that variable? Remember our use keyword? If not, take a look at it here.

https://blog.devgenius.io/php-7-x-p40-use-keyword-37d8e7df9138

The example that we used in that article is:

<?php

$name = "Dino";

$hello = function() use($name) {
    echo $name;
};

echo $name; // Dino

$name = "Harrison";

echo $name; // Harrison
$hello();   // Dino

This is a good example of how scope works. But, we changed the value of $name to Harrison on line 11, so why is Dino displayed?

use gets the value of the global variable when the function is defined and global will get the value of the variable when the function is called

As PHP was reading the program, it defined the function on line 5 and copied the value of the global variable so that it can use it. It was later, on line 14, that the closure was called. The definition portion has already been performed and the value was solidified inside of the closure. That is why you get the value Dino instead of Harrison.

Let’s look at another example of that article. This time, we’re using both an argument and passing the global variable

<?php

$name1 = "Dino";
$name2 = "Harrison";

$closure = function($greeting) use($name1) {
    global $name2;
    
    echo $greeting . " " . $name1 . " and " . $name2 . "<br>";
};

$closure("Hello there");

$name1 = "Amy";
$name2 = "Steve";

$closure("Hi there");

So what do we get?

Hello there Dino and Harrison
Hi there Dino and Steve

Even though both of the global variables were changed, only $name2 was updated as far the anonymous function is concerned, since use gets the value of the global variable when the function is defined, and global gets the value of the variable when the function is called.

global keyword

With the global keyword, we can get around the use keyword inconsistencies. You could want that format, but if you don’t, global is the way to go.

<?php

$a = 10;
$b = 20;

function sum()
{
    global $a, $b;

    $b = $a + $b;
}

sum();
var_dump($a);
var_dump($b);

$a = 0;
$b = 0;
sum();
var_dump($a);
var_dump($b);

What happens here?

  1. PHP assigns 10 to $a and 20 to $b.
  2. A function is declared called sum and we set $a and $b as global variables within the function.
  3. The sum function is called.
  4. Variables $a and $b are added and the value is assigned back to $b.
  5. $b now equals 30.
  6. We check the value of $a and $b. They are 10 and 30.
  7. $a and $b are now set to 0.
  8. The sum function is called again.
  9. Once we check the values of $a and $b, the value is 0 for both, which is what we normally think would happen.

We don’t have to use the global keyword to make the variables global. We can use the $GLOBALS built in array. Whenever you define a global variable, the name of the variable is set as the key inside of the $GLOBALS array.

<?php

function sum()
{
    $GLOBALS['b'] = $GLOBALS['a'] + $GLOBALS['b'];
}

CLASS WIZARDRY IN A NUTSHELL.

PHP – P106: BUILT IN FUNCTIONS: _INVOKE, _TOSTRING, _GET, AND _SET

PHP’s magic methods, including __invoke for object invocation, __toString for string conversion, and __get and __set for dynamic property handling, elevate class flexibility and clarity.

Scope surprises in PHP: The joy of debugging

PHP – P107: scope quirks

Scope defines variable visibility in a program. Variables in functions are isolated; others can’t access them.

BRIDGING THE GAP BETWEEN DATA AND CODE

PHP – P108: JSON

JSON, or JavaScript Object Notation, is a way to store and transport data. Whether we’re generating JSON objects to be sent from the server or accepting JSON objects from the client, we need to understand the JSON format.

Leave a Reply