PHP programming tutorial

  • Pages




  • Menu

7. Scope

Scope defines which variables are available for use in within each segment of code. By default variables exist in the global scope and if you include another file, the global scopes are shared. Here’s an example of a program that shares variables into another file:

In a file called php-7-1.php:

 
<?php
	$str = 'Hello world';
	include 'php-7-1-inc.php';
?>
 

In a file called php-7-1-inc.php:

 
<?php
	echo $str;
?>
 

When you test php-7-1.php you get the expected ‘Hello World’ output.

When you define a function, a new local function scope is created and none of the global variables are available within it. A simple example of that:

 
<?php
	$str = 'Hello world';
	function say_hi() {
		echo $str;
	}
	say_hi();
?>
 

This program will output nothing because the global $str variable is not available within the function scope. You can bring global variables into the local function scope with the global keyword like this:

 
<?php
	$str = 'Hello world';
	function say_hi() {
		global $str;
		echo $str;
	}
	say_hi();
?>
 

This example will now produce ‘Hello world’ because the global variable has been brought into the local function scope.

You can also access globals from function scope with the $GLOBALS superglobal array, here’s an example:

 
<?php
	$foo = 'bar';
	$snork = 'snark';
	$oogle = 'foogle';
	$zork = 'zark';
	function output_globals() {
		echo "foo: " . $GLOBALS['foo'] . "<br />\n";
		echo "snork: " . $GLOBALS['snork'] . "<br />\n";
		echo "oogle: " . $GLOBALS['oogle'] . "<br />\n";
		echo "zork: " . $GLOBALS['zork'] . "<br />\n";
 
	}
	output_globals();
?>
 

The advantage of doing it this way is that you can still use $foo in your function whilst referring to a different $foo in global namespace. Here’s a simple example of that:

 
<?php
	function output_foo() {
		$foo = 'zark';
		echo "Function local foo: " . $foo . "<br />\n";
		echo "Global foo: " . $GLOBALS['foo'] . "<br />\n";
	}
	$foo = 'bar';
	output_foo();
?>
 

The times when your global variable names and your function local variable names clash are normally not too common so the best approach is normally to bring the global into function local scope via the global keyword rather than using the $GLOBALS superglobal.

After each function is exectued and returns, all the variables in its local scope are lost. Here’s an example:

 
<?php
	function add_one() {
		$c = 0;
		$c++;
		echo $c . "<br />\n";
	}
	add_one();
	add_one();
?>
 

This script will never manage to increment $c above the number 1, it’s never incremented higher than that because $c is reset at the beginning of each function call. You need a way to initialise a variable once and then have it persist between separate calls to the function. This is achieved via the static keyword, as in this example:

 
<?php
	function add_one() {
		static $c = 0;
		$c++;
		echo $c . "<br />\n";
	}
	add_one();
	add_one();
?>
 

This script will now print the number 1 followed by the number 2, and would continue to increment after each call to add_one().

You can initialise a static variable with a string like in the following example, but not with the result of a function call or expression:

 
<?php
	function add_clap() {
		static $clap = 'clapping... ';
		$clap .= 'clap ';
		echo $clap . "<br />\n";
	}
	add_clap();
	add_clap();
	add_clap();
?>
 

The output from this script will be:

 
clapping... clap <br />
clapping... clap clap <br />
clapping... clap clap clap <br />
 

But if you try to do either of the following the script fill fail:

 
<?php
	function test() {
		static $str = 2 + 4; 			  // generates a syntax error
		static $str = substr('hello', 1);  // also a syntax error 
	}
?>
 

static variables are particularly useful when you come to doing recursive functions and you need a way to ensure the function doesn’t infinitely recurse:

 
<?php
	function fizz() {
		static $c = 0;
		$c++;
		if ($c < 15) {
			fizz();
		}
		return $c;
	}
	echo fizz();
?>
 

This function will output the number 15.

Previous chapter… (6. User Input)
Next chapter… (8. File I/O)