0

I have the following script for a Google maps application. The information about a specific place is sent via ajax to the $array array which is then added to the $SESSION['infomarker']. This part works fine. But the user should also be able to delete a place (If they regret the input).

This is handled by the removeElementWithValue() function, which takes the places lat and lng as arguments ($val1 and $val2 in this sample script). The array which contains the 'val1' and 'val2' values then disappears, like they should. But when I change the $val1 and $val2 variables to 'val3' and 'val4', the array which contained 'val1' and 'val2' returns while the array which contains 'val3' and 'val4' is unset.

I thought that unset() 'unset' the array in question for good, or do I need to do something else?

<?php
session_start();


if(isset($_POST['lat']) && !empty($_POST['lat']) ) {
$array = array(
                'titel' => $_POST['titel'], 
                'comment' => $_POST['comment'], 
                'lat' => $_POST['lat'], 
                'lng' => $_POST['lng'] 
                );


$_SESSION['infomarker'][] = $array;


   }    

  $val1 = 'val1';

  $val2 = 'val2';


  $newarray = removeElementWithValue($_SESSION['infomarker'], "titel", "comment", $val1, $val2);

 function removeElementWithValue($array, $key1, $key2, $value1, $value2){
 foreach($array as $subKey => $subArray){
      if($subArray[$key1] == $value1) {
      if($subArray[$key2] == $value2) 

         unset($array[$subKey]);

      }

   }
return $array;

}

print_r($newarray);
user1009453
  • 707
  • 2
  • 11
  • 28

2 Answers2

2

You are modifying the $array that is being passed to your removeElementWithValue method. You are passing the $_SESSION array into the method.

unset is doing what it's supposed to, by removing the value from $array. But, your method is actually receiving a copy of the $_SESSION variable since PHP will pass arrays by-value not by-reference.

You can prefix the $array variable in the function declaration with an amperstand (&) character, which will inform PHP to pass that variable to the function by-reference, and will cause any modifications made to the array inside of the function to change the source array ($_SESSION).

Clarification:

Calling a function creates a scope in the "stack" for that method. PHP, by default, passes everything by-value (for those who want to argue that objects are passed by reference - they're not. The reference to the object is passed by-value).

What does that mean? Well, it's easier than it seems. Take the code below:

function myfunc($value) {
  $value = $value + 1;
}

$testing = 1;
myfunc($testing);
var_dump($testing);

This will output int(1). Notice how, even though we increment the value inside of the function - the result doesn't change the $testing variable. This is because the $testing variable was declared in a different scope inside of the stack. As far as PHP saw, when we called the method, we actually called this myfunc(1) (notice the number instead of a variable). The variable's value was grabbed from memory, and that value was passed to the method.

This is where passing by-reference comes in handy. You can instruct PHP to pass by-reference by prefixing any argument in the function definition with an amperstand, so you get this:

function myfunc(&$value) {
  $value = $value + 1;
}

$testing = 1;
myfunc($testing);
var_dump($testing);

The addition of the simple ampersand will now make this code print int(2).

So what's the difference? Well, you'll remember that I said the first time we are basically calling myfunc(1). The second time, we are effectively calling myfunc(0xff940ac4) where 0xff940ac4 is the memory address to the $testing variable. Now, any changes we make to $value inside of the method will change the data at memory address 0xff940ac4, instead of the value that was "copied" into the scope for this method.

Colin M
  • 13,010
  • 3
  • 38
  • 58
  • Ok, not quite sure whta you mean by this, but I added the ampersand and it did the trick. I will have to read up on this! Thank's a lot though! – user1009453 Jan 08 '13 at 15:43
  • Ok, not quite sure what this means, but I added the ampersand and that did the trick. I will have to read up on this! Thanks a lot! – user1009453 Jan 08 '13 at 15:48
  • Just added a large explanation - let me know if this helps. – Colin M Jan 08 '13 at 15:54
  • Very nice explanation, even I umnderstand the difference now :) Thank's for taking the time to explain this! – user1009453 Jan 09 '13 at 16:11
1

That is, because in PHP, by default arrays aren't passed by-reference, but by-value. So, the function that you are using, will remove the values from the $array inside the function. But that won't modify the function. If you want to have that behaviour, you should have PHP pass the value by-reference.

You can do this by changing the function definition like this:

function removeElementWithValue(&$array, $key1, $key2, $value1, $value2)
{ ... }
kokx
  • 1,706
  • 13
  • 19