I have a cookie which stores info in an array.
This is for a classifieds website, and whenever users delete their 'ads' the cookie must also be removed of the ad which was deleted.
So I have this:
if (isset($_COOKIE['watched_ads'])){
$expir = time()+1728000;
$ad_arr = unserialize($_COOKIE['watched_ads']);
foreach($ad_arr as $val){
if($val==$id){ // $id is something like "bmw_m3_10141912"
unset($val);
setcookie('watched_ads', serialize($ad_arr), $expir, '/');
}
}
}
This doesn't work... any idea why? I think its a problem with the unset part...
Also, keep in mind if there is only one value inside the array, what will happen then?
Thanks
You got two bugs here: 1) you unset the $val instead of the array element itself. 2) You set the cookie within the loop to the unknown $ad_arr2 array.
foreach($ad_arr as $key => $val){
if($val==$id){ // $id is something like "bmw_m3_10141912"
unset($ad_arr[$key]);
}
}
setcookie('watched_ads', serialize($ad_arr), $expir, '/');
array_filter seems appropriate:
$array = array_filter($array, create_function('$v', 'return $v != '.$id.';'));
You are correct that you are using unset incorrectly. The manual on unset states:
If a static variable is unset() inside
of a function, unset() destroys the
variable only in the context of the
rest of a function. Following calls
will restore the previous value of a
variable.
When you use 'as' you're assigning the value of that array element to a temporary variable. You want to reference the original array:
foreach ($ad_arr as $key => $val)
...
unset($ad_arr[$key]);
...
Related
I got the following function:
public function stopWatcherSession($sessionID) {
if(array_key_exists($sessionID, $_SESSION[self::WATCHER_SESSION_KEY])) {
foreach ($_SESSION[self::WATCHER_SESSION_KEY][$sessionID]['names'] as $v) {
$ptype = $this->paramTypeFromName($v);
unset($_SESSION[self::SESSION_KEY][$ptype][$v]); //does not work, sets entry to null
}
unset($_SESSION[self::WATCHER_SESSION_KEY][$sessionID]); //does not work, sets entry to null
}
}
As the comments say, the array entry does not get unset, the array_key_exists()-function still returns true, and if you var_dump($_SESSION) you can see, that $_SESSION[self::WATCHER_SESSION_KEY][$sessionID] is null.
How can I unset the variable, so that also the key in the array gets removed?
Things i tried, that did not work:
// v1 (tried also for `$_SESSION[self::WATCHER_SESSION_KEY][$sessionID]` )
$tmp = $_SESSION[self::SESSION_KEY][$ptype];
unset($tmp[$v]);
$_SESSION[self::SESSION_KEY][$ptype] = $tmp;
//v2
unset($_SESSION[self::WATCHER_SESSION_KEY][$sessionID]);
session_write_close();
session_start();
//v3 => v1 & v2 combined
$tmp = $_SESSION[self::SESSION_KEY][$ptype];
unset($tmp[$v]);
$_SESSION[self::SESSION_KEY][$ptype] = $tmp;
session_write_close();
session_start();
I could add a crappy hack all over the code to check whether it's null, but then »empty« values must be changed to something else (like a predefined const, but thats a nasty workaround and leads to confusion for other devs!)
Anyone got some ideas?
Got it working:
unset($GLOBALS['_SESSION'][self::WATCHER_SESSION_KEY][$sessionID]); does the job.
http://php.net/manual/en/function.unset.php says:
The behavior of unset() inside of a function can vary depending on what type of variable you are attempting to destroy. […] To unset() a global variable inside of a function, then use the $GLOBALS array to do so
Seems like a classical »PHP behaviour is undefined in some cases«-example.
I'm trying to debug a PHP application, and as a section of the debug process, I passed print_r($GLOBALS) through the AJAX request to my browser. However, I'd prefer to see it in native JSON form because it comes out better in the browser. I'm trying to use the following snippet of code:
json_encode($GLOBALS);
but I've found it returns bool(false). The JSON documentation says "Returns a JSON encoded string on success or FALSE on failure." But what about $GLOBALS makes it fail? Is it the recursive $GLOBALS['GLOBALS']?
I was thinking as an alternative to loop over $GLOBALS and put that in an array, but that seems quite pointless when the point of json_encode is to encode an array.
Upon testing this myself, it appears json_encode() can't handle recursion such as what's provided in $GLOBALS['GLOBALS']... etc.
So a trick(?) you can do is:
json_encode(array_slice($GLOBALS, 1));
Which will skip past $GLOBALS['GLOBALS'] and continue encoding the rest of the array.
*EDIT: $GLOBALS['GLOBALS'] appears first for me when printing this array, but a better way is to find where $GLOBALS['GLOBALS'] appears and skip that element entirely.
I propose a way where the position of GLOBALS is not important:
json_encode(array_intersect_key($GLOBALS,array_flip(array("_GET", "_POST", "_FILES", "_COOKIE"))));
or a better way:
$new_array = $GLOBALS;
$index = array_search('GLOBALS',array_keys($new_array));
json_encode(array_splice($new_array, $index, $index-1));
The fact that $GLOBALS contains reference to itself results in an infinite recursion that json_encode can't handle because it exceeds the maximum depth of 512 and thus will return false by default.
The solution would be creating a copy of $GLOBALS without self-referencing, the function below references superglobals _GET _POST _SERVER .. only, assuming you don't use $_ in your variables naming conventions:
function getEncodableGlobals()
{
$g = [];
foreach ($GLOBALS as $key => &$val)
{
if ($key[0] == '_')
{
$g[$key] = &$val;
}
}
return $g;
}
Notice that $g doesn't hold copies but only references to variables, just like $GLOBALS does. If you wish to include all the variables in the global scope simply change the condition to exclude the troublesome reference:
...
if ($key !== 'GLOBALS')
...
Now you can safely encode it:
json_encode(
getEncodableGlobals()
);
You could also do it the array_filter way and copy the variables.
$encodableGlobals = array_filter($GLOBALS, function($key) {
return $key !== 'GLOBALS';
}, ARRAY_FILTER_USE_KEY);
json_encode can't handle recursion such as what's provided in $GLOBALS['GLOBALS']... etc.
JSON.stringify is same!
you will retrieve error :
So in php you can create a new variable, example $globals which holds an array of $GLOBALS.
And, unset the recursive $globals['GLOBALS'].
$globals = $GLOBALS;
unset($globals['GLOBALS']);
echo json_encode($globals);
And... Congrats!! Now you can json_encode $GLOBALS variable!
I would like to set a session variable with something akin to:
$key = '_SESSION[element]';
$$key = 'value';
This does indeed set $_SESSION['element'] equal to value, but it also seems to clear the rest of my $_SESSION variable, resulting in the $_SESSION array only containing the new key/value pair.
How can I write into the session using variable variables without nuking it?
Edit: if this can't be done, so be it, we'll probably have to restructure and do things the "right" way. I just wanted to know if there was an easy fix
#Mala, I think eval will help you.
Check the code below. It may help you for what you want.
session_start();
$_SESSION['user1'] = "User 1";
$_SESSION['user2'] = "User 2";
$key = "_SESSION['user3']";
eval("\$$key = 'User 3';");
foreach ($_SESSION as $key=>$value){
echo $key." => ".$value."<br/>";
unset($_SESSION[$key]);
}
session_destroy();
If you still have any trouble, Let me know. Thank you
From PHP Documentation:
Please note that variable variables cannot be used with PHP's
Superglobal arrays within functions or class methods. The variable
$this is also a special variable that cannot be referenced
dynamically.
How you ended up with a situation like this, is really questionable. You're probably doing something wrong.
EDIT
This little trick should give you what you want:
$key = '_SESSION[element]';
$key = str_replace(array('_SESSION[', ']'), '', $key);
$_SESSION[$key] = 'value';
var_dump($_SESSION);
This will basically produce the same results as xdazz's answer
Isn't this way better?
$key = 'element';
$_SESSION[$key] = 'value';
How do you unset a variable variable representing an array element?
function remove($var) {
unset($$var);
}
$x=array('a'=>1,'b'=>2);
remove('$x["a"]');
var_dump(isset($x['a']));
The code above doesn't unset the array element x['a']. I need that same remove() function to work with $_GET['ijk'].
Just use unset() or the (unset) cast.
If you want to use a function to unset, something like this would be better.
function removeMemberByKey(&$array, $key) {
unset($array[$key]);
}
It works!
You can try,
function remove(&$var,$key) {
unset($var[$key]);
}
$x=array('a'=>1,'b'=>2);
remove($x,'a');
var_dump(isset($x['a']));
Variable variables cannot be used with superglobals, so if you need it to work for $_GET as well, you need to look at using a different method.
Source: http://php.net/manual/en/language.variables.variable.php
Try This:
<?php
/* Unset All Declair PHP variable*/
$PHP_Define_Vars = array_keys(get_defined_vars());
foreach($PHP_Define_Vars as $Blast) {
// or may be reset them to empty string# ${"$var"} = "";
unset(${"$Blast"});
}
?>
unset is easier to type then remove
When using it with an array element, the array will still exist
You could rewrite your function to treat the parameter as a reference;
EDIT: updated to use alex's code
function remove(&$array, $key){
unset($array[$key]);
}
remove($x,'a');
I have some code here which looks as following:
if (isset($_SESSION['addToCart'])) {
foreach ($_SESSION["addToCart"] as &$value){
if ($value['titel'] == $titel){
$value['aantal'] = $aantal;
if($value['aantal'] == 0){
unset($value);
}
}
}
}
so when 'aantal' = 0, I want to delete that record, but it doesn't, it just gives back the result and 'aantal' is 0 instead of the record being removed from the session.
Anyone know what I'm doing wrong?
According to the PHP docs (http://php.net/manual/en/function.unset.php), a variable that is passed by reference is only destroyed in the local context. Try $value = null;
From the manual: "When you unset the reference, you just break the binding between variable name and variable content. This does not mean that variable content will be destroyed."
You'd want to do something like this:
foreach ($_SESSION['addToCart'] as $key => &$value) {
if ($value['aantal'] == 0) {
unset($_SESSION['addToCart'][$key]);
}
}
Think of it like filesystem's symbolic links. When you destroy a symbolic link, it doesn't destroy the file it was linked to.
Your problem may stem from the fact that $value is a value variable, a copy of the $_SESSION["addToCarT"][current_index]. You should be setting the $_SESSION["addToCart"][current_index] to null or unsetting that, not the copies variable in the limited scope.