I have a button next to all my 'shop items' that can remove one of the shop item, however i need it to just remove one, and not rid the entire array of the number, i thought this was possible by using a break statement when i found the number i want to remove, but it removes all of the numbers.
if (isset($_GET['remove']) && isset($_SESSION['shopitems'])) {
if (in_array($_GET['remove'], $_SESSION['shopitems'])) {
for ($i = 0; $i < sizeof($_SESSION['shopitems']); $i++) {
if ($_SESSION['shopitems'][$i] == $_GET['remove']) {
$shopArray = $_SESSION['shopitems'];
if(sizeof($shopArray) == 1) {
$_SESSION['shopitems'] = null;
$_SESSION['added'] = null;
} else {
array_splice($shopArray, $i, $i);
$_SESSION['shopitems'] = $shopArray;
}
break;
}
}
}
}
Here i check if the URL contains the remove variable and the session is set, once i have done this, i check if the array contains the number that is put in the URL, if so i'll start a for loop and check if the key index of the session shop items is equal to the URL variable, if so i want to remove it, however if i use array_splice, suddenly they are all gone, is this because of the function i am using? Or is the break not executing correctly?
Why don't you try array_search() and unset()? It's easier, have a look at the code below and adapt it to your situation:
$array = [1, 5, 6, 12];
$wantToRemove = 5;
$key = array_search($wantToRemove, $array);
unset($array[$key]);
var_dump($array);
You can format your $_SESSION['shopitems'] like this :
$_SESSION['shopitems'] = array (
"item_id" => "item_info",
"item2_id" => "item2_info",
...
)
and do unset($_SESSION['shopitems'][$_GET['remove']]).
Your code could be :
if (isset($_GET['remove']) && isset($_SESSION['shopitems']))
if (isset($_SESSION['shopitems'][$_GET['remove']]))
unset($_SESSION['shopitems'][$_GET['remove']])
How do I delete the whole line from an array? When the delete-button is pressed it should delete the whole line.
my array looks like that:
$liste[0][0] = email-user1
$liste[0][1]= password-user1
$liste[1][0] = email-user2
$liste[1][1]= password-user2
So if I delete the user one, the user2 should just take the place from user1(which should just disappear).
if (isset($_GET['delete'])){
$id=key($_GET['delete']);
for ($i = 0; $i < count($liste); $i++){
if ("$i"=="$id"){
unset($liste[$id][0]);
unset($liste[$id][1]);
unset($liste[$id][2]);
}
else{
}
}
update
I'm using array_splice($liste, $id, 1); now but everytime I try to save it to the file I get an error: implode(): Invalid arguments passed. For saving it to the file, I use the following function:
function saveDataToFile($fileName, $liste){
$file=fopen($fileName,"w");
for ($i = 0; $i < count($liste); $i++) {
$zArray=$liste[$i];
$zeile=implode("|", $zArray);
if(strlen($zeile) > 0){
$zeile=$zeile."\r\n";
fwrite($file, $zeile);
}
}
fclose($datei);
}
Try the below code:
$liste[0][0] = "email-user1";
$liste[0][1]= "password-user1";
$liste[1][0] = "email-user2";
$liste[1][1]= "password-user2";
$liste[2][0] = "email-user3";
$liste[2][1]= "password-user3";
unset($liste[1]); // say you want to delete this row
$new_arr = $liste;
unset($liste);
$i=0;
foreach($new_arr as $value){
$liste[$i] = $value;
$i++;
}
You can use array_splice() method:
array_splice($liste, $id, 1);
$liste[0][0], $liste[0][1] and $liste[0][2] are in real nothing else than a value array(value, value, value) (the inner array) which is assigned to $liste[0] (the outer array)
unsetting this (outer) array value $liste[0] is enough:
unset($liste[$id]);
If you care about the keys of this array (I see you loop from 0..n), you need to reindex your array using:
$liste = array_values($liste);
This will make your array behaving more like arrays normally do in other programming languages
Good practice is to use foreach instead of for. In this case you don't need to reindex:
for ($liste as $key=>$value){
if ("$key"=="$id"){
unset($liste[$key]);
}
But anyway you don't have to loop through an array just for finding a key. It's enough doing this:
if (isset($liste[$id])) { /* optional: check if the key exists */ }
unset($liste[$id]);
So I've got an external text file with about 20 lines of text. What I'm trying to do is get each line of text into an index in an array. That's fine.
Now where I'm running into some trouble. I need to step through the array, and depending on if the index has a certain string in it, carry out an action.
Each index will either be formatted as: "add xxxx", "next" or "remove xxxx", where xxxx is a name that will only be used once in the array.
In this case, if an index as "add" in it, I need to push that index sans the "add " to a new array. If it has "next" in it, I need to shift the first index out of the new array, and log whatever index was shifted out. Finally, if "remove" is in the index, I need to search and remove whatever index contains the "xxxx" name.
<?php
$fileContent = file_get_contents("queueList.txt");
$queueList = (explode("\n", $fileContent));
$newArray = array();
foreach($queueList as $command){
if($n = strstr($command, "add")) {
array_push($newArray, $n);
}
else if($x = strstr($command, "next")) {
// need to print the index before pushing out
array_push($newArray, $x);
}
else if($z = strstr($command, "remove")) {
unset($newArray[$z]);
}
};//end foreach
print_r ($newArray);
?>
My real question is, what's the best way to step through an array on a key by key basis, and then carry out an action accordingly?
foreach($array as $key => $value ) {
if(shouldActOn($key)) {
// your code goes here.
}
}
there is a $_SESSION array that holds the ID of user's currently selected products (which are in the cart). Now, when the user sees his bill, he want to remove an item (product) from his cart, I have put him a link to do so. but the script does not work.
I have configured a $_GET['itemid'] in the URL and by using it, I unset() that array element.
BUT it does not work. What should I do? Here is my code
function remove_from_cart($stack_id) // stack_id is the id of the item in cart array ($_SESSION)
{
for($i=0; $i < count($_SESSION['add-to-cart-item']); $i++)
{
if($_SESSION['add-to-cart-item'][$i] == $stack_id)
{
unset($_SESSION['add-to-cart-item'][$stack_id]);
}
}
}
in your code
if($_SESSION['add-to-cart-item'][$i] == $stack_id)
{
unset($_SESSION['add-to-cart-item'][$stack_id]);
}
you find that $stack_id equals $_SESSION['add-to-cart-item'][$i] and not $i
which means that you need to unset $_SESSION['add-to-cart-item'][$i].
good luck
You should unset with [$i]
unset($_SESSION['add-to-cart-item'][$i]);
I'm currently working on a generic form creation class and had an issue yesterday.
I made a snippet to reproduce the problem.
Essentially I want to delete elements that are grouped from the original elements array after the whole group has been drawn and I'm doing this while looping over the elements array.
The code snippet should cover the problem, am I missing something here? From my knowledge deleting an element while foreach is completely safe and legal since foreach internally only uses a copy that may be modified during the loop.
$ids = array('a' => array(), 'b' => array(), 'c' => array());
$groups['g1'] = array('a', 'c');
foreach($ids as $id => $element) {
//var_dump($ids);
$g_id = '';
// search the id in all groups
foreach($groups as $group_id => $group) {
if(in_array($id, $group)) {
$g_id = $group_id;
break;
}
}
// element is part of a group
if($g_id !== '') {
//echo $g_id;
// element a and c gets unset within loop and should not be in $ids anymore
foreach($groups[$g_id] as $field_id) {
unset($ids[$field_id]);
echo $field_id;
}
unset($groups[$g_id]);
} else {
if($id === 'a' || $id === 'c')
echo $id;
}
}
Element 'c' gets unset within the foreach(groups ..) loop but is afterwards again outputted in the else branch. Also when i var_dump($fields) at the beginning i always get 'a', 'b' and 'c' inside. I'm using PHP 5.4.7.
Thanks in advance
EDIT: i made a mistake in the sample code, its now updated. All comments about using the wrong index (it would have been 0,1 etc) were correct of course.
The values when using var_dump are unset now, but i still get into the else with 'c' one time.
EDIT2:
Im not done with the original code but after reading through the comments I currently came up with following solution to the posted code snippet above:
$ids=array("a"=>array(),"b"=>array(),"c"=>array(),"d"=>array(),"e"=>array());
$groups=array(array("a"),array("c", "e"));
array_walk($groups,function($v,$i)use(&$ids){
$in_both = array_intersect(array_keys($ids),$v);
//var_dump($in_both);
foreach($in_both as $b) {
unset($ids[$b]);
}
});
print_r($ids);
or
$ids=array("a"=>array(),"b"=>array(),"c"=>array(),"d"=>array(),"e"=>array());
$groups=array(array("a"),array("c"));
array_walk($ids,function($v,$i)use(&$ids, $groups){
$in_both = array();
foreach($groups as $g) {
if(in_array($i,$g)) {
$in_both = array_intersect(array_keys($ids),$g);
}
}
foreach($in_both as $b) {
unset($ids[$b]);
}
});
print_r($ids);
Using a foreach does not work for me in this case, because i need to change the $ids array while the loop is iterating over it.
In the very most basic situation a code something like this:
$ids = array('a', 'b');
while(count($ids)) {
array_pop($ids);
echo 'pop';
}
echo 'empty';
Allthough foreach can change the original values from the array it will not change the copy of the array used for the iteration as nl-x already stated.
Thanks to Passerby for the idea of using array_walk for this.
EDIT3:
Updated code snipped once more. The second snipped allthough behaves undefined as well. Deleting elements from an array while iterating over its seems to be a bad idea.
Chris, if I understand correctly, you don't expect 'C' to be outputted in the else branch?
But it should be outputted. Your logic is:
you do foreach ids and start with id 'a'.
then you clear ids a and c from ids and delete the group g1 that contained 'a'. During this step the deleted ids will be outputted, being a and c. (Clearing a and c from ids will have no impact on the foreach($ids as $id) as foreach will continue with the untouched copy even after ids array has been cleared.)
then you do id 'b': it is not found in any group. (actually, there isn't any group left by now anyway)
so for 'b' you enter the else branch. But the if() inside the else branch prevents output
then you do id 'c', which is also not found in any group, because you have already deleted group g1! There are no groups left, remember?
so for 'c' you also enter the else branch. And this time the if() inside the else branch allows the output! The output being just c
So the total output is indeed acc.
It is good to know that a foreach() that continues with a untouched copy even after its elements were cleared, is a specific PHP thing. Other language do no necessarily do the same.
Spent some time reading your code, and I guess your procedure is:
For every element in $ids, check if it exists in some sub-array in $groups;
If it exists, delete everything in $ids that also exists in this sub-array.
Following the above logic, I come up with this:
$ids=array("a","b","c","d","e");
$groups=array(array("a","c"),array("c","e"));
array_walk($groups,function($v,$i)use(&$ids){
$ids=array_diff($ids,$v);
});
print_r($ids);//debug
Live demo
I'm double checking now. But I think unsetting an array with foreach is not really safe.
What I usually would do is take a foreach, and start with the highest indexes and descrease the index along the way. for($i = count($arr)-1; $i >= 0; $i--) { unset($array[$i]); }
I'll edit this post in a few minutes.
edit: i was confused. The for with $i++ is indeed the culprit. foreach is safe (in php! not in all languages)
<?php
$arr = Array(1,2,3,4,5,6,7,8,9,10);
foreach ($arr as $key=>$val)
unset($arr[$key]);
echo implode(',',$arr); // returns nothing
$arr = Array(1,2,3,4,5,6,7,8,9,10);
for ($i=0; $i<count($arr); $i++)
unset($arr[$i]);
echo implode(',',$arr); // returns 6,7,8,9,10
$arr = Array(1,2,3,4,5,6,7,8,9,10);
for ($i=count($arr)-1; $i>=0; $i--)
unset($arr[$i]);
echo implode(',',$arr); // returns nothing
?>
$ids[$field_id] does not exist, you are using the value instead of the key.
You should simply unset using the right key :
if (in_array($field_id, $ids))
unset($ids[array_search($field_id, $ids)]);
If you want to remove the element from the array, shouldn't you 'splice' it out instead with array_splice?
From the PHP manual: http://php.net/manual/en/function.array-splice.php
Your foreach wont make any changes since a copy of array is used.. you will need to use pass by reference in order for this to work. one of the way is mentioned below
while(list($key,$value) = each($array)){
if(your reason to unset)
unset($array[$key]);
}
this will remove the element from the array.