【PHP】実行時間を無制限にする
PHPで長時間の処理を走らせているときにタイムアウトでプログラムが停止することがあります。
いくら時間がかかってもいいのですべての処理を終えたいときには実行時間を無制限に意図的にする必要があります。
無制限にする方法
まずは結論から書くと、PHPの実行時間を無制限にする方法は次の3つがあります。
①実行PHPファイル
実行するPHPスクリプトが書かれているファイルに次を記述します。
<?php
ini_set('max_execution_time', 0);
?>
※無制限は実行ファイルのみ有効
②「.htaccess」
サーバー設定ファイル「.htaccess」に次を記述する。
php_value max_execution_time 0
※ 無制限は 「.htaccess」があるディレクトリ以下で有効
③「php.ini」
設定ファイル「php.ini」に次を記述する。
max_execution_time = 0
※ 無制限は PHP実行すべてに有効
以上のいずれかを書けば 「max_execution_time」 が「0」(無制限)となります。
なお、後述していますが、無制限を適用した処理をブラウザから行う場合は「ignore_user_abort」も同時に設定するとよいと思います。
留意事項
なお、PHPがCGIではなくセーフモード(レンタルサーバーに多い?)で動いている場合、これらの操作は無効です。
セーフモードかどうかを調べる場合はPHPファイル内で次のスクリプトを実行してください。
if(ini_get('safe_mode')){
echo "セーフモードです";
}else{
echo "CGIです";
}
「max_execution_time」 について
まず前提として、PHPの最大実行時間は 設定ファイル「php.ini」の「max_execution_time」にて決められています( 秒数表示)。
実際にphpinfo関数で調べると・・・
このように30秒が指定されているので、PHP実行時間が30秒を超えるとその処理が停止されます。
注意
「max_execution_time」 の設定値が「30」だった場合、あらゆる処理が30秒でタイムアウトするかというとそうではありません。
関数 set_time_limit() と設定ディレクティブ max_execution_time は、 このスクリプト自体の実行時間にのみ影響を与えます。 system() を用いたシステムコール、ストリーム操作、 データベースクエリ等のスクリプト実行以外で発生する処理にかかった時間は スクリプトが実行される最大時間を定義する際には含まれません。 ただし、Windows ではこれは当てはまりません。 計測された時間は実際の時間と等しくなります。
つまり「スクリプト自体の実行時間」とあるように、次の関数はノーカウントです。
- sleep関数
- file_get_contents関数
- mysql_query関数
- exec関数
例えば、sleep関数で20秒スリープさせても、PHPの純粋な処理が別に30秒実行されないとタイムアウトされません。
※PHPでの動画編集のためにffmpegをexecで叩いとき、60分以上処理が走り続けたこともあります
「max_execution_time」 の変更
ということで、 「max_execution_time」 の値を変更してあげるとPHPの処理時間を変更できます。
その変更方法ですが、記述方法が2つ、 記述場所が3つあるので合計6パターンあります。
記述方法
記述方法(使用する関数)は次の2つがあります。
ini_set('max_execution_time', ここに秒数);
set_time_limit(ここに秒数);
ただし、これら2つには違いがないようなので前者のみを使って説明します。
記述場所
記述する場所は次の3つがあります。
- 実行させるPHPファイル
- サーバー設定ファイル「.htaccess」
- php.ini
1.実行させるPHPファイル
実行させるPHPファイルに次のように記述すれば 「max_execution_time」 の値を変更できます。
<?php
ini_set('max_execution_time', ここに秒数);
?>
例えば600秒(10分)を設定すると・・・
このように 「max_execution_time」 が600秒に変わります(右の数値がデフォルト値)。
この方法はファイルごと、場所ごとに記述できるので「この処理だけ実行時間を○秒にしたい!」というときに有効です。
2.「.htaccess」
「.htaccess」に次を記述しても同じです。
php_value max_execution_time 600
この場合、この設定ファイルがあるディレクトリ以下すべてのPHP実行時間が600秒に変更されます。
この方法は、あるサーバーのディレクトリ内の処理時間だけ変更したいときに役立ちます。
3.「php.ini」
次に、PHP設定ファイル「php.ini」に次を記述してもOKです。
max_execution_time = 600
この方法は、PHPすべての処理に適用されます。
Tips
引き延ばし
PHPファイルの中で「max_execution_time」の変更は何度でもできます。しかも、変更する度にそこからアイムアウト時間が引き延ばされます(足し算される)。
例えば・・・
<?php
ini_set('max_execution_time', 60); //ここから60秒後にタイムアウト
//なんやかんや処理があって35秒でここまできた(残り25秒)
ini_set('max_execution_time', 60); //60秒延長される(残り85秒)
?>
もっと言うならば、ループ中に使用すると、そのたびにタイムアウト時間を引き延ばすことができます(上限値を超えたら強制終了のリスクあり?)。
<?php
foreach(){
ini_set('max_execution_time', 60);//再リセット
}
?>
ちなみに、現在の設定値を取得することも可能です。
<?php
ini_set('max_execution_time', 60);
echo = ini_get('max_execution_time'); //「60」秒と出力される
ini_set('max_execution_time', 300);
echo = ini_get('max_execution_time'); //「300」秒と出力される
?>
ブラウザからの処理
ブラウザから無制限タイムアウトを適用させたPHPを実行する場合、処理が全て完了するまで待ち続けなければなりません(ブラウザを閉じたり接続が切断されたら処理はそこで中断する)。
しかし、無制限とした処理を終わるまでそのままじっと待つのはナンセンスです。
そのため、ブラウザを閉じたり接続が切断された後も処理が継続されるように設定しましょう。
1.実行させるPHPファイル
<?php
ignore_user_abort(true);
ini_set('max_execution_time', 0);
?>
2.「.htaccess」
php_value ignore_user_abort On
php_value max_execution_time 0
3.「php.ini」
ignore_user_abort = On
max_execution_time = 0
終わりに
私は「.htaccess」での設定が好きなので次のようにしています。
php_value ignore_user_abort On
php_value max_execution_time 86400
「86400」のところを「0」にしてもいいのですが、万が一無限ループに陥った場合、ほんとに無限まで処理が継続されるので1日(86400秒)にしています。
あわせて読んでほしい!
コメント
まだコメントはありません。