static vs global

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
User avatar
Obadiah
Forum Regular
Posts: 580
Joined: Mon Jul 31, 2006 9:13 am
Location: Ashland, KY
Contact:

static vs global

Post by Obadiah »

what is the true difference between global and static?

say i had a small program

Code: Select all

<?php
$num_of_calls=0;
function numberedHeading($txt){
global $num_of_calls;
$num_of_calls++;
echo"<h1>$num_of_calls. $txt</h1>";
}
numberedHeading("Widgets");
echo "<p>We build a fine range of widgets.</p>";
numberedHeading("Doodads");
echo "<p>Finest in the world.</p>";
?>
you guys woud say "obi...you didnt need to use the global", then ill say, i did because im using the function throughout the program....which is theoretically correct until someone recreates the same code this way

Code: Select all

<?php
function numberedHeading($txt){
static $num_of_calls=0;
$num_of_calls++;
echo"<h1>$num_of_calls. $txt</h1>";
}
numberedHeading("Widgets");
echo "<p>We build a fine range of widgets.</p>";
numberedHeading("Doodads");
echo "<p>Finest in the world.</p>";
?>
you guys can all agree that thats much more elegant which can agree it does look a bit cleaner...but if i can define a variable as a static and use it throughout my program the same way as i would use a global...whats the purpose of using the global...what is the difference in the two? :?

[edited]

also the num_of_calls() isnt working correctly as it should worl like a ordered list showing numbers but it doesnt
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post by feyd »

The static only exists within the scope it was defined. A global exists in the global scope.
User avatar
Obadiah
Forum Regular
Posts: 580
Joined: Mon Jul 31, 2006 9:13 am
Location: Ashland, KY
Contact:

Post by Obadiah »

gotcha....so why isnt the num_of_calls() increment echoing?
User avatar
bokehman
Forum Regular
Posts: 509
Joined: Wed May 11, 2005 2:33 am
Location: Alicante (Spain)

Post by bokehman »

Using globals within a function ties the function to the proceedural code in one particular script. For this reason, if you want to write high quality portable functions, don't use globals.
User avatar
Christopher
Site Administrator
Posts: 13596
Joined: Wed Aug 25, 2004 7:54 pm
Location: New York, NY, US

Post by Christopher »

How about:

Code: Select all

class Heading {
var $num_of_calls=0;

function numberedHeading($txt){
    ++$this->num_of_calls;
    return "<h1>{$this->num_of_calls}. $txt</h1>";
}
}

$heading = new Heading();
echo $heading->numberedHeading("Widgets");
echo "<p>We build a fine range of widgets.</p>";
echo $heading->numberedHeading("Doodads");
echo "<p>Finest in the world.</p>";
Looks the the beginnings of a View or Response class...
(#10850)
User avatar
Obadiah
Forum Regular
Posts: 580
Joined: Mon Jul 31, 2006 9:13 am
Location: Ashland, KY
Contact:

Post by Obadiah »

Code: Select all

++$this->num_of_calls;
@aborint=what does this line do? what is it for?

it looks as though your incrementing something but wouldent the ++ have to be after the argument, function, or variable that your wanting to increment?
User avatar
bokehman
Forum Regular
Posts: 509
Joined: Wed May 11, 2005 2:33 am
Location: Alicante (Spain)

Post by bokehman »

Obadiah wrote:wouldnt the ++ have to be after the argument
No, but they are different!

Code: Select all

++$i
increments the variable and then returns the value whereas

Code: Select all

$i++
returns the value and then increments the variable.

This only matters though when the piece of code is doing both operations in one hit.
User avatar
CoderGoblin
DevNet Resident
Posts: 1425
Joined: Tue Mar 16, 2004 10:03 am
Location: Aachen, Germany

Post by CoderGoblin »

My 2 cents

Code: Select all

function firstFunct()
{
  // count the number of times this function is run.
  static $counter=0;
  return ++$counter;
}

function secondFunct()
{
  // count the number of times this function is run.
  global $counter;
  return ++$counter;
}

$counter=0;
echo("Function 1 Counter:: ".firstFunct()."<br />"); // returns 1
echo("Function 1 Counter:: ".firstFunct()."<br />"); // returns 2
echo("Function 2 Counter:: ".secondFunct()."<br />"); // returns 1
echo("Function 2 Counter:: ".secondFunct()."<br />");  // returns 2

$counter=10; // accidently set this after all $counter could be a common variable name

echo("Function 1 Counter:: ".firstFunct()."<br />");  // returns 3
echo("Function 1 Counter:: ".firstFunct()."<br />");  // returns 4
echo("Function 2 Counter:: ".secondFunct()."<br />");  // returns 11
echo("Function 2 Counter:: ".secondFunct()."<br />");  // returns 12
Hopefully you can see the difference. Using globals can cause errors where you accidently set values you didn't mean to.
User avatar
bokehman
Forum Regular
Posts: 509
Joined: Wed May 11, 2005 2:33 am
Location: Alicante (Spain)

Post by bokehman »

CoderGoblin wrote:My 2 cents

Code: Select all

function firstFunct()
{
  // count the number of times this function is run.
  static $counter = 0;
  return ++$counter;
}
One thing is a pain with static and that is resetting the variable to a particular value:

Code: Select all

function firstFunct(reset = false)
{
  // count the number of times this function is run.
  static $counter = 0;
  if($reset) $counter = 0;
  return ++$counter;
}
Your other option of course is a call by reference. This still allows the function to be portable (unlike with global) but is fed to the function (unlike static).
User avatar
CoderGoblin
DevNet Resident
Posts: 1425
Joined: Tue Mar 16, 2004 10:03 am
Location: Aachen, Germany

Post by CoderGoblin »

bokehman wrote: One thing is a pain with static and that is resetting the variable to a particular value....
Disagree.. It means you need to make the decision to reset the value so you do not do it "accidently".
bokehman wrote:Your other option of course is a call by reference.
The purpose of the code was to answer the question in the title with a simple example. Whilst the second option could be a a call by reference it does not demonstrate the point in the title. Also I have seen many occasions where people use global instead of call by reference as they have never seen it/don't know about it. Any global call within a function could be passed in by reference.
User avatar
bokehman
Forum Regular
Posts: 509
Joined: Wed May 11, 2005 2:33 am
Location: Alicante (Spain)

Post by bokehman »

CoderGoblin wrote:Any global call within a function could be passed in by reference.
Yes, but using global ties the function to proceedural code whereas a call by reference does not since the variable name is irrelevant with calls by reference (not so with globals). By the way I wasn't suggesting there was anything wrong with your code.

As for your point about overwriting the global variable although true this can happen anywhere within a script and is more to do with bad coding than static being advantageous.
User avatar
CoderGoblin
DevNet Resident
Posts: 1425
Joined: Tue Mar 16, 2004 10:03 am
Location: Aachen, Germany

Post by CoderGoblin »

bokehman wrote:By the way I wasn't suggesting there was anything wrong with your code.
Wasn't taking it as a criticism :D
bokehman wrote:As for your point about overwriting the global variable although true this can happen anywhere within a script and is more to do with bad coding than static being advantageous.
Agreed, normally static is not required, local variables and passing by parameters are normally sufficient. The only times I think I have used "static" is during recursion to keep track of the depth. As for passing variables by reference, I personally have found very little use for it other than using php4 with objects/classes. If you pass things by reference you tighten the join between the variables and functions restricting the function's "reusability". When all said and done, normally the only thing a function should do is get parameters and possibly return values. Side effects should be minimised as they are very hard to track.
Post Reply