PHP中用于无限循环的Idom?

8

在阅读Paul Hudson的PHP教程时,他说:

也许令人惊讶的是,在脚本中无限循环有时会很有用。由于无限循环不会在没有外部影响的情况下终止,使用它们最常见的方法是在循环内部匹配条件时打破循环和/或完全退出脚本。您还可以依靠用户输入来终止循环-例如,如果您正在编写一个程序以接受人们键入数据,只要他们想要,脚本就不能循环30,000次甚至300,000,000次。相反,代码应该永久循环,不断接受用户输入,直到用户通过按Ctrl-C结束程序。

请给我一个简单的PHP无限循环使用示例,谢谢!


以下是一个使用无限循环的简单PHP示例:
```php while (true) { // 这里是你的代码 } ```
这个循环将一直运行,直到遇到 `break` 或 `exit` 命令才停止。您可以根据需要添加条件来控制循环何时停止,如下所示:
```php while (true) { if ($condition == true) { break; // 当满足条件时跳出循环 } // 这里是你的代码 } ```
您还可以使用用户输入来控制循环何时停止,如下所示:
```php while (true) { $input = readline("请输入数据:"); if ($input == "exit") { break; // 当用户输入“exit”时跳出循环 } // 这里是你的代码 } ```

你应该修改问题,更好地反映出你想要一个 PHP 无限循环的示例。 - emptyset
我编辑了问题标题,加入了 PHP。 - Ben S
12个回答

16

应用程序监控

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

服务器监听客户端

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

视频游戏

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

或者……任何需要在后台定期检查并保持运行的东西。


5
你有看过使用 PHP 语言编写的电子游戏吗? - Sergey Kuznetsov
6
@Sergey:当然,为什么不呢?PHP有一些图形库。如果你想的话,你可以用PHP写一个游戏。我提到这个是因为它是无限循环的经典例子。 - Ben S
@Ben S:当然,但是使用PHP语言编写视频游戏是一件非常头疼的事情,我认为 :) - Sergey Kuznetsov
2
我认为PHP不适合实时应用。但我曾经读过一次,如果你想使用它,没有什么能阻止你! - taabouzeid
@taabouzeid PHP在CLI环境下实际上非常有能力。它不是万能工具,但它的功能和适用于长时间运行的任务与Python等语言一样强大。这完全取决于开发人员编写软件时最熟悉的语言。 - Ieuan

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);
?> 

3

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


是的,我也很好奇怎样让它在硬限制生命周期为30秒(在php.ini中)的情况下无限制地运行。 - Jakub

2

有很多种方法可以使用无限循环,这里是一个获取1到200之间100个随机数的无限循环示例:

$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);

2
我不同意到目前为止其他回答的观点,并建议,如果您对事情很谨慎,它们永远没有用处。
总会有一些条件需要关闭,因此至少应该是 while(测试是否未请求关闭) 或 while(仍然能够有意义地运行)。
我认为,在实际情况下,有时人们不使用条件,而是依靠像 sigint 到 php 这样的东西来终止,但我认为这不是最佳实践,即使它可以工作。
将测试放置在循环内部并在失败时中断的风险是,它使将来修改代码以无意中创建无限循环变得更容易。例如,您可能会将 while 循环的内容包装在另一个循环中,突然间,break 语句就无法让您退出 while...
应尽可能避免使用 for(;;) 或 while(1),几乎总是可以避免。

1
无限循环在创建命令行应用程序时非常有用。应用程序将一直运行,直到用户告诉它停止。(例如,在用户输入“quit”时添加一个break/exit语句)
while (true) {
  $input = read_input_from_stdin();

  do_something_with_input();

  if ($input == 'quit') {
    exit(0);
  }
}

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

如果标准输入(stdin)被关闭,你会得到一个异常:ValueError:I/O operation on closed file。 - Jason Orendorff

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...
}

在Python中,这是你无法避免的事情,但循环并不真正意味着不结束。 - ZJR
有时使用 do { ... } while($condition); 会更加合适。 - ZJR

0

我在考虑猜数字游戏,用户需要猜测随机(或非随机)生成的数字,因此他将不断输入数字直到猜中为止。 这是你需要的吗?


0

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

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

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接