sleep — 実行を秒単位で一時停止する

PHP
  • カテゴリ: PHP
  • 掲載バージョン:PHP 8.4
  • 名前空間 / FQCN / コマンド: sleep
  • 関連: usleep / time_nanosleep / time_sleep_until / set_time_limit
  • 変更履歴: 特になし

要点(TL;DR)

  • 指定した秒数だけ処理をブロックする関数
  • 最低限の使い方:sleep(2);
  • よくある罠
    • Web実行(FPM/Apache)で使うとワーカーを占有してスループット低下
    • max_execution_time を超えるとタイムアウト
    • サブ秒は止められない(usleep/time_nanosleep を使う)

概要

sleep は現在のスレッド(プロセス)の実行を、引数で指定した秒数だけ停止します。CLI の簡易ウェイトや、API リトライの間隔確保などに向きます。HTTP リクエスト中に用いると処理スロットを占有するため、基本的にバッチ・キュー処理での利用が安全です。

構文 / シグネチャ

int sleep(int $seconds)
  • 引数(表) 引数 型 必須 既定値 説明 $seconds int ✔ — 停止する秒数(0以上の整数)
  • 戻り値int — 成功時は 0。シグナルなどで割り込まれた場合は残り秒数を返します。
  • 例外/副作用
    • プロセスをブロックします(非並列)。
    • 実行時間制限(max_execution_time)に達するとスクリプトが終了します。
    • 無効な引数(負値等)ではエラーになります(環境によっては ValueError になることがあります)。

使用例

最小例

<?php
// 2秒待ってから出力
echo "start\n";
sleep(2);
echo "done\n";

実務例:HTTP のリトライ間隔にスリープ(指数バックオフ)

<?php

function getWithRetry(string $url, int $maxRetries = 3, int $initialWait = 1): string
{
    $wait = $initialWait;

    for ($attempt = 1; $attempt <= $maxRetries; $attempt++) {
        $ch = curl_init($url);
        curl_setopt_array($ch, [
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_TIMEOUT => 10,
            CURLOPT_FOLLOWLOCATION => true,
        ]);
        $body = curl_exec($ch);
        $err  = curl_error($ch);
        $code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);

        if ($err === '' && $code >= 200 && $code < 300 && $body !== false) {
            return $body;
        }

        if ($attempt < $maxRetries) {
            // 次の試行まで待機(1, 2, 4, ... 秒)
            sleep($wait);
            $wait *= 2;
        }
    }

    throw new RuntimeException("Request failed after {$maxRetries} attempts.");
}

// 使い方
try {
    $json = getWithRetry('https://httpbin.org/status/200');
    echo substr($json, 0, 80) . "...\n";
} catch (RuntimeException $e) {
    error_log($e->getMessage());
}

よくある落とし穴・注意

  • Web実行での使用は慎重に:FPM/Apache のワーカーを占有し、同時処理数を圧迫。キュー(cron/queue)に退避する。
  • 時間制限sleep(60) でも max_execution_time=30 なら途中でFatal timeout。必要に応じて set_time_limit を調整。
  • 精度:秒単位で粗いウェイト。サブ秒は usleep(マイクロ秒)/time_nanosleep を使う。
  • 割り込み:シグナルで中断されると残り秒数を返すことがある(CLI+pcntl_* 利用時など)。
  • PHPカテゴリ付記
    • 必要拡張:なし(コア)
    • エラー形態:無効引数でエラー(環境により例外/警告)。
    • エンコーディング:非該当
    • 8.1/8.2/8.3/8.4差分:機能差は実務上ほぼ無し

代替・関連APIとの比較

  • usleep(int $microseconds)マイクロ秒単位で待機。サブ秒が必要ならこちら。
  • time_nanosleep(int $seconds, int $nanoseconds)ナノ秒精度の待機。より細かな制御。
  • time_sleep_until(float $timestamp):UNIXタイムスタンプまでぴったり待機したい場合に有用。
  • set_time_limit(int $seconds):スクリプトの実行時間制限を延長。長いスリープを行う前に検討。
  • (非ブロッキング代替)待機を避けたいならジョブキューや**スケジューラ(cron)**へ委譲。

テスト例(Pest)

<?php
it('sleeps about the given seconds', function () {
    $start = microtime(true);
    sleep(1);
    $elapsed = microtime(true) - $start;

    expect($elapsed)->toBeGreaterThanOrEqual(0.95)
                    ->toBeLessThan(1.30);
});

トラブルシュート(エラー別)

症状/エラー原因対処
Maximum execution time of N seconds exceededmax_execution_time を超過set_time_limit() で延長、または処理をジョブ化
期待より早く復帰するシグナル等で割り込み戻り値(残り秒数)を確認し再スリープ/割り込み要因を除去
sleep(): ... seconds must be >= 0(警告/例外)負の秒数0以上の整数に修正/バリデーション追加
Webで応答が遅い/詰まるワーカー占有スリープを排し、非同期処理・キューへ移行

参考リンク

レン (Wren)

こんにちは。レンです。

Laravelのコードの森に住んでいる、小さな案内役です。
ルーティングの枝やクラスの影を歩きながら、コードの流れや仕組みを眺めています。

このサイトでは、Laravelの基本から実装のコツまで、開発で役立つポイントを静かに整理しています。
難しいことを増やすのではなく、コードの見通しが少し良くなるヒントを届けるのが役目です。

「この処理はどこに書くのがいいのか」
「Laravelではどう考えると整理できるのか」

そんな疑問に、小さなメモを残すような気持ちで記事を書いています。

コードを書いている途中で迷ったとき、
このサイトが少し立ち止まって整理できる場所になればうれしいです。

レン (Wren)をフォローする