8

在阅读 Paul Hudson 的优秀在线PHP教程时,他说

也许令人惊讶的是,无限循环有时对您的脚本很有帮助。由于无限循环在没有外部影响的情况下永远不会终止,因此最流行的使用方法是在条件匹配时跳出循环和/或完全从循环内退出脚本。您还可以依靠用户输入来终止循环 - 例如,如果您正在编写一个程序来接受人们输入数据的时间,那么让脚本循环 30,000 次甚至 300,000,000 次是行不通的. 相反,代码应该永远循环,不断地接受用户输入,直到用户按下 Ctrl-C 结束程序。

请给我一个简单的运行示例,说明如何在 PHP 中使用无限循环?

4

12 回答 12

16

监控应用程序

如果您有一个后台进程来监控服务器的状态并在出现问题时发送电子邮件。它将有一个无限循环来重复检查服务器(迭代之间有一些暂停。)

服务器监听客户端

如果您有一个服务器脚本侦听套接字的连接,它将无限循环,在等待新客户端连接时阻塞。

视频游戏

游戏通常有一个“游戏循环”,每帧运行一次,无限期地运行。

或者......任何其他需要通过定期检查在后台继续运行的东西。

于 2009-11-19T19:04:39.433 回答
5

如果你实现了一个套接字服务器(取自:http ://devzone.zend.com/article/1086 ):

    #!/usr/local/bin/php –q

<?php
// Set time limit to indefinite execution
set_time_limit (0);

// Set the ip and port we will listen on
$address = '192.168.0.100';
$port = 9000;
$max_clients = 10;

// Array that will hold client information
$clients = Array();

// Create a TCP Stream socket
$sock = socket_create(AF_INET, SOCK_STREAM, 0);
// Bind the socket to an address/port
socket_bind($sock, $address, $port) or die('Could not bind to address');
// Start listening for connections
socket_listen($sock);

// Loop continuously
while (true) {
    // Setup clients listen socket for reading
    $read[0] = $sock;
    for ($i = 0; $i < $max_clients; $i++)
    {
        if ($client[$i]['sock']  != null)
            $read[$i + 1] = $client[$i]['sock'] ;
    }
    // Set up a blocking call to socket_select()
    $ready = socket_select($read,null,null,null);
    /* if a new connection is being made add it to the client array */
    if (in_array($sock, $read)) {
        for ($i = 0; $i < $max_clients; $i++)
        {
            if ($client[$i]['sock'] == null) {
                $client[$i]['sock'] = socket_accept($sock);
                break;
            }
            elseif ($i == $max_clients - 1)
                print ("too many clients")
        }
        if (--$ready <= 0)
            continue;
    } // end if in_array

    // If a client is trying to write - handle it now
    for ($i = 0; $i < $max_clients; $i++) // for each client
    {
        if (in_array($client[$i]['sock'] , $read))
        {
            $input = socket_read($client[$i]['sock'] , 1024);
            if ($input == null) {
                // Zero length string meaning disconnected
                unset($client[$i]);
            }
            $n = trim($input);
            if ($input == 'exit') {
                // requested disconnect
                socket_close($client[$i]['sock']);
            } elseif ($input) {
                // strip white spaces and write back to user
                $output = ereg_replace("[ \t\n\r]","",$input).chr(0);
                socket_write($client[$i]['sock'],$output);
            }
        } else {
            // Close the socket
            socket_close($client[$i]['sock']);
            unset($client[$i]);
        }
    }
} // end while
// Close the master sockets
socket_close($sock);
?> 
于 2009-11-19T19:04:51.613 回答
3

也许在您编写命令行 PHP 应用程序时它很有用?因为当 PHP 脚本由 web 服务器(Apache 或任何其他)运行时,它们的生命周期默认限制为 30 秒(或者您可以在配置文件中手动更改此限制)。

于 2009-11-19T19:05:12.940 回答
2

There are many ways to use infinite loops, here is an example of an infinite loop to get 100 random numbers between 1 and 200

$numbers = array();
$amount  = 100;

while(1) {
   $number = rand(1, 200);
   if ( !in_array($number, $numbers) ) {
      $numbers[] = $number;
      if ( count($numbers) == $amount ) {
         break;
      }
   }
}

print_r($numbers);
于 2015-03-07T04:40:24.473 回答
2

到目前为止,我将不同意其他答案,并建议,如果你对事情很小心,它们永远不会占有一席之地。

总有一些你想要关闭的情况,所以至少应该是 while(测试是否未请求关闭) 或 while(仍然能够有意义地运行)

我认为实际上有时人们不使用条件并依赖诸如 sigint 到 php 之类的东西来终止,但在我看来这不是最佳实践,即使它有效。

将测试置于循环中并在失败时中断的风险在于,它使将来更容易修改代码以无意中创建无限循环。例如,您可能将 while 循环的内容包装在另一个循环中,然后突然 break 语句并没有让您退出 while...

应尽可能避免使用 for(;;) 或 while(1),而且几乎总是可以的。

于 2009-11-19T19:36:31.553 回答
1

在创建命令行应用程序时,无限循环特别有用。然后应用程序将运行,直到用户告诉它停止。(例如,当用户输入为“退出”时添加中断/退出语句)

while (true) {
  $input = read_input_from_stdin();

  do_something_with_input();

  if ($input == 'quit') {
    exit(0);
  }
}
于 2009-11-19T21:05:43.257 回答
0

我正在考虑猜数字游戏,用户必须猜测随机(或不)生成的数字,因此,他必须输入数字,直到他得到它。那是你需要的吗?

于 2009-11-19T19:04:58.417 回答
0

有时,与退出条件太长而无法保持可读性的循环相比,命名不当的“无限”循环可能是最好的方法。

<?php

while(1) {
  // ... 
  $ok=preg_match_all('/.../',$M,PREG_SET_ORDER);
  if (!$ok) break;

  switch(...) { ... }

  // match another pattern
  $ok=preg_match('/.../',$M,PREG_SET_ORDER);
  if (!$ok) break;

  //and on, and on...
}
于 2009-11-19T19:16:26.850 回答
0

Paul Biggar为 LaTeX 项目发布了一个make 脚本,该脚本使用无限循环在后台运行,并不断尝试重建 LaTeX 源代码。

终止脚本的唯一方法是在外部终止它(例如使用Ctrl+ C)。

(当然,不是 PHP(实际上是 Bash),但同样的脚本也可以用 PHP 来实现。)

于 2009-11-19T19:08:21.483 回答
0

对于用户输入...

while True:
    input = get_input_from_user("Do you want to continue? ")
    if input not in ("yes", "y", "no", "n"):
        print "invalid input!"
    else: 
        break
于 2009-11-19T19:12:43.533 回答
0

我认为错过了一点......实际上并没有无限循环(你会永远被困在其中),而是while(true){...}当你有非平凡的退出条件时(例如来自第三方库的那些,或者一个需要花费大量时间来计算但可以在循环内部逐步计算出来的限制,或者依赖于用户输入的东西)。

并非每个循环都可以简明扼要地表述为for,whiledo不使用break.

于 2009-11-19T20:20:40.497 回答
-1

无限循环是您保存在单独工具箱中的工具之一,它不会被打开太多,因为它是(几乎)最后手段的工具。

我发现它们的最佳用途是用于状态机或接近状态机的循环。这是因为退出条件通常非常复杂,不能放在循环的顶部或底部。

于 2009-11-20T01:48:49.243 回答