eコマースShopify WordPressディスカッション

長時間実行されるPHPスクリプトを管理する最良の方法は?

I have a PHP script that takes a long time (5-30 minutes) to complete. Just in case it matters, the script is using curl to scrape data from another server. This is the reason it's taking so long; it has to wait for each page to load before processing it and moving to the next. I want to be able to initiate the script and let it be until it's done, which will set a flag in a database table. What I need to know is how to be able to end the http request before the script is finished running. Also, is a php script the best way to do this?
アップデート +12 年 - セキュリティに関する注意事項 これは、長時間実行されるコードを呼び出すには依然として良い方法ですが、Web サーバーの PHP が他の実行可能ファイルを起動する機能を制限したり無効にしたりすることは、セキュリティにとっては良いことです。また、これにより、ログを実行している動作とそれを開始した動作が切り離されるため、多くの場合、デーモンまたは cron ジョブを使用する方が適切である可能性があります。 元の回答 確かに PHP で実行できますが、これをバックグラウンド タスクとして実行しないでください。新しいプロセスは、それが開始されたプロセス グループから切り離される必要があります。 この FAQ に対して人々は同じ間違った答えを出し続けるため、ここに完全な答えを書きました。 http://symcbean.blogspot.com/2010/02/php-and-long-running-processes.html コメントから: 短いバージョンは、shell_exec('echo /usr/bin/php -q longThing.php | at now'); です。しかし、「なぜ」という理由は、ここに含めるには少し長くなります。

2024 年 1 月 7 日

ここで多くの人が述べているように、最良のアプローチではありませんが、これは役立つかもしれません。 無視_ユーザー_中止(1); // ユーザーがブラウザを閉じてもスクリプトをバックグラウンドで実行します set_time_limit(1800); // 30分間実行します // 長時間実行されるスクリプトはここにあります

2024 年 1 月 7 日

if you have long script then divide page work with the help of input parameter for each task.(then each page act like thread) i.e if page has 1 lac product_keywords long process loop then instead of loop make logic for one keyword and pass this keyword from magic or cornjobpage.php(in following example) and for background worker i think you should try this technique it will help to call as many as pages you like all pages will run at once independently without waiting for each page response as asynchronous. cornjobpage.php //mainpage <?php post_async("http://localhost/projectname/testpage.php", "Keywordname=testValue"); //post_async("http://localhost/projectname/testpage.php", "Keywordname=testValue2"); //post_async("http://localhost/projectname/otherpage.php", "Keywordname=anyValue"); //call as many as pages you like all pages will run at once independently without waiting for each page response as asynchronous. ?> <?php /* * Executes a PHP page asynchronously so the current page does not have to wait for it to finish running. * */ function post_async($url,$params) { $post_string = $params; $parts=parse_url($url); $fp = fsockopen($parts['host'], isset($parts['port'])?$parts['port']:80, $errno, $errstr, 30); $out = "GET ".$parts['path']."?$post_string"." HTTP/1.1rn";//you can use POST instead of GET if you like $out.= "Host: ".$parts['host']."rn"; $out.= "Content-Type: application/x-www-form-urlencodedrn"; $out.= "Content-Length: ".strlen($post_string)."rn"; $out.= "Connection: Closernrn"; fwrite($fp, $out); fclose($fp); } ?> testpage.php <? echo $_REQUEST["Keywordname"];//case1 Output > testValue ?> PS:if you want to send url parameters as loop then follow this answer :https://stackoverflow.com/a/41225209/6295712

2024 年 1 月 7 日

what I ALWAYS use is one of these variants (because different flavors of Linux have different rules about handling output/some programs output differently): Variant I @exec('./myscript.php 1>/dev/null 2>/dev/null &'); Variant II @exec('php -f myscript.php 1>/dev/null 2>/dev/null &'); Variant III @exec('nohup myscript.php 1>/dev/null 2>/dev/null &'); You might havet install "nohup". But for example, when I was automating FFMPEG video converstions, the output interface somehow wasn't 100% handled by redirecting output streams 1 & 2, so I used nohup AND redirected the output.

2024 年 1 月 7 日

プロキシを使用してリクエストを委任します。

2024 年 1 月 7 日

Perlでも同様のこと、double fork()、親プロセスからのデタッチを行いました。すべての http フェッチ作業はフォークされたプロセスで実行する必要があります。

2024 年 1 月 7 日

I would like to propose a solution that is a little different from symcbean's, mainly because I have additional requirement that the long running process need to be run as another user, and not as apache / www-data user. First solution using cron to poll a background task table: PHP web page inserts into a background task table, state 'SUBMITTED' cron runs once each 3 minutes, using another user, running PHP CLI script that checks the background task table for 'SUBMITTED' rows PHP CLI will update the state column in the row into 'PROCESSING' and begin processing, after completion it will be updated to 'COMPLETED' Second solution using Linux inotify facility: PHP web page updates a control file with the parameters set by user, and also giving a task id shell script (as a non-www user) running inotifywait will wait for the control file to be written after control file is written, a close_write event will be raised an the shell script will continue shell script executes PHP CLI to do the long running process PHP CLI writes the output to a log file identified by task id, or alternatively updates progress in a status table PHP web page could poll the log file (based on task id) to show progress of the long running process, or it could also query status table Some additional info could be found in my post : http://inventorsparadox.blogspot.co.id/2016/01/long-running-process-in-linux-using-php.html

2024 年 1 月 7 日

I realize this is a quite old question but would like to give it a shot. This script tries to address both the initial kick off call to finish quickly and chop down the heavy load into smaller chunks. I haven't tested this solution. <?php /** * crawler.php located at http://mysite.com/crawler.php */ // Make sure this script will keep on runing after we close the connection with // it. ignore_user_abort(TRUE); function get_remote_sources_to_crawl() { // Do a database or a log file query here. $query_result = array ( 1 => 'http://exemple.com', 2 => 'http://exemple1.com', 3 => 'http://exemple2.com', 4 => 'http://exemple3.com', // ... and so on. ); // Returns the first one on the list. foreach ($query_result as $id => $url) { return $url; } return FALSE; } function update_remote_sources_to_crawl($id) { // Update my database or log file list so the $id record wont show up // on my next call to get_remote_sources_to_crawl() } $crawling_source = get_remote_sources_to_crawl(); if ($crawling_source) { // Run your scraping code on $crawling_source here. if ($your_scraping_has_finished) { // Update you database or log file. update_remote_sources_to_crawl($id); $ctx = stream_context_create(array( 'http' => array( // I am not quite sure but I reckon the timeout set here actually // starts rolling after the connection to the remote server is made // limiting only how long the downloading of the remote content should take. // So as we are only interested to trigger this script again, 5 seconds // should be plenty of time. 'timeout' => 5, ) )); // Open a new connection to this script and close it after 5 seconds in. file_get_contents('http://' . $_SERVER['HTTP_HOST'] . '/crawler.php', FALSE, $ctx); print 'The cronjob kick off has been initiated.'; } } else { print 'Yay! The whole thing is done.'; }

2024 年 1 月 7 日

XHR (Ajax) リクエストとして送信できます。通常、通常の HTTP リクエストとは異なり、クライアントには XHR のタイムアウトがありません。

2024 年 1 月 7 日

I agree with the answers that say this should be run in a background process. But it's also important that you report on the status so the user knows that the work is being done. When receiving the PHP request to kick off the process, you could store in a database a representation of the task with a unique identifier. Then, start the screen-scraping process, passing it the unique identifier. Report back to the iPhone app that the task has been started and that it should check a specified URL, containing the new task ID, to get the latest status. The iPhone application can now poll (or even "long poll") this URL. In the meantime, the background process would update the database representation of the task as it worked with a completion percentage, current step, or whatever other status indicators you'd like. And when it has finished, it would set a completed flag.

2024 年 1 月 7 日

PHP が最適なツールである場合もあれば、そうでない場合もありますが、PHP の使用方法はわかっており、アプリケーションの残りの部分は PHP を使用して作成されます。これら 2 つの特性と、PHP が「十分に優れている」という事実を組み合わせると、Perl、Ruby、または Python の代わりに PHP を使用することが非常に強力になります。 別の言語を学習することが目的の場合は、言語を 1 つ選んで使用してください。あなたが挙げたどの言語でも問題なく機能します。私はたまたま Perl が好きですが、あなたが好むものは異なるかもしれません。 Symcbean のリンクには、バックグラウンド プロセスの管理方法に関する優れたアドバイスが記載されています。 つまり、長いビットを処理する CLI PHP スクリプトを作成します。何らかの方法でステータスを報告するようにしてください。 AJAX または従来の方法を使用して、ステータスの更新を処理する php ページを作成します。キックオフ スクリプトは、独自のセッションで実行中のプロセスを開始し、プロセスが進行中であることの確認を返します。 幸運を。

2024 年 1 月 7 日

Yes, you can do it in PHP. But in addition to PHP it would be wise to use a Queue Manager. Here's the strategy: Break up your large task into smaller tasks. In your case, each task could be loading a single page. Send each small task to the queue. Run your queue workers somewhere. Using this strategy has the following advantages: For long running tasks it has the ability to recover in case a fatal problem occurs in the middle of the run -- no need to start from the beginning. If your tasks do not have to be run sequentially, you can run multiple workers to run tasks simultaneously. You have a variety of options (this is just a few): RabbitMQ (https://www.rabbitmq.com/tutorials/tutorial-one-php.html) ZeroMQ (http://zeromq.org/bindings:php) If you're using the Laravel framework, queues are built-in (https://laravel.com/docs/5.4/queues), with drivers for AWS SES, Redis, Beanstalkd

2024 年 1 月 7 日

No, PHP is not the best solution. I'm not sure about Ruby or Perl, but with Python you could rewrite your page scraper to be multi-threaded and it would probably run at least 20x faster. Writing multi-threaded apps can be somewhat of a challenge, but the very first Python app I wrote was mutlti-threaded page scraper. And you could simply call the Python script from within your PHP page by using one of the shell execution functions.

2024 年 1 月 7 日

exec または system を使用してバックグラウンド ジョブを開始し、その中で作業を行うことができます。 また、Web をスクレイピングするための、あなたが使用しているものよりも優れたアプローチもあります。スレッド化アプローチ (複数のスレッドが一度に 1 ページを実行する) を使用することも、イベントループを使用するアプローチ (1 つのスレッドが一度に複数ページを実行する) を使用することもできます。 Perl を使用する私の個人的なアプローチは、AnyEvent::HTTP を使用することです。 ETA: symcbean は、バックグラウンドプロセスを適切に切り離す方法をここで説明しました。

2024 年 1 月 7 日

The quick and dirty way would be to use the ignore_user_abort function in php. This basically says: Don't care what the user does, run this script until it is finished. This is somewhat dangerous if it is a public facing site (because it is possible, that you end up having 20++ versions of the script running at the same time if it is initiated 20 times). The "clean" way (at least IMHO) is to set a flag (in the db for example) when you want to initiate the process and run a cronjob every hour (or so) to check if that flag is set. If it IS set, the long running script starts, if it is NOT set, nothin happens.

2024 年 1 月 7 日

スクリプトの目的の出力が Web ページではなく何らかの処理である場合、望ましい解決策は、単に次のようにシェルからスクリプトを実行することだと思います。 php my_script.php

2024 年 1 月 7 日

TurboCommerce make the better internet purchasing globaly

ターボ多言語翻訳者

世界中でインターネット購入をより良くする

Turbosify SEO スピードブースター

5.0 (7) 無料プランあり
ストアの読み込み速度を向上させてコンバージョンを向上 インストール済み

ターボ多言語チャット - AI カスタマー サービスを片手に

TurboCommerce make the better internet purchasing globaly
当社の製品

必要なときに、必要なサポートを

ターボエンジンによるアプリ

3 つのアプリ • 平均評価 5.0

ターボ化スピードブースター

5.0 (7)
Shopify ストアの Google ページの速度を最適化してコンバージョンを向上させます インストール済み

Wordpress Woocommerce 用 Turbosify 翻訳者

5.0 (74) 無料の Wordpress Woocommerce プラグイン
WordPress Web サイトを 1 クリックで多言語に翻訳します。設定は必要ありません。 技術的な必要はありません

ここでビジネスを成長させましょう

製品を路上で販売したい場合でも、世界中で販売したい場合でも、私たちは次のようなサービスを提供します。 必要なすべてのツール。
長時間実行されるPHPスクリプトを管理する最良の方法は?

eコマースShopify WordPressディスカッション

長時間実行されるPHPスクリプトを管理する最良の方法は?

I have a PHP script that takes a long time (5-30 minutes) to complete. Just in case it matters, the script is using curl to scrape data from another server. This is the reason it's taking so long; it has to wait for each page to load before processing it and moving to the next. I want to be able to initiate the script and let it be until it's done, which will set a flag in a database table. What I need to know is how to be able to end the http request before the script is finished running. Also, is a php script the best way to do this?
アップデート +12 年 - セキュリティに関する注意事項 これは、長時間実行されるコードを呼び出すには依然として良い方法ですが、Web サーバーの PHP が他の実行可能ファイルを起動する機能を制限したり無効にしたりすることは、セキュリティにとっては良いことです。また、これにより、ログを実行している動作とそれを開始した動作が切り離されるため、多くの場合、デーモンまたは cron ジョブを使用する方が適切である可能性があります。 元の回答 確かに PHP で実行できますが、これをバックグラウンド タスクとして実行しないでください。新しいプロセスは、それが開始されたプロセス グループから切り離される必要があります。 この FAQ に対して人々は同じ間違った答えを出し続けるため、ここに完全な答えを書きました。 http://symcbean.blogspot.com/2010/02/php-and-long-running-processes.html コメントから: 短いバージョンは、shell_exec('echo /usr/bin/php -q longThing.php | at now'); です。しかし、「なぜ」という理由は、ここに含めるには少し長くなります。

2024 年 1 月 7 日

ここで多くの人が述べているように、最良のアプローチではありませんが、これは役立つかもしれません。 無視_ユーザー_中止(1); // ユーザーがブラウザを閉じてもスクリプトをバックグラウンドで実行します set_time_limit(1800); // 30分間実行します // 長時間実行されるスクリプトはここにあります

2024 年 1 月 7 日

if you have long script then divide page work with the help of input parameter for each task.(then each page act like thread) i.e if page has 1 lac product_keywords long process loop then instead of loop make logic for one keyword and pass this keyword from magic or cornjobpage.php(in following example) and for background worker i think you should try this technique it will help to call as many as pages you like all pages will run at once independently without waiting for each page response as asynchronous. cornjobpage.php //mainpage <?php post_async("http://localhost/projectname/testpage.php", "Keywordname=testValue"); //post_async("http://localhost/projectname/testpage.php", "Keywordname=testValue2"); //post_async("http://localhost/projectname/otherpage.php", "Keywordname=anyValue"); //call as many as pages you like all pages will run at once independently without waiting for each page response as asynchronous. ?> <?php /* * Executes a PHP page asynchronously so the current page does not have to wait for it to finish running. * */ function post_async($url,$params) { $post_string = $params; $parts=parse_url($url); $fp = fsockopen($parts['host'], isset($parts['port'])?$parts['port']:80, $errno, $errstr, 30); $out = "GET ".$parts['path']."?$post_string"." HTTP/1.1rn";//you can use POST instead of GET if you like $out.= "Host: ".$parts['host']."rn"; $out.= "Content-Type: application/x-www-form-urlencodedrn"; $out.= "Content-Length: ".strlen($post_string)."rn"; $out.= "Connection: Closernrn"; fwrite($fp, $out); fclose($fp); } ?> testpage.php <? echo $_REQUEST["Keywordname"];//case1 Output > testValue ?> PS:if you want to send url parameters as loop then follow this answer :https://stackoverflow.com/a/41225209/6295712

2024 年 1 月 7 日

what I ALWAYS use is one of these variants (because different flavors of Linux have different rules about handling output/some programs output differently): Variant I @exec('./myscript.php 1>/dev/null 2>/dev/null &'); Variant II @exec('php -f myscript.php 1>/dev/null 2>/dev/null &'); Variant III @exec('nohup myscript.php 1>/dev/null 2>/dev/null &'); You might havet install "nohup". But for example, when I was automating FFMPEG video converstions, the output interface somehow wasn't 100% handled by redirecting output streams 1 & 2, so I used nohup AND redirected the output.

2024 年 1 月 7 日

プロキシを使用してリクエストを委任します。

2024 年 1 月 7 日

Perlでも同様のこと、double fork()、親プロセスからのデタッチを行いました。すべての http フェッチ作業はフォークされたプロセスで実行する必要があります。

2024 年 1 月 7 日

I would like to propose a solution that is a little different from symcbean's, mainly because I have additional requirement that the long running process need to be run as another user, and not as apache / www-data user. First solution using cron to poll a background task table: PHP web page inserts into a background task table, state 'SUBMITTED' cron runs once each 3 minutes, using another user, running PHP CLI script that checks the background task table for 'SUBMITTED' rows PHP CLI will update the state column in the row into 'PROCESSING' and begin processing, after completion it will be updated to 'COMPLETED' Second solution using Linux inotify facility: PHP web page updates a control file with the parameters set by user, and also giving a task id shell script (as a non-www user) running inotifywait will wait for the control file to be written after control file is written, a close_write event will be raised an the shell script will continue shell script executes PHP CLI to do the long running process PHP CLI writes the output to a log file identified by task id, or alternatively updates progress in a status table PHP web page could poll the log file (based on task id) to show progress of the long running process, or it could also query status table Some additional info could be found in my post : http://inventorsparadox.blogspot.co.id/2016/01/long-running-process-in-linux-using-php.html

2024 年 1 月 7 日

I realize this is a quite old question but would like to give it a shot. This script tries to address both the initial kick off call to finish quickly and chop down the heavy load into smaller chunks. I haven't tested this solution. <?php /** * crawler.php located at http://mysite.com/crawler.php */ // Make sure this script will keep on runing after we close the connection with // it. ignore_user_abort(TRUE); function get_remote_sources_to_crawl() { // Do a database or a log file query here. $query_result = array ( 1 => 'http://exemple.com', 2 => 'http://exemple1.com', 3 => 'http://exemple2.com', 4 => 'http://exemple3.com', // ... and so on. ); // Returns the first one on the list. foreach ($query_result as $id => $url) { return $url; } return FALSE; } function update_remote_sources_to_crawl($id) { // Update my database or log file list so the $id record wont show up // on my next call to get_remote_sources_to_crawl() } $crawling_source = get_remote_sources_to_crawl(); if ($crawling_source) { // Run your scraping code on $crawling_source here. if ($your_scraping_has_finished) { // Update you database or log file. update_remote_sources_to_crawl($id); $ctx = stream_context_create(array( 'http' => array( // I am not quite sure but I reckon the timeout set here actually // starts rolling after the connection to the remote server is made // limiting only how long the downloading of the remote content should take. // So as we are only interested to trigger this script again, 5 seconds // should be plenty of time. 'timeout' => 5, ) )); // Open a new connection to this script and close it after 5 seconds in. file_get_contents('http://' . $_SERVER['HTTP_HOST'] . '/crawler.php', FALSE, $ctx); print 'The cronjob kick off has been initiated.'; } } else { print 'Yay! The whole thing is done.'; }

2024 年 1 月 7 日

XHR (Ajax) リクエストとして送信できます。通常、通常の HTTP リクエストとは異なり、クライアントには XHR のタイムアウトがありません。

2024 年 1 月 7 日

I agree with the answers that say this should be run in a background process. But it's also important that you report on the status so the user knows that the work is being done. When receiving the PHP request to kick off the process, you could store in a database a representation of the task with a unique identifier. Then, start the screen-scraping process, passing it the unique identifier. Report back to the iPhone app that the task has been started and that it should check a specified URL, containing the new task ID, to get the latest status. The iPhone application can now poll (or even "long poll") this URL. In the meantime, the background process would update the database representation of the task as it worked with a completion percentage, current step, or whatever other status indicators you'd like. And when it has finished, it would set a completed flag.

2024 年 1 月 7 日

PHP が最適なツールである場合もあれば、そうでない場合もありますが、PHP の使用方法はわかっており、アプリケーションの残りの部分は PHP を使用して作成されます。これら 2 つの特性と、PHP が「十分に優れている」という事実を組み合わせると、Perl、Ruby、または Python の代わりに PHP を使用することが非常に強力になります。 別の言語を学習することが目的の場合は、言語を 1 つ選んで使用してください。あなたが挙げたどの言語でも問題なく機能します。私はたまたま Perl が好きですが、あなたが好むものは異なるかもしれません。 Symcbean のリンクには、バックグラウンド プロセスの管理方法に関する優れたアドバイスが記載されています。 つまり、長いビットを処理する CLI PHP スクリプトを作成します。何らかの方法でステータスを報告するようにしてください。 AJAX または従来の方法を使用して、ステータスの更新を処理する php ページを作成します。キックオフ スクリプトは、独自のセッションで実行中のプロセスを開始し、プロセスが進行中であることの確認を返します。 幸運を。

2024 年 1 月 7 日

Yes, you can do it in PHP. But in addition to PHP it would be wise to use a Queue Manager. Here's the strategy: Break up your large task into smaller tasks. In your case, each task could be loading a single page. Send each small task to the queue. Run your queue workers somewhere. Using this strategy has the following advantages: For long running tasks it has the ability to recover in case a fatal problem occurs in the middle of the run -- no need to start from the beginning. If your tasks do not have to be run sequentially, you can run multiple workers to run tasks simultaneously. You have a variety of options (this is just a few): RabbitMQ (https://www.rabbitmq.com/tutorials/tutorial-one-php.html) ZeroMQ (http://zeromq.org/bindings:php) If you're using the Laravel framework, queues are built-in (https://laravel.com/docs/5.4/queues), with drivers for AWS SES, Redis, Beanstalkd

2024 年 1 月 7 日

No, PHP is not the best solution. I'm not sure about Ruby or Perl, but with Python you could rewrite your page scraper to be multi-threaded and it would probably run at least 20x faster. Writing multi-threaded apps can be somewhat of a challenge, but the very first Python app I wrote was mutlti-threaded page scraper. And you could simply call the Python script from within your PHP page by using one of the shell execution functions.

2024 年 1 月 7 日

exec または system を使用してバックグラウンド ジョブを開始し、その中で作業を行うことができます。 また、Web をスクレイピングするための、あなたが使用しているものよりも優れたアプローチもあります。スレッド化アプローチ (複数のスレッドが一度に 1 ページを実行する) を使用することも、イベントループを使用するアプローチ (1 つのスレッドが一度に複数ページを実行する) を使用することもできます。 Perl を使用する私の個人的なアプローチは、AnyEvent::HTTP を使用することです。 ETA: symcbean は、バックグラウンドプロセスを適切に切り離す方法をここで説明しました。

2024 年 1 月 7 日

The quick and dirty way would be to use the ignore_user_abort function in php. This basically says: Don't care what the user does, run this script until it is finished. This is somewhat dangerous if it is a public facing site (because it is possible, that you end up having 20++ versions of the script running at the same time if it is initiated 20 times). The "clean" way (at least IMHO) is to set a flag (in the db for example) when you want to initiate the process and run a cronjob every hour (or so) to check if that flag is set. If it IS set, the long running script starts, if it is NOT set, nothin happens.

2024 年 1 月 7 日

スクリプトの目的の出力が Web ページではなく何らかの処理である場合、望ましい解決策は、単に次のようにシェルからスクリプトを実行することだと思います。 php my_script.php

2024 年 1 月 7 日

TurboCommerce make the better internet purchasing globaly

ターボ多言語翻訳者

世界中でインターネット購入をより良くする

Turbosify SEO スピードブースター

5.0 (7) 無料プランあり
ストアの読み込み速度を向上させてコンバージョンを向上 インストール済み

ターボ多言語チャット - AI カスタマー サービスを片手に

TurboCommerce make the better internet purchasing globaly
当社の製品

必要なときに、必要なサポートを

ターボエンジンによるアプリ

3 つのアプリ • 平均評価 5.0

ターボ化スピードブースター

5.0 (7)
Shopify ストアの Google ページの速度を最適化してコンバージョンを向上させます インストール済み

Wordpress Woocommerce 用 Turbosify 翻訳者

5.0 (74) 無料の Wordpress Woocommerce プラグイン
WordPress Web サイトを 1 クリックで多言語に翻訳します。設定は必要ありません。 技術的な必要はありません

ここでビジネスを成長させましょう

製品を路上で販売したい場合でも、世界中で販売したい場合でも、私たちは次のようなサービスを提供します。 必要なすべてのツール。