2017-02-10 5 views
0

私は約140のURLを含むデータベースを持つPHPアプリケーションを構築しています。PHP curlで多くのWebページをダウンロード

目的は、これらのWebページのコンテンツのコピーをダウンロードすることです。

私はすでに自分のデータベースからURLを読み取って、curlを使ってページのコピーを取得するコードを書いています。その後、<body> </body>の間のすべてを取得し、ファイルに書き込みます。また、リダイレクトも考慮されます。私がURLに行き、応答コードが302であれば、それは適切なリンクに従います。ここまでは順調ですね。

これはすべてURLの数(多分20秒程度)でもOKですが、max_execution_timeが30秒に設定されているため、スクリプトのタイムアウトが発生します。私はそれを無効にするか、またはこれを増やしたくない。私はそれが貧弱な解決策だと感じているからだ。

私は2つの回避策を考えましたが、これが良い/悪いアプローチか、より良い方法があるかどうかを知りたいと思います。

最初のアプローチは、タスクを一度に20行に分割する(つまり、140行がある場合はスクリプト7の別々の時間を実行する)ように、データベースクエリでLIMITを使用することです。私はこのアプローチから、スクリプトを呼び出す必要があることを理解しています。download.phpは7回に分かれており、LIMIT数値を渡す必要があります。

2番目は、個々のデータベースレコードのIDを渡すスクリプトを用意し、そのURLに(たとえばdownload.php?id=2)を入力してから、複数のAjaxリクエスト(download.php?id=2, download.php?id=3, download.php?id=4など)を実行します。 $_GET['id']に基づいて、データベースなどのURLを検索するクエリを実行することができます。理論的には、URLごとに1つのリクエストが設定されているため、140個の別々のリクエストを行います。

私はキューイングシステムを指摘している他の投稿を読んだことがありますが、これは私の知る限りではありません。これが最善の方法である場合は、見てみる価値のある特定のシステムがありますか?

ご協力いただければ幸いです。

編集:現在、140のURLがありますが、これは時間とともに増加する可能性があります。だから私はタイムアウトの制限を打つことなく拡大縮小するソリューションを探しています。

+0

140ページをつかむためにどのくらいの時間がかかるか、またはサーバーが遅れていくつかの要求を他のものよりも長くするように思っているので、おそらくmax_execution_timeを変更するのが最適な解決策です。 – Brogan

+0

タイムアウトを延長するのは貧弱な解決策ではありません。ループの各ステップ(または単一のページに賢明なもの)には、['set_time_limit(30)'](http://php.net/manual/en/function.set-time-limit.php)を使用してください。 「cURL呼び出しごとにX秒を許可します」というのは妥当なことです。 – apokryfos

+1

私はajaxコールのアプローチに行きます。データベース上のすべてのレコードを取得し、それを反復してAjax呼び出しを送信し、完了したら何かを報告することができます。スクリプトを呼び出して(そして作業をして)報告して、次のようなことを言うことができます: "XのうちXが完了し、Yがエラー" – LordNeo

答えて

2

私はあなたのロジックに同意しません。スクリプトが正常に実行されていて、終了するのにもっと時間が必要な場合は、時間がかかります。それは貧弱な解決策ではありません。あなたが提案していることは、あなたのURLが増えれば。

時間制限がなくブラウザを実行しないコマンドラインにスクリプトを移動することをお勧めします。

+0

完全に反対ですが、リストが大きくなると、タイムアウトが増加してもエスカレートしません。タイムアウトを無期限に増やすことはできません。 ajax呼び出しは、各プロセスを別々のスレッドに分離して分離し、すべてをゼロから再実行することなく複数の結果(成功/失敗)を持つことができます。 – LordNeo

+1

それは私が示唆したものではありません、私は時間制限が全くないコマンドラインに移動すると言いました。 set_time_limit(0)の等価物。 –

+0

あなたはコマンドラインを無期限に開いておくことはできません。リストが10.000ほどに大きくなるかどうかはわかりません。 – LordNeo

1

知られていないリストを持っているときに、非同期呼び出しが不明な時間がかかります。

スクリプトを1ページのダウンロード(提案したように、download.php?id=X)に分割します。

"main"スクリプトから、データベースからリストを取得し、それを反復処理し、それぞれに対してajax呼び出しを送信します。すべてのコールが一斉に起動されるため、帯域幅とCPU時間を確認してください。あなたは成功コールバックを使ってそれを "X active task"に分割することができます。

download.phpファイルを成功のデータを返すように設定するか、ウェブサイトのIDと呼び出しの結果をデータベースに保存することができます。私は後でお勧めします。なぜなら、メインスクリプトを残して後で結果を取得できるからです。

時間制限を無期限に増やすことはできません。要求を完了するまでに無期限に待つことができないため、非同期呼び出しが最も効果的です。

@apokryfosは、このような「バックアップ」のタイミングによっては、これをタスクスケジューラ(chronのような)に合わせることができると指摘しました。あなたがそれを "オンデマンド"と呼ぶなら、それをguiに入れて、それを "毎回x時間"と呼ぶならば、メインスクリプトを指し示すchronタスクを置くならば、同じことをするでしょう。

+1

タスクスケジューラには適していて、クライアントサイドのUIには適していないものがあります。おそらくCLIがより良いアプローチです。 – apokryfos

0

あなたが説明していることは、コンソールの仕事のように聞こえます。ブラウザはユーザーが見ることができますが、タスクはプログラマーが実行するものなので、コンソールを使用してください。あるいは、開発者が扱うcron-jobなどで実行するようにファイルをスケジュールすることもできます。

0

stream_socket_client()を使用して、すべての要求を同時に実行します。すべてのソケットIDを配列に保存する

次に、IDの配列をstream_select()でループして応答を読み取ります。

これはPHP内でのマルチタスクのようなものです。

関連する問題