8

ポールハドソンの素晴らしいオンラインPHPチュートリアルを読んでいる間、彼は言いました

おそらく驚くべきことに、スクリプトでは無限ループが役立つことがあります。無限ループは外部の影響なしに終了することはないため、それらを使用する最も一般的な方法は、条件が一致するたびにループから抜け出すか、ループ内からスクリプトを完全に終了することです。また、ユーザー入力に依存してループを終了することもできます。たとえば、ユーザーが必要なだけデータを入力できるようにするプログラムを作成している場合、スクリプトループを30,000回、さらには300,000,000回実行しても機能しません。 。代わりに、ユーザーがCtrl-Cを押してプログラムを終了するまで、コードは永久にループし、ユーザー入力を常に受け​​入れます。

PHPで無限ループを使用する方法の簡単な実行例を教えてください。

4

12 に答える 12

16

アプリケーションの監視

サーバーの状態を監視し、問題が発生した場合に電子メールを送信するバックグラウンドプロセスがある場合。サーバーを繰り返しチェックするための無限ループがあります(反復の間に一時停止があります)。

クライアントをリッスンするサーバー

接続のためにソケットをリッスンするサーバースクリプトがある場合、それは無限にループし、新しいクライアントが接続するのを待っている間ブロックします。

ビデオゲーム

ゲームには通常、1フレームに1回、無期限に実行される「ゲームループ」があります。

または...定期的なチェックでバックグラウンドで実行し続ける必要があるその他のもの。

于 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

私はこれまでのところ他の答えに反対するつもりです、そしてあなたが物事に注意しているなら、彼らは決して場所を持っていないことを提案します。

シャットダウンしたい条件は常にあるので、少なくともwhile(シャットダウンが要求されていないかどうかをテストする)またはwhile(まだ意味のある実行が可能)である必要があります

実際には、条件を使用せず、sigint to phpのようなものに依存して終了する場合があると思いますが、これは、たとえ機能したとしても、私の意見ではベストプラクティスではありません。

テストをループ内に配置し、失敗した場合に中断するリスクは、将来コードが変更されて、誤って無限のループが作成されやすくなることです。たとえば、whileループの内容を別のループ内にラップすると、突然breakステートメントがwhileループから抜け出せなくなります...

for(;;)またはwhile(1)は可能な限り避ける必要があり、ほとんどの場合可能です。

于 2009-11-19T19:36:31.553 に答える
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);
于 2015-03-07T04:40:24.473 に答える
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

Paul Biggarは、無限ループを使用してバックグラウンドで実行し、LaTeXソースの再構築を継続的に試みるLaTeXプロジェクトのmakeスクリプトを投稿しました。

スクリプトを終了する唯一の方法は、スクリプトを外部で強制終了することです(たとえば、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

可読性を維持するには終了条件が長すぎるループの代わりに、不適切な名前の「無限」ループが最善の方法である場合があります。

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

ポイントが失われていると思います...実際には無限ループはありません(永遠にループに陥ります)。むしろwhile(true){...}、重要な終了条件がある場合(たとえば、サードパーティのライブラリからのものなど)、coは便利です。または、計算に多くの時間がかかるが、ループ内で段階的に計算できる制限、またはユーザー入力に依存するもの)。

forすべてのループが、、whileまたはdoを使用せずにループとして簡潔に記述できるわけではないことは驚くべきことではありませんbreak

于 2009-11-19T20:20:40.497 に答える
-1

無限ループは、(ほとんど)最後の手段であるため、あまり開かない別のツールボックスに保持するツールの1つです。

私が見つけたそれらの最良の使用法は、ステートマシンまたはステートマシンに接近しているループを使用することです。これは、終了条件が通常非常に複雑であり、ループの上部または下部に配置できないためです。

于 2009-11-20T01:48:49.243 に答える