I have infinite loop in PHP and need to know the integer after the break in the switch case. Right now I use break 5; but I am now sure if this is right. Could someone tells me how to break out of all of the loops but while (true). I removed the unnecessary code so only the loops are left.
$i = 0;
while (true)
{
// After the break 5 in the switch we should land here again
foreach ($users as $user)
{
while ($i < 10)
{
if (!empty($user))
{
if (isset($user->id))
{
switch($user->id)
{
case 1:
break 5;
default:
break 5; // Need to break out the foreach. So a break five right?
}
}
}
$i++;
}
}
$i=0;
}
The answer is 3, as break ends execution of the current for, foreach, while, do-while or switch structure.
Where break 1 only exists the switch, 2 the while and 3 the foreach and 4 the main while.
But perhaps this is a better method, as you specifically state where to go instead of guessing. You cannot place the goto marker inside a loop, but in your case you can just make it before the loop.
$i = 0;
mybegin:
while (true){
# 1. After the break 3 in the switch we will -not- land here.
# 3. So if you want to start here, you will need to use the goto statement.
foreach ($users as $user){
while ($i < 10){
if (!empty($user)){
if (isset($user->id)){
switch($user->id){
case 1:
break 3;
default:
goto mybegin;
}
}
}
$i++;
}
}
# 2. Using break 3, the code continues here.
$i=0;
}
But I have to say that I never needed that many loops or a goto statement for that matter as there is always a better way.
Related
So I am trying to optimize a piece of php code that basically runs the same operations on two different datasets, based on user input. What would be a better and more optimized approach?
//$input = //user input
//$a = [1,2,3 .....];
//$b = [a,b,c .....];//both are same length - n
case 1 :
for($i =0; $i<n; $i++) {
if($input == 'a')
//doSomething with $a[i] - code here
else
//doSomething with $b[i] - code here
}
case 2 :
if($input == 'a') {
for($i =0; $i<n; $i++) {
//doSomething with $a[i] - code here
}
}
else {
for($i =0; $i<n; $i++) {
//doSomething with $b[i] - code here
}
}
case 3 :
if($input == 'a') {
for($i =0; $i<n; $i++) {
doSomething($a[i]);
}
}
else {
for($i =0; $i<n; $i++) {
doSomething($b[i]);
}
}
the operation is same in all cases
Better is always difficult to quantify, but if you want to do exactly the same processing on the inputs, just picking the one dataset depending on the input, you may be better off just setting an input array and just processing that...
if($input == 'a')
$dataset = $a;
else
$dataset = $b;
foreach ( $dataset as $dataItem ) {
//doSomething data code here
}
This might not really be the answer you're looking for, but honestly, I would just go for whatever conveys the actual use case the best and not try to optimize too much.
Performance-wise, unless the operation that checks the $input takes a lot of time (orders of magnitude more than a simple comparison), or if the operation on $dataset is very short (comparable to the input check), it simply won't matter.
Assuming $input does not change while you're processing your dataset, I'd go for case three. You're making it clear that it is the same operation, and the only difference between the different if branches is the dataset you're working with. If you're familiar with ternary operators, I'd even use this:
for($i = 0; $i < n; $i++) {
doSomething(($input == $a) ? $a[i] : $b[i]);
}
I'd take code readability over micro-optimizations any day, as long as you don't actually have performance issues with this piece of code.
As a bonus, have a read at this question about optimization: https://softwareengineering.stackexchange.com/questions/80084/is-premature-optimization-really-the-root-of-all-evil
I am new to PHP and I am having trouble with making this infinite while loop work. I am trying to make a infinite while loop generate random numbers between 1 and 10 and to output the cube root of those numbers, as well as terminating the loop when 5 is generated. So far I have the code below and I am not sure where I am going wrong. Any help or guidance will be much appreciated.
$counter = rand(1, 10);
while ($counter==5) {
break;
if ($counter >5 or $counter<5) {
echo sqrt($counter) . "</br>";
}
$counter++;
}
EDIT: I have listened to the advice you guys gave to me below and I noticed some mistakes I had made myself such as "or" becoming "and". However I am still yet to understand why it isn't generating a loop with numbers 1-10 to their powers?
while(true)
{
$counter = rand(1, 10);
if ($counter <=10) {
echo sqrt($counter) . "</br>";
}
if($counter ==5) break;
}
you are breaking the loop WHILE (ongoing) your counter equals 5 and only echo once IF your condition is met.
what you might want to do could look like
while(true)
{
$counter = rand(1 , 10);
#echo stuff
if($counter == 5) break;
}
I am aware we can skip the next iteration with continue in a for loop. Anyway to skip the next x loops (2 or more)?
You actually can't, you can do a dirty trick like
for ($i=0; $i<99; $i++){
if(someCondition) {
$i = $i + N; // This will sum N+1 because of the $i++ in the for iterator (that fire when the new loop starts)
continue;
}
}
If you're iterating with a for loop (as opposed to a foreach loop) you could do something like this:
for ($i=0; $i<$numLoops; $i++) {
if(condition()) {
$i+= $numLoopsToSkip;
continue;
}
}
Take for example, you can define the amount of times you want to loop as you want as $y
<?php
y = 5;
while (true) {
// do something
if (y > 0) {
y--;
continue;
}
// do something else
}
?>
Coming soon in PHP 'X' ;-)
continue += x;
I've been trying to teach myself php and I came across this code (as with all code I try it out myself to get a better understanding etc) but this one doesn't run.
<?php
$i = 0;
while($i++){
switch ($i) {
case 5:
echo "At 5<br />";
break 1;
case 10:
echo "At 10; quitting<br />";
break 2;
default:
break;
}
}
?>
The output is just blank but would i be correct in saying that $i is incremented until it hits 5, at which point switch($i) would go to case 5 at echo "At 5" and then it'll break that switch statement and continue in the while loop incrementing $i till it reaches 10, then it'll repeat the same process and go to echo "At 10; quitting" and the break 2 would leave the switch and while loop?
During all the other values for $i i'm assuming it goes to default and just breaks out of the switch
Thank You.
The problem is this:
$i = 0;
while($i++){
When you do $i++ the variable $i is incremented with one but the value that is returned is still the old value, see the manual on Incrementing/Decrementing operators. So the first time when $i is still 0, the condition evaluates to false and the whole while() loop is never run / your switch is never reached.
To increase first and then return the value, you do:
$i = 0;
while(++$i){
See the example.
Try and make your code more readable by using variables/constants instead of magic numbers and you can also use labels on loops to break/continue on. Here is an example for you:
define("SOMETHING", 5);
define("SOMETHING_ELSE", 10);
$count = 0;
mainLoop:
while($count < 100) { #loop virtually forever
switch(++$count) { #increment and switch on $count in each iteration
case SOMETHING: #$count = 5
#do something here
echo "At 5<br />";
break; #break switch, continue while loop
case SOMETHING_ELSE: #$count = 10
#do something else here
echo "At 10; quitting<br />";
break mainLoop; #break while loop
}
}
I'm working on custom pagination system and encountered following problem. When one of the elements is filtered out of the set, the size of the final array is smaller than needed. Therefore I'm looking for a solution to increase the number of iterations from within the loop to always get array consisting of 50 elements.
$limit = 50; //Number of elements I want to fetch
for($x=0; $x<$limit; $x++){
if ($elementIsNotFiltered) {
//add element to $someArray;
}
else {
//increase the number of iterations, so even if some elements are filtered out,
//the size of $someArray will always be 50
}
}
Thanks for any help.
Do it in a while() loop instead, and break when you finally hit your $limit
Use a while loop.
while(count($somearray) < 50 && /*elements remain*/) ...
else {
++$limit;
}
Tried that?
You may also do the same thing the other way round:
else {
--$x;
}
Or be a little bit more effective:
$x = 0;
while ($x != 50) {
if ($notFiltered) {
++$x;
}
}
If you want to save the counter variable, too, you may use:
while (!isset($array[49])) {
}
The !isset($array[49]) here is only a synonym of count($array) < 50.
It sounds to me like you're looking for a while loop - not a for loop:
while ($items < 50 && [more items to filter]) {
if ([add to array]) {
$items++;
}
}
If you really want to do it in your for loop you can always modify $x but this makes your code unreadable and hard to maintain - I would recommend not doing this...