PDA

View Full Version : سوال: نحوه اجرای اسکریپت php در پس زمینه با استفاده از تابع exec()



generalhak
دوشنبه 29 مهر 1392, 13:30 عصر
سلام
من یک فایل به اسم myfile.php دارم که میخوام اون رو در پس زمینه اجرا کنم
از ignore_user_abort() نمیشه استفاده کنم چون تابع خوبی نیست ! یعنی اگر بعضی توابع خواص در اسکریپت وجود داشته باشند و یا کانفیگ درست نباشه درست کار نمیکنه
و تا اونجا که فهمیدم بهترین را استفاده از exec() هست
و در ضمن مثلا من میخوام این فایل رو مثلا 10 بار اجرا کنم یعنی 10 تا از همین اسکریپت همزمان در پس زمینه اجرا بشن تا وقتی که خود فایل اجراش تموم بشه هم قطع نشن
حالا چطوری باید از این تابع استفاده کنم ؟ فرمانی که میزنم باید چی باشه ؟
سیستم من هم linux هست و فرض کنید این فایل هم درون root cpanel من قرار داره
مثلا آدرس فایل به این صورت هست :


/home/test/public_html/myfile.php

mbf5923
دوشنبه 29 مهر 1392, 18:33 عصر
چندین راه برای این کار وجود داره:
یکیش که با استفاده از خود php هستش با استفاده از تابع زیر:

function JobStartAsync($server, $url, $port=81,$conn_timeout=30, $rw_timeout=86400)
{
$errno = '';
$errstr = '';

set_time_limit(0);

$fp = fsockopen($server, $port, $errno, $errstr, $conn_timeout);
if (!$fp) {
echo "$errstr ($errno)<br />\n";
return false;
}
$out = "GET $url HTTP/1.1\r\n";
$out .= "Host: $server\r\n";
$out .= "Connection: Close\r\n\r\n";

stream_set_blocking($fp, false);
stream_set_timeout($fp, $rw_timeout);
fwrite($fp, $out);

return $fp;
}
روش فراخوانی هم به شکل زیر:

JobStartAsync('localhost','/myfile.php',80);
روش دوم استفاده از ajax هستش:

function execute(filename,var1,var2,var3)
{
var xmlhttp;
if(window.XMLHttpRequest)
{
//Code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp = new XMLHttpRequest();
}
else if(window.ActiveXObject)
{
//Code for IE6, IE5
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
else
{
alert("Your browser does not support AJAX!");
}

var url = filename+"?";
var params = "var1="+var1+"&var2="+var2+"&var3="+var3;

xmlhttp.open("POST", url, true);

xmlhttp.onreadystatechange=function()
{
if(xmlhttp.readyState==4)
{
//Below line will fill a DIV with ID 'response'
//with the reply from the server. You can use this to troubleshoot
//document.getElementById('response').innerHTML=xmlh ttp.responseText;

xmlhttp.close;
}
}

//Send the proper header information along with the request
xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xmlhttp.setRequestHeader("Content-length", params.length);
xmlhttp.setRequestHeader("Connection", "close");

xmlhttp.send(params);
document.getElementById('msg').innerHTML ='Runing Program';
}
فراخوانی هم متفاوته دیگه مثلا:

<button type="button" onclick="execute('myfile.php')">Start With Ajax</button>

generalhak
دوشنبه 29 مهر 1392, 19:23 عصر
ممنون ولی من سوالم در کل روش استفاده از exec() بود
این تابعی که شما گفتید فکر نکنم مطمعن باشه !
میخوام وقتی صفحه بسته میشه کار کنه اسکریپت و روش هم مطمعن باشه

mbf5923
دوشنبه 29 مهر 1392, 19:37 عصر
این روش اصلا صفحه رو باز نمیکنه که اگه بسته بشه دیگه کارنکنه
استفاده از exec رو بنده تا بحال ندیدم کسی برای اجرای فایل php ازش استفاده کنه

MMSHFE
دوشنبه 29 مهر 1392, 19:45 عصر
برای کارهای پشت صحنه، همونطور که استارتر اشاره کردن، exec و shell_exec مطمئن ترین روشها محسوب میشن. البته به شرطی که توی اسکریپتتون دو کد زیر رو بگذارین:


set_time_limet(0);
ignore_user_abort();

ضمناً یک نکته که خیلی مهمه دقت کنید اینه که در این روش (فراخوانی بصورت CLI) به Session و کوکی و... دسترسی ندارین چون اصلاً کلاینت در کار نیست که بخواد State داشته باشه. بعلاوه دستورات shell_exec و exec روی اکثر سرورها بخاطر مسائل امنیتی بسته است ولی اگه سرور اختصاصی دارین یا این دستورات باز هستن، روش اجرا بصورت زیر هست:
اگه به کنسول سرور (SSH و ترمینال و...) دسترسی دارین، این دستور رو به تعداد موردنظر بنویسید:

nohup path/to/php path/to/your/script.php > /dev/null &
در غیر اینصورت، این کد رو در یک اسکریپت PHP بنویسید و اجراش کنید:

shell_exec('nohup path/to/php path/to/your/script.php > /dev/null &');
نکته: استفاده از nohup باعث میشه اسکریپت در وضعیت No hang up اجرا بشه یعنی تا وقتی که کاربر root بطور دستی با kill نیاد Process رو از بین ببره، خود سیستم عامل اسکریپت رو نمیبنده حتی اگه با کمبود منابع مواجه بشه.

generalhak
دوشنبه 29 مهر 1392, 20:14 عصر
برای کارهای پشت صحنه، همونطور که استارتر اشاره کردن، exec و shell_exec مطمئن ترین روشها محسوب میشن. البته به شرطی که توی اسکریپتتون دو کد زیر رو بگذارین:


set_time_limet(0);
ignore_user_abort();

ضمناً یک نکته که خیلی مهمه دقت کنید اینه که در این روش (فراخوانی بصورت CLI) به Session و کوکی و... دسترسی ندارین چون اصلاً کلاینت در کار نیست که بخواد State داشته باشه. بعلاوه دستورات shell_exec و exec روی اکثر سرورها بخاطر مسائل امنیتی بسته است ولی اگه سرور اختصاصی دارین یا این دستورات باز هستن، روش اجرا بصورت زیر هست:
اگه به کنسول سرور (SSH و ترمینال و...) دسترسی دارین، این دستور رو به تعداد موردنظر بنویسید:

nohup path/to/php path/to/your/script.php > /dev/null &
در غیر اینصورت، این کد رو در یک اسکریپت PHP بنویسید و اجراش کنید:

shell_exec('nohup path/to/php path/to/your/script.php > /dev/null &');
نکته: استفاده از nohup باعث میشه اسکریپت در وضعیت No hang up اجرا بشه یعنی تا وقتی که کاربر root بطور دستی با kill نیاد Process رو از بین ببره، خود سیستم عامل اسکریپت رو نمیبنده حتی اگه با کمبود منابع مواجه بشه.
سلام
اینطوری که شما گفتید که بازم شد همون که نمیخواستم بشه !!
اگر بخوام از دو تابع
set_time_limet(0);
ignore_user_abort();
استفاده کنم که دیگه خوب میرم صفحه رو باز میکنم بعد میبندم !!
من دسترسی سرور دارم فقط میخوام یه روش مطمعن باشه که وسطش قطع نشه
اگر از اون 2 تابع استفاده کنم به راحتی میشه از دیتابیس زمانی که صفحه بسته شده استفاده کرد ؟!

MMSHFE
دوشنبه 29 مهر 1392, 20:29 عصر
بله بخاطر وجود اون & در انتها، CLI منتظر تمام شدن اسکریپت نمیمونه و اسکریپت اصلی PHP کارش تمام میشه و بسته میشه و اون اسکریپتها که با nohup صدا زدین، کارشون رو انجام میدن. درمورد امنیت این روش خیالتون راحت باشه. ما با همین روش یک Download Manager با امکان Leech از سرورهای اشتراک فایل و دانلود همزمان چند فایل طراحی کردیم که داره همچنان بدون مشکل کار میکنه. نمیدونم مشکلتون با ignore_user_abort چیه چون این تابع فقط میگه اگه کاربر موقع بارگذاری صفحه با Esc درخواست لغو بارگذاری رو داد، اسکریپت این درخواست رو نادیده بگیره و تا وقتی کارش تمام نشده، همچنان فعالیت خودش رو ادامه بده. set_time_limit هم که محدودیت زمان اجرا رو تعیین میکنه و اگه صفر بفرستیم یعنی محدودیت رو برداشتیم. این روش خیلی با بازکردن صفحه فرق میکنه. حتی میتونید با کمک دستورات لینوکس مثل pgrep و grep و فیلترکردن با ps -aux و... توی خود اسکریپت، دنبال Processهای مختلفش بگردین و اگه تعداد اجراهاش کمتر از 10 بود، اسکریپتتون به تعداد لازم دوباره خودش رو تکثیر کنه.