PHP 中的 Idom 无限循环?

发布于 2024-08-12 08:18:34 字数 385 浏览 4 评论 0原文

在阅读 Paul Hudson 的精彩在线 PHP 教程时,他说

也许令人惊讶的是,无限循环 有时可以对您有所帮助 脚本。因为无限循环永远不会 在没有外界影响的情况下终止, 最流行的使用方式是 跳出循环和/或退出 完全在循环内编写脚本 每当条件匹配时。你 也可以依赖用户输入 终止循环 - 例如,如果 你正在编写一个程序来接受 人们输入数据的时间长达 他们想要,但行不通 让脚本循环 30,000 次或 甚至三亿次。相反, 代码应该永远、不断地循环 接受用户输入,直到用户 按 Ctrl-C 结束程序。

您能给我一个如何在 PHP 中使用无限循环的简单运行示例吗?

While reading through the great online PHP tutorials of Paul Hudson he said

Perhaps surprisingly, infinite loops
can sometimes be helpful in your
scripts. As infinite loops never
terminate without outside influence,
the most popular way to use them is to
break out of the loop and/or exit the
script entirely from within the loop
whenever a condition is matched. You
can also rely on user input to
terminate the loop - for example, if
you are writing a program to accept
people typing in data for as long as
they want, it just would not work to
have the script loop 30,000 times or
even 300,000,000 times. Instead, the
code should loop forever, constantly
accepting user input until the user
ends the program by pressing Ctrl-C.

Would you please give me a simple running example of how to use infinite loops in PHP ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(12

酒儿 2024-08-19 08:18:34

监控应用程序

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

服务器侦听客户端

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

视频游戏

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

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

Monitoring applications

If you have a background process that monitors the state of your servers and sends an email if trouble occurs. It would have an infinite loop to repeatably check the servers (with some pause between iterations.)

Server listening for Clients

If you have a server script that listens to a socket for connections, it will loop infinitely, blocking while waiting for new clients to connect.

Video Games

Games usually have a "game loop" that runs once a frame, indefinitely.

Or... anything else that needs to keep running in the background with periodic checks.

隱形的亼 2024-08-19 08:18:34

如果您实现了套接字服务器(取自: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);
?> 

If you implemented a socket server (taken from: 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);
?> 
ゞ记忆︶ㄣ 2024-08-19 08:18:34

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

Maybe it useful when you write a command line PHP application? Because when PHP-scripts runs by web-server (Apache or any other) they lifetime is limited by 30 seconds by default (or you can manually change this limit at the configuration file).

一张白纸 2024-08-19 08:18:34

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

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

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

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

for(;;) 或 while(1) 应避免只要有可能,而且几乎总是有可能。

I'm going to disagree with the other answers so far, and suggest that, if you're being careful about things, they never have a place.

There is always some condition in which you want to shut down, so at the very least, it should be while(test if shutdown not requested) or while(still able to meaningfully run)

I think practically there are times when people don't use the condition and rely on things like sigint to php to terminate, but this is not best practice in my opinion, even if it works.

The risk of putting the test inside the loop and breaking if it fails is that it makes it easier for the code to be modified in the future to inadvertently create an endless loop. For example, you might wrap the contents of the while loop inside another loop, and then all of a sudden the break statement doesn't get you out of the while...

for(;;) or while(1) should be avoided whenever possible, and it's almost always possible.

溺孤伤于心 2024-08-19 08:18:34

使用无限循环的方法有很多种,下面是一个无限循环的示例,用于获取 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);

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);
拿命拼未来 2024-08-19 08:18:34

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

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

  do_something_with_input();

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

Infinite loops are particulary useful when creating command line applications. The application will then run until the user tells it to stop. (add a break/exit-statement when the user input is "quit", for instance)

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

  do_something_with_input();

  if ($input == 'quit') {
    exit(0);
  }
}
木有鱼丸 2024-08-19 08:18:34

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

I'm thinking about the guess-the-number game, where the user has to guess the randomly (or not) generated number, so, he'll have to enter numbers until he gets it.
Is that what you needed ?

合久必婚 2024-08-19 08:18:34

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

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

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

Paul Biggar has posted a make script for LaTeX projects which uses an infinite loop to run in the background and continually tries to rebuild the LaTeX sources.

The only way to terminate the script is to kill it externally (e.g. using Ctrl+C).

(Granted, not PHP (Bash, actually) but the same script could well be implemented in PHP instead.)

浮生面具三千个 2024-08-19 08:18:34

对于用户输入...

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

For user input...

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
因为看清所以看轻 2024-08-19 08:18:34

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

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

Sometimes instead of a loop which would have an exit condition too long to preserve readability an improperly named "infinite" loop may be the best way to go.

<?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...
}
我也只是我 2024-08-19 08:18:34

我认为有一点被忽略了......并没有真正的无限循环(你会永远陷入其中),而是 while(true){...} 和 co 当你具有重要的退出条件(例如,来自第三方库的退出条件,或者需要花费大量时间来计算但可以在循环内逐步计算出来的限制,或者依赖于用户输入的东西)。

不足为奇的是,并非每个循环都可以在不使用 break< 的情况下简洁地表述为 forwhiledo 循环。 /代码>。

I think a point is being missed... there aren't really infinite loops (you would be stuck in them forever), rather while(true){...} and co are useful when you have non trivial exit conditions (e.g. those coming from a third-party library, or a limit which would take a lot of time to calculate but can be worked out incrementally inside of the loop, or something relying on user input).

It shouldn't be surprising that not every loop can be concisely stated as a for, while or do loop without using break.

农村范ル 2024-08-19 08:18:34

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

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

Infinite loops are one of those tools you keep in a separate toolbox that doesn't get opened much as it is a tool of (almost) last resort.

The best use I have found for them is with state machines or loops that are approaching state machines. This is because the exit condition is usually quite complex and cannot be put at the top or the bottom of the loop.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文