I'm using references to alter an array:
foreach($uNewAppointments as &$newAppointment)
{
foreach($appointments as &$appointment)
{
if($appointment == $newAppointment){
$appointment['index'] = $counter;
}
}
$newAppointment['index'] = $counter;
$newAppointments[$counter] = $newAppointment;
$counter++;
}
If I print the array contents, then I receive the expected result. When I iterate over it, all elements seem to be the same (the first).
When I remove the reference operator & in the inner array, all goes normal, except index isn't set.
Using references in foreach loops is asking for trouble :) I've done that several times, and I always rewrote that code.
You should to it as well. Like this:
foreach($uNewAppointments as $newAppointmentKey => $newAppointment)
{
foreach($appointments as $appointmentKey => $appointment)
{
if($appointment == $newAppointment){
appointments[$appointmentKey]['index'] = $counter;
}
}
$uNewAppointments[$newAppointmentKey]['index'] = $counter;
$$uNewAppointments[$newAppointmentKey][$counter] = $newAppointment;
$counter++;
}
Though I have just rewritten it "mechanically", so it will probably not work. But it's to get the idea of how to achieve the same effect, without the side effects. You are still modifying the original arrays in this loop.
If you do this, you must unset $newAppointment when you exit the loop. Here is the relevant entry.
Related
Does anyone know why this simple bit of code wont work? The second loop doesnt seem to take place.
while(list($get_key, $get_value) = each($HTTP_GET_VARS)) {
if (!${$get_key}) {
${$get_key}=$get_value;
}
}
while(list($keyone, $valueone) = each($HTTP_GET_VARS))
{
echo $keyone;
}
Your problem here is the use of each(). It remembers the index it has reached in the array so in your second loop there is nothing left to loop out so it evaluates to false. If you use reset() this should resolve the issue.
while(list($get_key, $get_value) = each($HTTP_GET_VARS)) {
if (!${$get_key}) {
${$get_key}=$get_value;
}
}
reset($HTTP_GET_VARS);//will put the pointer back to the first element
while(list($keyone, $valueone) = each($HTTP_GET_VARS))
{
echo $keyone;
}
Alternatively you can just use the foreach(){} syntax which will always start from the first element in the array.
I have a series of variables in php:
move1A = $row['column'];
move2A = $row['column'];
move3A = $row['column'];
etc.
I want to create a variable that will represent these variables and check if it is NULL. I have spent quite a bit of time looking, and although I believe that variable variables may be the key to my problem. So far I have tried:
$current_move_check = 'move'.$moveCounter.'A';
and
$current_move_check = '$move'.$moveCounter.'A';
Neither seem to work. Any suggestions for making something like this work? Thanks!
UPDATE:
So I'm trying to loop the moveXA variables based on user input and I need to run different script whether it is null or set.
I thought that:
elseif (!$$current_move_check) {
and
elseif ($$current_move_check) {
would work but they seem to not be outputting as expected.
Considering your update, I'd really suggest you to use an array, rather than the variable variables trick. Your code would makes more sense and be easier to maintain :
$count = 0;
$moveA[++$count] = $row['column'];
$moveA[++$count] = $row[...];
$moveA[++$count] = $row[...];
...
foreach ($moveA as $key => $value) {
if ($value) { // = $$current_move_check
} else { // = !$$current_move_check
}
}
As #MatsLindh pointed out in its comment : "Variable variables are never a good idea. Unless you know when it makes sense to break that rule, don't."
$current_move_check = 'move'.$moveCounter.'A';
echo $$current_move_check;
now you can check this as well like
if($$current_move_check!=NULL)
{
// do your code
}
OK so I'm making something to do some data mining but I do changes to an array (by overwritting previous array values) in a loop and they show that they've been changed but once I get outside of a greater loop the values change back to their original values.
Probably easier to give an example:
It starts off like this, turning a bunch of the parts of the array into the word "MATCH".
Now if I was to immediately dump the values of the array it would show that some values have changed to "MATCH" (ie, right after changing the value I would echo the array slot and it would show it's value to be "MATCH") However after I get outside the loop the array changes back to it's original contents
Here is a compressed version of the code:
//i've got this big loop for doing the main work
do {
//Set dat ticker
$q = 0;
// Run through entire previous scrape array to check for matches and mark them as unchanged
do {
if ($itemTitle[$i] == $prodURLS[$q]) {
$prodURLS[$q] = "MATCH";
echo "When the value is printing immediately it shows that it's changed: ".$prodURLS[$q]."<br>";
}
$q++;
} while ($q < $urlArraySize);
$i++;
} while ($i < $itemtitleArraySize);
//If I were to try to print the variable down here it would be reverted to like it was before I changed it to "MATCH"
print_r($prodURLS);
From running your code, setting the variables as follow, it works for me:
$prodURLS = array('a','b','c');
$itemTitle = array('a');
$urlArraySize = count($prodURLS);
$itemtitleArraySize = count($itemTitle);
$i = 0;
My only recommendations with only this amount of information, are:
To provide more context information, as madth3 suggests.
To check the scope in which you are setting/checking values. You may need the & operator to pass variables by reference, or the global keyword to use global variables.
To use the foreach loop, it will make your code smaller and easier to read. Also you won't need to count the size of the arrays and will have other advantages, e.g. in the use of associative arrays. Again, be careful about the use of variables by reference. For example:
foreach ($itemTitle as $item) {
foreach ($prodURLS as &$prod) {
if ($item == $prod) {
$prod = 'MATCH';
}
}
}
unset($prod); //Unset variable set by reference if you are going to use it later on!
Also, you may find useful some of the php array functions like array_walk. Check out the PHP Manual on the array functions reference.
Really, there isn't a lot that can be said from just the code you provided.
Good luck.
I'm working with 3 different arrays (although I'm only testing with two for the time being) and I'm trying to process the arrays on $_POST. I'm currently using:
while(list($key_member,$member)=each($_POST['member_ids'])
&& list($key_amount,$amount)=each($_POST['payment_amounts']))
{
echo "MEMBER: $member<br>";
echo "AMOUNT: $amount<br><br>";
}
If I use one list() on either array it will print the info for that particular item. However, if I attempt to use multiple list() commands in the while, only the last list()ed item gets filled properly. Is list() doing some trickery in the background that's preventing it from working in a while loop?
Obviously the "easy" solution would be to use an index and simply force the issue, but I prefer enumerating -- and I'm honestly just curious as to
What am I doing wrong, and/or what is "broken" with list()?
bug? dunno.
here's a workaround.
while(list($key_member,$member)=each($_POST['member_ids'])){
list($key_amount,$amount)=each($_POST['payment_amounts']);
echo "MEMBER: $member<br>";
echo "AMOUNT: $amount<br><br>";
}
You could extract each array's keys using array_keys(), which produces an indexed array, then keep separate loop counters for each array:
$member_ids = array_keys($_POST['member_ids']);
$amounts = array_keys($_POST['payment_amounts']);
$mi = 0;
$am = 0;
while(1) {
...
$mi++
$am++;
if (count($member_ids) >= $mi) && (count(amounts) >= $am) {
break;
}
}
&& is evaluated in a short-circuit manner, the first statement to return false jumps out of it. In your case it stops to iterate as soon as the first array is at its end. list should work fine here, as it's a language construct which assigns variables.
I am getting the key from a given value in a multidimensional array. It works fine except that I cannot seem to access the variable from OUTSIDE the nested foreach loop that I'm using to get the key.
so my foreach loop is: ($name_books is the multi-d array which contains 3 smaller arrays)
foreach($name_books as $test) {
foreach ($test as $key => $value) {
$book_code = array_search($row['name'],$test);
echo $book_code; //just to see if it works, which it does
break;
}
}
//But then if I go outside of the loop..
echo $book_code." is the book code"; // <--DOES NOT WORK
So I know that I'm dealing with variable scope issues here and I've tried declaring globals inside the foreach loop but nothing works.
I'm sure there is something absurdly simple I'm missing!
EDIT:
urg..I took a step back and realized something else,
all this is happening inside a while loop (getting stuff from a db)
so the code is more like:
while($row=mysql_fetch_assoc($result)) {
...original foreach loop from above
}
apologies for not including this, I was focusing on this tiny piece and forgot to back up and see where it fit.
break;
Will only exit the internal nested foreach. If there are more rows in $name_books, it will continue looping and eventually overwriting $book_code with 'false' values from array_search;
Once you've found the value you're looking for, use:
break 2;
Regarding your edit, where you break depends on what you're doing with the value you've found for $book_code. If you don't plan on continuing, change the parameter for break. break 3; will exit the while loop too. Change the value depending on the level of nesting.
This has nothing to do with variable scope so long as what you posted is exactly what you have in your script.
I think what the problem is, is that you are only breaking out of the inner loop. In each iteration of the outer loop, $book_code will get changed, so you need to stop the outer loop as well. Try changing break; to break 2; and see if it fixes your problem. That causes it to break out of both the inner and the outer loop.
Edit: I think you can also simplify your code:
foreach ($name_books as $test) {
$book_code = array_search($row['name'], $test);
if ($book_code !== FALSE) {
break;
}
}If I knew more about your structure, this could possibly be reduced down to a single SQL statement and 0 loops.
simshaun is right, but I would actually take a different approach.
I would check for the existence of $book_code in my foreach loops rather than dealing with the breaks.
New Code
foreach($name_books as $test) {
foreach ($test as $key => $value) {
if(!isset($book_code)){
$book_code = array_search($row['name'],$test);
echo $book_code; //just to see if it works, which it does
}
}
}
echo $book_code." is the book code";