2

I am having a problem with an foreach, that his main propose is to check if a server is up, then access that file, and i'm stuck on an foreach that i want to make it repeat a step. For example i have the following code:

<?php
$Array = array("one","two","tree","four");
next($Array); 

$i = 0;
foreach($Array as $Key=>$Value)
{
    $i++;
    echo "Key=".$Key." VAL=".$Value."<br>";

    if($Key==2) prev($Array);

    if($i==10) break;
}
?>

that is outputing:

Key=0 VAL=one
Key=1 VAL=two
Key=2 VAL=tree
Key=3 VAL=four

and i want to make it that it will output

Key=0 VAL=one
Key=1 VAL=two
Key=2 VAL=tree
Key=2 VAL=tree
Key=2 VAL=tree
Key=2 VAL=tree
Key=2 VAL=tree
Key=2 VAL=tree
Key=2 VAL=tree
Key=2 VAL=tree // till the $i is 10 therefore it's exits the foreach trough break;

and i have tried prev($Array); with no result.

I also been thinking about

while(true)
{
    if(server exists)
    {
         echo "server is good";
         break;
    }
    else
    {
         echo "server is BAD ... continueing";
         prev($Array);
    }
}

but this didn't worked for me either ... Can anyone help me with this??

hakre
  • 193,403
  • 52
  • 435
  • 836
Master345
  • 2,250
  • 11
  • 38
  • 50

8 Answers8

0

You cannot prev($array) in a foreach loop just as already stated you should either iterate with a while or for loop

But beyond that, you will face some other troubles with that anyways..

php is a very linear language, as long as the code is INSIDE such a loop it cannot do anything else so this php has to run as a seperate thread, and as it should do something (return a value) it will lock not only itself but the thread to catch that value too. And it will most likely break after a certain time, you can expand the php max script execution time within that loop to prevent it from dying, but you have to do the same with the getter too.. you shouldn't do something like that (that's why there is no code here)

So if I got you right, you want to access a file on a remote server...

you could simply:

while (!$handle) // file not opened i.e. server not accessible
{
    $handle = fopen("http://www.example.com/", "r"); //try to fopen file
}

This too will be locked inside the loop as long as the $handle is not set OR set to FALSE and it will let your script die after max ececution time (generally 60sec) As soon as the $handle is set to a filehandle for the remote servers html output (in this case) it will execute all following code normally If you're done reading $handle don't forget to close it with

fclose($handle);
itsid
  • 801
  • 7
  • 16
0
$Array = array("one","two","tree","four");

$i = 0;
foreach($Array as $Key=>$Value)
{
    $count = 0;
    // Registra a referência do
    start:

    $i++;
    echo "Key=".$Key." VAL=".$Value."\n";

    if($Key == 2 && $count < 10) {
      // Count
      $count++;
      // Return to start loop
      goto start;
    }
}

// OUTPUT

Key=0 VAL=one
Key=1 VAL=two
Key=2 VAL=tree
Key=2 VAL=tree
Key=2 VAL=tree
Key=2 VAL=tree
Key=2 VAL=tree
Key=2 VAL=tree
Key=2 VAL=tree
Key=2 VAL=tree
Key=2 VAL=tree
Key=2 VAL=tree
Key=2 VAL=tree
Key=3 VAL=four
0

Iterate your array with for() so that you have total control over the incrementation of the counter variable.

Call your server status checking function inside the loop. If the server is down, subtract .9 from the counter. The ++$i in the for() will effectively add .1 on the next iteration. This will mean that the same server will get upto 10 checks before the loop will move onto the next server. If the server is back up before the 10-try limit is reached, just set the counter to its truncated integer value, then the ++$i in the for() will progress to the next item in the array.

Code: (Demo)

$servers = ["one", "two", "tree", "four"];

function isServerDown($server) {
    return $server === 'tree';
}

for ($i = 0, $count = count($servers); $i < $count; ++$i) {
    $server = $servers[(int)$i];
    printf("Key=%d VAL=%s\n", $i, $server);
    $i = isServerDown($server) ? $i - .9 : (int)$i;
}
mickmackusa
  • 43,625
  • 12
  • 83
  • 136
0

This suits your needs:

$arr = array('one', 'two', 'three', 'four');
$val = null;
for ($i = 0; $i < 10; $i++) {
  if (isset($arr[$i])) {
    $val = $arr[$i];
  }
  echo 'key=' . $i . ' val=' . $val . '<br />';
}
RobinUS2
  • 955
  • 6
  • 17
  • This gets stuck at "four" instead of "tree" for me. – jn1kk Feb 07 '12 at 13:48
  • it is actually repeating key=3 val=four , imagine that server two is down , and four is online ... this wouldn't help me, the main reason is to skip offline servers – Master345 Feb 07 '12 at 13:51
  • Hmm, missed that part in his example. I guess he just wants to repeat the last found element in the array and keep repeating it. If he wants to skip the last a simple array_pop() before starting should do the trick. – RobinUS2 Feb 07 '12 at 13:52
0

http://php.net/manual/en/control-structures.foreach.php

Problem #1:

When foreach first starts executing, the internal array pointer is automatically reset to the first element of the array

Thus, your first next() call is useless.

Problem #2:

As foreach relies on the internal array pointer changing it within the loop may lead to unexpected behavior.

jn1kk
  • 5,012
  • 2
  • 45
  • 72
0

Foreach is ideally suited to arrays as skynorth mentioned with a finite size.

For this I would recommend a Do While loop which guarantees atleast one execution of the loop allowing you to do your checks on the server.

tomaytotomato
  • 3,788
  • 16
  • 64
  • 119
0

I think you are after something like this:

<?php
$myArray = array('one','two','tree','four');
$length = count($myArray );
$attempts = 0;

for ($i = 0; $i < $length; ++$i) {
    echo 'Key=' . $i . ' VAL=' . $myArray[$i] . '<br>';
    if ($i === 2) {
        --$i;
    }

    if (attempts >= 10) {
        break;
    }
    ++$attempts;
}
?>

Notes.

Regardless of the size of the array this ends after 10 iterations. If your array was 20 items long, this just isn't going to work.

I'm assuming you have some actual condition that you wish to use rather than checking for an item with a key of 2, in which case it might make more sense to limit the attempts at the specific condition rather than limiting against the entire array - but you know your requirements best and can ask for more help on that if you want it.

Fenton
  • 241,084
  • 71
  • 387
  • 401
0
for ($i = 0; $i < count($Array) - 2; $i++) {
     echo "Key=$i VAL={$Array[$i]}\n";
}
for ($j = $i; $j < 10; $j++) {
     echo "Key=$i VAL={$Array[$i]}\n";    
}
JRL
  • 76,767
  • 18
  • 98
  • 146
  • and do you think it will work with http://neo22s.com/check-if-url-exists-and-is-online-php/ ? i'm trying but ... no results, i need to know if a server is down, and if it is down, go to the next server – Master345 Feb 07 '12 at 14:09