質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Q&A

解決済

4回答

13424閲覧

PHPで時間のかかる処理を実行する方法

msx2

総合スコア174

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

1グッド

3クリップ

投稿2016/02/23 02:57

編集2016/02/23 10:11

PHPを使ってデータを処理するツールを作っています。
ブラウザ上で条件を指定して実行する簡単なページで、条件により数時間かかる可能性があります。

現状ではタイムアウトが設定されているので時間のかかる処理は完了することができていません。
もちろん何時間かかろうと終わらせたい処理もあるのでタイムアウトをなしにすればいいと思いますが、タイムアウトなしで本当に終わらない処理(バグで無限ループ等)を実行してしまった場合に一体どうなってしまうのか理解していません。

とりあえずはブラウザ上で進捗状況を確認したいのと、処理を中断できる機能を追加したいのですが、ブラウザを閉じてしまった場合はどうしたらいいのか疑問はつきません。

前置きが長くなってしまいましたが、このような重い処理をブラウザから実行する場合に皆様はどのようにしているのかアドバイスいただければと思い質問しました。

具体的な実装でなく考え方でも大変ありがたいです。
よろしくお願いします。

fumi35👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sonor_3rd

2016/02/23 03:04

処理が重いとなると、仕様や設計、コーディングに問題があるように思われます。 処理時間を改善する余地はないのでしょうか。
msx2

2016/02/23 03:17

ありがとうございます。 処理件数が増えるとどうしても時間がかかってしまうんです。件数を絞る訳にもいかないので。。 応答速度よりも確実に終わらせることを求めています。終わらせるというのは成功して完了でも中断でも何でも構いません。 本来であればバッチ処理するものだと思いますが、今回はブラウザからの実行が要件です。
ngyuki

2016/02/23 06:44

関連する質問は別の質問にした方が良いと思います
msx2

2016/02/23 10:10

勝手がわからず失礼しました。 別途質問させていただきます。
guest

回答4

0

ベストアンサー

個人的な見解では、Apache(mod_php) で PHP の exec 系の関数をバックグラウンドで実行するのはいろいろ辛みがあるので、

あまり簡単な実装ではないですが、例えば次のような感じでしょうか。

  • Gearmand や RabbitMQ などのキューサーバを立てる
  • Redis などの適当な KVS を立てる
  • daemontools とか supervisord でワーカープロセスを常時起動してキューサーバに接続する
  • ブラウザからキューサーバにジョブを登録する
    • キューサーバに接続したワーカーがジョブを取り出して実行する
  • ワーカーは KVS に進捗状況を書き込む
    • ブラウザでその進捗状況を取り出して表示する
  • KVS には中断を意味するフラグも書き込めるようにしておく
    • ワーカーは定期的にそのフラグを読み込んで ON なら中断する
    • ブラウザからそのフラグに書き込むと処理が中断される
    • バグにより無限ループ、とかだとどうしようもない。。

投稿2016/02/23 04:08

ngyuki

総合スコア4514

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

msx2

2016/02/23 04:34

ご回答ありがとうございます。 なかなか難しそうな実装で手が出そうにありませんが…。 データベースを使うという発送をいただいて少し考えてみると、単純に処理のループ内で進捗をデータベースに書き込んだり、フラグをチェックして中断する方法が浮かびます。 キューサーバーとかはよくわからないので非同期実行ということになりますが、バックグラウンド実行はあまり推奨されない方法なのでしょうか?
ngyuki

2016/02/23 06:43

非奨励ということはないと思います。それほど長い処理でないのなら簡単で良いと思います、が、その方法で数時間のも処理を実行させるというのはちょっと聞いたことがありません
msx2

2016/02/23 10:17

なるほど、長時間動かすのはあまり聞かないのですね。 おかげさまでどうやって作ればいいのか少しイメージできました。
msx2

2016/02/23 10:23

すいません、cronに登録してPHPスクリプトで数時間かかる処理を実行するのは一般的でしょうか?
ngyuki

2016/02/23 10:28

一般的かどうかはともかく、日次バッチや月次バッチであれば数時間も無くはないと思います。ただ、質問に記載のような要件(オンデマンドでの実行)だと、実行のインターバルは 1分毎とかにするということですよね? ちょっと聞いたことはないです。
ngyuki

2016/02/23 10:31

ただ、データベースから検索条件を取り出すときに select -> delete で取り出すようにすれば(次のインターバルで実行されるスクリプトがジョブを実行してしまわないように)大丈夫だとは思います。そのスクリプトがなんらかの原因で異常終了とかしたらそのジョブは失われますけれども。
guest

0

とりあえずブラウザで実行途中から切り離して

exec("nohup php -c '' 'xxxx.php' '{$param1}' '{$param2}' > /dev/null &");

あとはファイルでもDBでも通して相互に状況確認すればいいんじゃないですかね。
無限ループは勝手にタイムアウトさせるか、適当に状況変えて抜ければいいと思います。

投稿2016/02/23 09:19

pochi0701

総合スコア210

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

msx2

2016/02/24 00:04

ありがとうございます。 ブラウザの処理からは切り離す方法で検討しています。 無限ループは発生しないように気をつけます。
guest

0

非同期処理については、コメントがついていたので、別アプローチを

夜間バッチ処理用に コマンドライン処理があったという理由もあるのですが、
0. Web から検索条件のみを入力し、データベースに登録。
0. cron 等で、バッチ処理プログラム起動して、データベースから検索条件を取り出し、作成。
0. 作成が成功したら 登録されたメールアドレス宛に 表示(ダウンロード)用 URL を送信。

ということをやっているシステムもあります。

投稿2016/02/23 03:30

CHERRY

総合スコア25171

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

CHERRY

2016/02/23 03:33

あ、書いている間に 補足が追加されていました。 バッチ処理は、対象外なんですね。 消すほどでもないと思うので、そのままにしておきます。
msx2

2016/02/23 04:19

ありがとうざいます。 確かに今回はバッチ処理は対象外ですが、データベースに検索条件を登録→別の処理からデータベースを読み込んで実行という発想はなかったのでとても参考になりました。 データベースを使えば処理間の連携が可能ですよね。何でも一連の処理でやらないといけないと思いこんでいたのでこの回答はありがたかったです!
guest

0

進捗状況の確認や中断は実装したことがないのですが、

>重い処理をブラウザから実行する場合
については、処理部分を非同期にしています。
ブラウザから処理を実行開始すると、次のページへの遷移などは即時やってくれるのですが、裏では重い処理をやってる…という感じです。

弊社では、実行コマンドをPHPから叩く(exec関数)ような実装にしています。
(フレームワーク等により実装方法がいろいろあるかもしれないので、詳しくは「PHP 非同期」で検索してみてください)

投稿2016/02/23 03:06

takushi168

総合スコア228

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

msx2

2016/02/23 04:12

ありがとうございます。 非同期で実行させる方法調べてみます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問