Jump to content

Unset local arrays with global scope: not working as expected


ExpertAlmost

Recommended Posts

Good morning!

 

I've spent hours on this to no avail. My understanding is that unset() only deletes the copy of the variable local to the current scope. But I am getting a very different result. I have the following structure and output. What am I doing wrong?

 

<?php

first_function();

second_function() {

  for ($count = 0; $count < $max; $count++) {

      $my_array = array[];  //initialize my array, local in this scope but can be called global in nested functions

      print_r($my_array );    //print 1: array should be always empty but is only in empty in FIRST loop.

      third_function();          //fills the array with numbers, see below, nested function declaring a global array

      print_r($my_array );    //print 3 of my_array, should be full of numbers from third_function global changes

      unset($my_array);      //delete my array so I can start with new array in next loop

      print_r($my_array );    //print 4 of my_array, should be unknown variable

      print('End one loop');

  }

}

 

third_function() {

  global $my_array;  //declare my global variable

  //...fill my now global array with stuff...

  print_r($my_array );  //print 2: should be filled with numbers. And it is.

}

?>

 

My output amazingly looks something like this

 

Array()

Array(45,48,38...all my numbers...)

Array()

ERROR: Notice -- Undefined variable: my_array

End one loop

Array(45,48,38...all my SAME numbers again as if array was NOT unset...)

......

 

The first and second print lines make sense. But shouldn't the third line be the array filled with numbers generated in third_function? The fourth line error makes sense as the variable is unset. But WHAT did I unset? The next time around in the loop, the array contains the SAME numbers from the previous loop and my new numbers simply get appended to the end of the ever growing array. Why?

 

This should not be that difficult but seems to be driving me crazy. Any help would be greatly appreciated.

 

alexander

Link to comment
Share on other sites

Hello Ken!

 

Thank you for your help. Unfortunately, the code is rather complex. I simplified the code considerably to shorten the post.

 

The main question being: if I create an array in a function and declare it global in various sub-functions (which does work as expected as the variables do update), shouldn't an unset delete the array in the initial function? And why, as seen in my output, does the array in the initial calling function appear to have no contents?

 

I have a typo which is corrected to: $my_array = array();

 

The code seems to work fine on the first pass of the loop. It is only on the second pass where I found that $my_array is appending to the array contents in the first pass.

 

In short, how do I declare and array in a function. Make it global in sub-functions. (That part works already.) And then unset in the declaring function? That is what I am ultimately trying to do.

 

Thank you again for your help!

alexander

 

 

Link to comment
Share on other sites

Your results make perfect sense. When you create "$my_array" in second_function() it is local to that function. Using

global $my_array;

in third_function() does not give you access to $my_array; from second_function().

 

In order to access a global variable the variable must first exist in the global scope, i.e. it has to be defined outside any functions.

 

Example:

$globalA = "A";

function createLocalVar()
{
    $localB = "B";
}

function outputVarsFromLocal()
{
    global $globalA, $localB;
    echo "GlobalA: {$globalA}<br />\n";
    echo "LocalB: {$localB}<br />\n";
    $localB = "C";
}

createLocalVar();
outputVarsFromLocal();
echo "LocalB (second time): {$localB}<br />\n";

 

Output

GlobalA: A
LocalB (first time): 
LocalB (second time): C

 

The variable $localB was defined in a local scope so it cannot be accessed from the global scope (first time). However, by defining the variable as Global in the function, that variable is now also accessible in the global scope. So, we can modify the value in the function and access it while in the gloable scope (i.e. outside any functions).

Link to comment
Share on other sites

Thank you mjdamato!

 

Your explanation is very thorough and instructive! Because I want to resuse the array in the loop I did not think I could create it in the main program scope. But if I can create it in the second function, that would be great.

 

So if I understand correctly, the line in question would be: global $my_array = array[];  in the second function. As shown below?

 

<?php

first_function();

second_function() {

  for ($count = 0; $count < $max; $count++) {

      global $my_array = array[]; 

      third_function();         

      unset($my_array);     

      print('End one loop');

  }

}

 

third_function() {

  global $my_array; 

  //...fill my global array with stuff...

}

?>

 

Link to comment
Share on other sites

 

About 20 years ago it occurred to me that software engineering was the Science of Successful Disappointments!

That short bright feeling of success followed by the darkening sky of yet another bug...

Right now I am enjoying that success brought about by your help!

 

The one star that seems constant however is the communal kindness of fellow coders. Thank you all for sharing your ever precious time, hard-won expertise, and clever ideas. Should any of you ever find yourself in Thailand, let me know. Coffee and dessert are on me :)

 

Apparently it is possible to create globals within functions. To complete the thread, I opted for the following (pseudo-code) solution which does work in my code:

 

<?php

first_function();

second_function() {

  for ($count = 0; $count < $max; $count++) {

      global $my_array;            // make the variable global here

      $my_array = array();        // set the variable to an array

      third_function();

      unset($my_array);          // unset the variable here

  }

}

 

third_function() {

  global $my_array;              // declare the variable as global here

  //...fill my global array with stuff...

}

?>

 

While I agree with the view that using globals is a dangerous thing, I have three arrays which are used almost everywhere and changed in many places. Hence the globals. Fortunately I am a strong code documenter (from years of repeated experience with "what in the world was I thinking when I wrote this?") so array changes are clearly and explicitly stated.

 

Thank you again everyone! May your coding skies be bright and clear and path behind you littered with the desiccating corpses of vanquished bugs.

alexander

Link to comment
Share on other sites

OK, I know that is only mock code, but there are some issues with it.

 

1. Declare the $my_array as gloabl before you start the loop. Having it in the loop causes unnecessary processing.

 

2. Do you actually use $my_array in second_function() at all? In the code above it serves no purpose to even use $my_array in that function.

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.