উত্তর:
ধরে নিই যে এটি একটি লিনাক্স মেশিনে চলছে, আমি সর্বদা এটি এইভাবে পরিচালনা করেছি:
exec(sprintf("%s > %s 2>&1 & echo $! >> %s", $cmd, $outputfile, $pidfile));
এটি কমান্ডটি প্রবর্তন করে $cmd
, কমান্ড আউটপুটটিকে পুনর্নির্দেশ করে $outputfile
এবং প্রসেস আইডি লিখে দেয় $pidfile
।
এটি আপনাকে প্রক্রিয়াটি কী করছে এবং যদি এটি এখনও চলছে তা সহজেই নিরীক্ষণ করতে দেয়।
function isRunning($pid){
try{
$result = shell_exec(sprintf("ps %d", $pid));
if( count(preg_split("/\n/", $result)) > 2){
return true;
}
}catch(Exception $e){}
return false;
}
সার্ভার-সাইড স্ক্রিপ্ট হিসাবে প্রক্রিয়াটি যে কোনও ভাষায় (পিএইচপি / বাশ / পার্ল / ইত্যাদি) সহজেই লিখুন এবং আপনার পিএইচপি স্ক্রিপ্টের প্রক্রিয়া নিয়ন্ত্রণ ফাংশন থেকে কল করুন।
ফাংশনটি সম্ভবত সনাক্ত করে যে যদি স্ট্যান্ডার্ড আইওটি আউটপুট স্ট্রিম হিসাবে ব্যবহৃত হয় এবং যদি তা হয় তবে এটি প্রত্যাবর্তন মান নির্ধারণ করবে..তখন এটি শেষ হয় না
proc_close( proc_open( "./command --foo=1 &", array(), $foo ) );
কমান্ড হিসাবে "স্লিপ 25s" ব্যবহার করে আমি কমান্ড লাইন থেকে এটি দ্রুত পরীক্ষা করেছি এবং এটি একটি কবজির মতো কাজ করেছে।
আপনি আপনার কমান্ডে এটি যুক্ত করার চেষ্টা করতে পারেন
>/dev/null 2>/dev/null &
যেমন।
shell_exec('service named reload >/dev/null 2>/dev/null &');
উইন্ডোজটিতে এই কার্যকারিতাটি পরীক্ষা করার জন্য আমি খুব সাধারণ উদাহরণ যুক্ত করতে চাই:
নিম্নলিখিত দুটি ফাইল তৈরি করুন এবং একটি ওয়েব ডিরেক্টরিতে সেভ করুন:
foreground.php:
<?php
ini_set("display_errors",1);
error_reporting(E_ALL);
echo "<pre>loading page</pre>";
function run_background_process()
{
file_put_contents("testprocesses.php","foreground start time = " . time() . "\n");
echo "<pre> foreground start time = " . time() . "</pre>";
// output from the command must be redirected to a file or another output stream
// http://ca.php.net/manual/en/function.exec.php
exec("php background.php > testoutput.php 2>&1 & echo $!", $output);
echo "<pre> foreground end time = " . time() . "</pre>";
file_put_contents("testprocesses.php","foreground end time = " . time() . "\n", FILE_APPEND);
return $output;
}
echo "<pre>calling run_background_process</pre>";
$output = run_background_process();
echo "<pre>output = "; print_r($output); echo "</pre>";
echo "<pre>end of page</pre>";
?>
background.php:
<?
file_put_contents("testprocesses.php","background start time = " . time() . "\n", FILE_APPEND);
sleep(10);
file_put_contents("testprocesses.php","background end time = " . time() . "\n", FILE_APPEND);
?>
আপনি উপরের ফাইলগুলি যে ডিরেক্টরিটিতে তৈরি করেছেন তাতে লেখার জন্য আইইউএসআরকে অনুমতি দিন
পড়ুন এবং এক্সেকিউট সি: আইওএসআরকে অনুমতি দিন: \ উইন্ডোজ \ সিস্টেম 32 \ সেমিডি.এক্সে
একটি ওয়েব ব্রাউজার থেকে ফোরগ্রাউন্ড.এফপি হিট করুন
নিম্নলিখিতটি আউটপুট অ্যারেতে ব্রাউজার ডাব্লু / বর্তমান টাইমস্ট্যাম্প এবং স্থানীয় সংস্থান # তে রেন্ডার করা উচিত:
loading page
calling run_background_process
foreground start time = 1266003600
foreground end time = 1266003600
output = Array
(
[0] => 15010
)
end of page
উপরের ফাইলগুলি যেভাবে সংরক্ষণ করা হয়েছিল সেই একই ডিরেক্টরিতে আপনার টেস্টআউটপুট.এফপি দেখতে হবে এবং এটি খালি থাকতে হবে
উপরের ফাইলগুলি যেভাবে সংরক্ষণ করা হয়েছিল সেই একই ডিরেক্টরিতে আপনার টেস্টপ্রোসেসেস.এফপি দেখতে পাওয়া উচিত এবং এতে নিম্নোক্ত পাঠ্য ডাব্লু / বর্তমান টাইমস্ট্যাম্পগুলি থাকা উচিত:
foreground start time = 1266003600
foreground end time = 1266003600
background start time = 1266003600
background end time = 1266003610
আপনার যদি পিএইচপি পৃষ্ঠাটি সম্পূর্ণ হওয়ার অপেক্ষায় ব্যাকগ্রাউন্ডে কিছু করার দরকার হয় তবে আপনি অপর একটি (পটভূমি) পিএইচপি স্ক্রিপ্ট ব্যবহার করতে পারেন যা উইজেট কমান্ডের সাহায্যে "আহ্বান" করা হয়েছে। এই ব্যাকগ্রাউন্ড পিএইচপি স্ক্রিপ্ট অবশ্যই আপনার সিস্টেমে অন্য কোনও পিএইচপি স্ক্রিপ্ট হিসাবে সুবিধাগুলি সহ কার্যকর করা হবে।
উইন্ডোজে gnuwin32 প্যাকেজগুলির উইজেট ব্যবহার করে এখানে একটি উদাহরণ দেওয়া আছে।
একটি উদাহরণ হিসাবে পটভূমি কোড (ফাইলের পরীক্ষা-proc-bg.php) ...
sleep(5); // some delay
file_put_contents('test.txt', date('Y-m-d/H:i:s.u')); // writes time in a file
অগ্রভূমি স্ক্রিপ্ট, একটি অনুরোধ ...
$proc_command = "wget.exe http://localhost/test-proc-bg.php -q -O - -b";
$proc = popen($proc_command, "r");
pclose($proc);
সঠিকভাবে কাজ করার জন্য আপনাকে অবশ্যই পপেন / প্লেস ব্যবহার করতে হবে।
উইজেট বিকল্পগুলি:
-q keeps wget quiet.
-O - outputs to stdout.
-b works on background
পিএইচপিতে একটি পটভূমি প্রক্রিয়া চালু করার জন্য এখানে একটি ফাংশন is অবশেষে এমন একটি তৈরি করেছে যা উইন্ডোজে আসলে অনেকগুলি পন্থাগুলি এবং প্যারামিটারগুলি পড়ে এবং পরীক্ষার পরেও উইন্ডোজে কাজ করে।
function LaunchBackgroundProcess($command){
// Run command Asynchroniously (in a separate thread)
if(PHP_OS=='WINNT' || PHP_OS=='WIN32' || PHP_OS=='Windows'){
// Windows
$command = 'start "" '. $command;
} else {
// Linux/UNIX
$command = $command .' /dev/null &';
}
$handle = popen($command, 'r');
if($handle!==false){
pclose($handle);
return true;
} else {
return false;
}
}
দ্রষ্টব্য 1: উইন্ডোজগুলিতে, /B
অন্য কোথাও প্রস্তাবিত প্যারামিটার ব্যবহার করবেন না । এটি start
কমান্ড হিসাবে একই কনসোল উইন্ডোটি চালাতে প্রক্রিয়াটিকে জোর করে, ফলস্বরূপ প্রক্রিয়াটি সিঙ্ক্রোনসিভভাবে প্রক্রিয়াজাত হয়। পৃথক থ্রেডে (প্রক্রিয়াবিহীন) চালানোর জন্য, ব্যবহার করবেন না /B
।
দ্রষ্টব্য 2: start ""
কমান্ডটি উদ্ধৃত পথ হলে খালি ডাবল উদ্ধৃতিগুলির প্রয়োজন। start
কমান্ড উইন্ডো শিরোনাম হিসাবে প্রথম উদ্ধৃত প্যারামিটার ব্যাখ্যা করে।
আপনি কি একটি পৃথক প্রক্রিয়া কাঁটাচামচ করার ব্যবস্থা করতে পারেন, এবং তারপরে আপনার অনুলিপিটি পটভূমিতে চালাবেন? আমি কোনও পিএইচপি করার পরে এটি হয়ে গেছে, তবে পিসিএনটিএল- ফাংশনটি আশাব্যঞ্জক বলে মনে হচ্ছে।
পটভূমিতে আপনার প্রোগ্রামটি চালাতে এই ফাংশনটি ব্যবহার করুন। এটি ক্রস প্ল্যাটফর্ম এবং সম্পূর্ণরূপে কাস্টমাইজযোগ্য।
<?php
function startBackgroundProcess(
$command,
$stdin = null,
$redirectStdout = null,
$redirectStderr = null,
$cwd = null,
$env = null,
$other_options = null
) {
$descriptorspec = array(
1 => is_string($redirectStdout) ? array('file', $redirectStdout, 'w') : array('pipe', 'w'),
2 => is_string($redirectStderr) ? array('file', $redirectStderr, 'w') : array('pipe', 'w'),
);
if (is_string($stdin)) {
$descriptorspec[0] = array('pipe', 'r');
}
$proc = proc_open($command, $descriptorspec, $pipes, $cwd, $env, $other_options);
if (!is_resource($proc)) {
throw new \Exception("Failed to start background process by command: $command");
}
if (is_string($stdin)) {
fwrite($pipes[0], $stdin);
fclose($pipes[0]);
}
if (!is_string($redirectStdout)) {
fclose($pipes[1]);
}
if (!is_string($redirectStderr)) {
fclose($pipes[2]);
}
return $proc;
}
নোট করুন যে কমান্ড শুরুর পরে, ডিফল্টরূপে এই ফাংশনটি চলমান প্রক্রিয়াটির স্টিডিন এবং স্টাডআউট বন্ধ করে দেয়। আপনি প্রক্রিয়া আউটপুট file redirectStdout এবং irect redirectStderr আর্গুমেন্টের মাধ্যমে কিছু ফাইলে পুনর্নির্দেশ করতে পারেন।
উইন্ডোজ ব্যবহারকারীদের জন্য নোট:
আপনি nul
নিম্নলিখিত পদ্ধতিতে stdout / stderr পুনর্নির্দেশ করতে পারবেন না :
startBackgroundProcess('ping yandex.com', null, 'nul', 'nul');
তবে, আপনি এটি করতে পারেন:
startBackgroundProcess('ping yandex.com >nul 2>&1');
* নিক্স ব্যবহারকারীদের জন্য নোট:
1) আপনি প্রকৃত পিআইডি পেতে চাইলে এক্সিকিউট শেল কমান্ডটি ব্যবহার করুন:
$proc = startBackgroundProcess('exec ping yandex.com -c 15', null, '/dev/null', '/dev/null');
print_r(proc_get_status($proc));
2) আপনি যদি আপনার প্রোগ্রামের ইনপুটটিতে কিছু ডেটা দিতে চান তবে স্ট্যান্ডিন আর্গুমেন্টটি ব্যবহার করুন:
startBackgroundProcess('cat > input.txt', "Hello world!\n");
আপনি রেসকের মতো একটি কুইউিং সিস্টেম চেষ্টা করতে পারেন । তারপরে আপনি একটি কাজ তৈরি করতে পারেন, যা তথ্য প্রক্রিয়া করে এবং "প্রসেসিং" চিত্রটি সহ বেশ দ্রুত ফিরে আসে। এই পদ্ধতির সাহায্যে আপনি জানেন না কখন এটি শেষ হয়েছে।
এই সমাধানটি বৃহত্তর স্কেল অ্যাপ্লিকেশনগুলির উদ্দেশ্যে করা হয়েছে, যেখানে আপনি আপনার সামনের মেশিনগুলি ভারী উত্তোলন করতে চান না, যাতে তারা ব্যবহারকারীর অনুরোধগুলি প্রক্রিয়া করতে পারে। সুতরাং এটি ফাইল এবং ফোল্ডারগুলির মতো শারীরিক ডেটা সহ কাজ করতে বা নাও পারে, তবে আরও জটিল যুক্তি বা অন্যান্য অ্যাসিনক্রোনাস টাস্কগুলি (যেমন নতুন রেজিস্ট্রেশন মেলস) প্রসেস করার জন্য এটি ভাল এবং খুব পরিমাণে স্কেলযোগ্য is
উইন্ডোজ এবং লিনাক্স উভয়ের জন্য একটি কার্যক্ষম সমাধান। আমার গিথুব পৃষ্ঠায় আরও সন্ধান করুন ।
function run_process($cmd,$outputFile = '/dev/null', $append = false){
$pid=0;
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {//'This is a server using Windows!';
$cmd = 'wmic process call create "'.$cmd.'" | find "ProcessId"';
$handle = popen("start /B ". $cmd, "r");
$read = fread($handle, 200); //Read the output
$pid=substr($read,strpos($read,'=')+1);
$pid=substr($pid,0,strpos($pid,';') );
$pid = (int)$pid;
pclose($handle); //Close
}else{
$pid = (int)shell_exec(sprintf('%s %s %s 2>&1 & echo $!', $cmd, ($append) ? '>>' : '>', $outputFile));
}
return $pid;
}
function is_process_running($pid){
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {//'This is a server using Windows!';
//tasklist /FI "PID eq 6480"
$result = shell_exec('tasklist /FI "PID eq '.$pid.'"' );
if (count(preg_split("/\n/", $result)) > 0 && !preg_match('/No tasks/', $result)) {
return true;
}
}else{
$result = shell_exec(sprintf('ps %d 2>&1', $pid));
if (count(preg_split("/\n/", $result)) > 2 && !preg_match('/ERROR: Process ID out of range/', $result)) {
return true;
}
}
return false;
}
function stop_process($pid){
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {//'This is a server using Windows!';
$result = shell_exec('taskkill /PID '.$pid );
if (count(preg_split("/\n/", $result)) > 0 && !preg_match('/No tasks/', $result)) {
return true;
}
}else{
$result = shell_exec(sprintf('kill %d 2>&1', $pid));
if (!preg_match('/No such process/', $result)) {
return true;
}
}
}
এই উত্তরের জন্য ধন্যবাদ : একটি পটভূমি প্রক্রিয়া চালানোর জন্য একটি নিখুঁত সরঞ্জাম হ'ল সিমফনি প্রক্রিয়া উপাদান যা proc_*
ফাংশনের উপর ভিত্তি করে তৈরি হয় তবে এটি ব্যবহার করা অনেক সহজ। আরও তথ্যের জন্য এর ডকুমেন্টেশন দেখুন ।
একটি ব্যাকগ্রাউন্ড প্রক্রিয়া শুরু করার পরিবর্তে, একটি ট্রিগার ফাইল তৈরি করা এবং ক্রোন বা অটোসিসের মতো সময়সূচী থাকার সময়ে পর্যায়ক্রমে এমন স্ক্রিপ্ট কার্যকর করা যা ট্রিগার ফাইলগুলির সন্ধান করে এবং সেগুলিতে কাজ করে? ট্রিগারগুলিতে নির্দেশাবলী বা এমনকি কাঁচা কমান্ড থাকতে পারে (আরও ভাল, এটি কেবল একটি শেল স্ক্রিপ্ট তৈরি করুন)।
যদি পিএইচপি ব্যবহার করা হয় তবে pcntl_fork ব্যবহার করে এটি করার আরও অনেক সহজ উপায় রয়েছে:
আমি ভারী ব্যবহার করছি fast_cgi_finish_request()
একটি বন্ধ এবং রেজিস্টার_শটডাউন_ফাংশন () এর সাথে একত্রে
$message ='job executed';
$backgroundJob = function() use ($message) {
//do some work here
echo $message;
}
তারপরে শাটডাউনের আগে কার্যকর হওয়ার জন্য এই বন্ধকে নিবন্ধন করুন register
register_shutdown_function($backgroundJob);
পরিশেষে যখন ক্লায়েন্টকে প্রতিক্রিয়া প্রেরণ করা হয়েছিল তখন আপনি ক্লায়েন্টের সাথে সংযোগ বন্ধ করতে পারেন এবং পিএইচপি প্রক্রিয়াটির সাথে কাজ চালিয়ে যেতে পারেন:
fast_cgi_finish_request();
বন্ধটি দ্রুত_সিজি_ফিনিশ_প্রয়োজনের পরে কার্যকর করা হবে।
$ বার্তাটি কোনও সময় দৃশ্যমান হবে না। এবং আপনি যতটা ক্লোজার্স চান তা নিবন্ধভুক্ত করতে পারেন, তবে স্ক্রিপ্ট সম্পাদনের সময় সম্পর্কে যত্ন নিন। এটি কেবল তখনই কাজ করবে যদি পিএইচপি দ্রুত সিজিআই মডিউল হিসাবে চালিত হয় (এটি কি ঠিক ছিল?!)
পিএইচপি স্ক্রিপ্টিং অন্য ডেস্কটপ অ্যাপ্লিকেশন বিকাশকারী ভাষার মতো নয়। ডেস্কটপ অ্যাপ্লিকেশন ভাষাগুলিতে আমরা একটি পটভূমি প্রক্রিয়া চালাতে ডেমন থ্রেড সেট করতে পারি তবে পিএইচপি-তে কোনও প্রক্রিয়া ঘটে যখন কোনও পৃষ্ঠার জন্য ব্যবহারকারীকে অনুরোধ করা হয়। তবে সার্ভারের ক্রোন জব কার্যকারিতা যা পিএইচপি স্ক্রিপ্টটি ব্যবহার করে একটি পটভূমি কাজ সেট করা সম্ভব।
আমরা যারা উইন্ডোজ ব্যবহার করি তাদের জন্য এটি দেখুন:
তথ্যসূত্র: http://php.net/manual/en/function.exec.php# 43917
আমিও উইন্ডোজের ব্যাকগ্রাউন্ডে স্ক্রিনটি চালিয়ে যাওয়া চালিয়ে যাওয়ার জন্য একটি প্রোগ্রাম পাওয়ার সাথে কুস্তি করেছিলাম। অন্যান্য সমাধানগুলির বিপরীতে এই পদ্ধতিটি আপনাকে কোনও প্রোগ্রাম ন্যূনতম, সর্বাধিক বা কোনও উইন্ডো ছাড়াই শুরু করার অনুমতি দেয়। llbra @ phpbrasil এর সমাধানটি কাজ করে তবে ডেস্কটপে এটি কখনও কখনও অযাচিত উইন্ডো তৈরি করে যখন আপনি সত্যই টাস্কটি গোপনে চালিত করতে চান।
নোটপ্যাড.এক্সি পটভূমিতে হ্রাস করা শুরু করুন:
<?php
$WshShell = new COM("WScript.Shell");
$oExec = $WshShell->Run("notepad.exe", 7, false);
?>
পটভূমিতে অদৃশ্য একটি শেল কমান্ড শুরু করুন:
<?php
$WshShell = new COM("WScript.Shell");
$oExec = $WshShell->Run("cmd /C dir /S %windir%", 0, false);
?>
এমএসপেইন্টটি সর্বাধিকীকরণ শুরু করুন এবং স্ক্রিপ্টটি চালিয়ে যাওয়ার আগে এটি বন্ধ করার জন্য অপেক্ষা করুন:
<?php
$WshShell = new COM("WScript.Shell");
$oExec = $WshShell->Run("mspaint.exe", 3, true);
?>
রান () পদ্ধতি সম্পর্কে আরও তথ্যের জন্য এখানে যান: http://msdn.microsoft.com/library/en-us/script56/html/wsMthRun.asp
সম্পাদিত ইউআরএল:
উপরের লিঙ্কটি আর উপস্থিত না থাকায় পরিবর্তে https://technet.microsoft.com/en-us/library/ee156605.aspx এ যান ।
Fatal error: Class 'COM' not found
আমি জানি এটি একটি 100 বছরের পুরানো পোস্ট, তবে যাইহোক, ভেবেছিল এটি কারও পক্ষে কার্যকর হতে পারে। আপনি পৃষ্ঠায় কোথাও একটি অদৃশ্য চিত্র রাখতে পারেন যা ইউআরএলটিকে নির্দেশ করে যা ব্যাকগ্রাউন্ডে চালানো দরকার:
<img src="run-in-background.php" border="0" alt="" width="1" height="1" />