PDA

View Full Version : دانلود فایل توسط PHP



mst_ab
چهارشنبه 27 اردیبهشت 1391, 02:17 صبح
سلام، یه سرور FTPداریم که فایل های تصویری حجیمی روش هست، مثلاً 200 مگ، می خوام به کاربرام یه لینک بدم که اولاً PHP باشه، و از طریق هدر Content-Disposition: attachment کاربر رو مجبور به دانلود کردن فایل کنه، (توی پلیر ویندوز باز نکنه) در ثانی، فایل رو کش نکنه چون 200 مگه، می خوام همون جوری که داره از سرور FTP می خونه بفرسته برای browser .
کسی حرفه ای باشه براش کاری نداره. مرسی همگی... :قلب:

Unique
چهارشنبه 27 اردیبهشت 1391, 15:23 عصر
بهترین روش برای فایل های بزرگ اینه که بی خیال php بشیم و کار را بدیم دست اوستا یعنی apache و اون یعنی این شکلی :


header("X-Sendfile: $somefile");
header("Content-type: application/octet-stream");
header('Content-Disposition: attachment; filename="' . basename($file) . '"');

mst_ab
پنج شنبه 28 اردیبهشت 1391, 00:40 صبح
روش جالبیه، خیلی ممنون یه چیزایی گرفتم، هدر اول رو یه توضیح مختصری میدی چی کار می کنه؟

mst_ab
پنج شنبه 28 اردیبهشت 1391, 00:44 صبح
$somefile اشاره گر فایل هست یا رشته حاوی آدرس اون؟
با آدرس FTP کار می کنه؟ مثلاً این:

ftp://user:password@101.11.27.33/somefile.mpg
؟

Unique
پنج شنبه 28 اردیبهشت 1391, 22:15 عصر
X-Sendfile از Apache درخواست میکنه که خودش ارسال فایل به کاربر را مدیریت کنه (چه حافظه چه فرآیند)
somefile$ هم همون آدرس کامل فایل هست ! FTP نمیخواد ! آدرس کامل بدین !

MMSHFE
پنج شنبه 28 اردیبهشت 1391, 23:57 عصر
البته یک نکته هم بد نیست گفته بشه و اون هم اینکه برای فایلهای حجیم بهتره با fread فایل رو تکه تکه بخونید و بفرستین تا قابلیت Resume Support رو به دانلودتون بدین. ضمناً تابع header هم مال PHP هست نه Apache ! نشون به اون نشون که روی IIS هم کار میکنه!!!

Unique
شنبه 30 اردیبهشت 1391, 00:34 صبح
ضمناً تابع header هم مال PHP هست نه Apache

بله تابع header میاد و یک http header را به سرویس دهنده حالا چه IIS چه Apache چه ... اعلام میکنه ! منظور من این بود که وقتی header با نام X-Sendfile ارسال بشه ! از اوجا به بعد php نقشی در ارسال فایل بازی نمیکنه و buffer کردن و غیره را خود Apache یا IIS به عهده میگرند. کلا مدیریت حافظه به صورت بهینه انجام خواهد شد !

البته وقت تست کردن ندارم ولی به احتمال 90% خود IIS به صورت بالفطره X-Sendfile را پشتیبانی نمیکنه و باید حتمی یک Plugin چیزی روی IIS نصب بشه که این اتفاق روی Shared Server ها نمیفته !

php_love
دوشنبه 13 خرداد 1392, 14:17 عصر
سلام

عزیزان لطفا یک تابعی که هم قابلیت Resume‌ داشته باشه - هم در مواجه با فایل های حجیم مشکلی نداشته باشه و با افت سرعت مواجه نشه (مثل وقتی که کاربر با لینک مستقیم دانلود می کنه) کدش رو اینجا قرار بدین .

ممنون میشم کاربر واجب و فوریه

Unique
سه شنبه 14 خرداد 1392, 03:06 صبح
من برای فایل های بزرگ از X-Sendfile استفاده کردم ! البته مربوط به چند سال پیش بود ولی بعید میدونم resume نداشته باشه ! کلا خیلی تنظیمات میشه بهش داد (منظورم ماژول مربوطه هست). اول تست کنین و متسنداتش را هم بررسی کنین بعد اگه نشد اونوقت میشه resume را با fread هم فراهم کرد ! اما خیلی بعید میدونم با X-Sendfile نشه resume کرد !

php_love
سه شنبه 14 خرداد 1392, 10:28 صبح
این تابع رو پیدا کردم تست کردم جواب داده



function serve_file_resumable ($file, $contenttype = 'application/octet-stream') {

// Avoid sending unexpected errors to the client - we should be serving a file,
// we don't want to corrupt the data we send
@error_reporting(0);

// Make sure the files exists, otherwise we are wasting our time
if (!file_exists($file)) {
header("HTTP/1.1 404 Not Found");
exit;
}

// Get the 'Range' header if one was sent
if (isset($_SERVER['HTTP_RANGE'])) $range = $_SERVER['HTTP_RANGE']; // IIS/Some Apache versions
else if ($apache = apache_request_headers()) { // Try Apache again
$headers = array();
foreach ($apache as $header => $val) $headers[strtolower($header)] = $val;
if (isset($headers['range'])) $range = $headers['range'];
else $range = FALSE; // We can't get the header/there isn't one set
} else $range = FALSE; // We can't get the header/there isn't one set

// Get the data range requested (if any)
$filesize = filesize($file);
if ($range) {
$partial = true;
list($param,$range) = explode('=',$range);
if (strtolower(trim($param)) != 'bytes') { // Bad request - range unit is not 'bytes'
header("HTTP/1.1 400 Invalid Request");
exit;
}
$range = explode(',',$range);
$range = explode('-',$range[0]); // We only deal with the first requested range
if (count($range) != 2) { // Bad request - 'bytes' parameter is not valid
header("HTTP/1.1 400 Invalid Request");
exit;
}
if ($range[0] === '') { // First number missing, return last $range[1] bytes
$end = $filesize - 1;
$start = $end - intval($range[0]);
} else if ($range[1] === '') { // Second number missing, return from byte $range[0] to end
$start = intval($range[0]);
$end = $filesize - 1;
} else { // Both numbers present, return specific range
$start = intval($range[0]);
$end = intval($range[1]);
if ($end >= $filesize || (!$start && (!$end || $end == ($filesize - 1)))) $partial = false; // Invalid range/whole file specified, return whole file
}
$length = $end - $start + 1;
} else $partial = false; // No range requested

// Send standard headers
header("Content-Type: $contenttype");
header("Content-Length: $filesize");
header('Content-Disposition: attachment; filename="'.basename($file).'"');
header('Accept-Ranges: bytes');

// if requested, send extra headers and part of file...
if ($partial) {
header('HTTP/1.1 206 Partial Content');
header("Content-Range: bytes $start-$end/$filesize");
if (!$fp = fopen($file, 'r')) { // Error out if we can't read the file
header("HTTP/1.1 500 Internal Server Error");
exit;
}
if ($start) fseek($fp,$start);
while ($length) { // Read in blocks of 8KB so we don't chew up memory on the server
$read = ($length > 8192) ? 8192 : $length;
$length -= $read;
print(fread($fp,$read));
}
fclose($fp);
} else readfile($file); // ...otherwise just send the whole file

// Exit here to avoid accidentally sending extra content on the end of the file
exit;

}

php_love
سه شنبه 28 خرداد 1392, 11:34 صبح
متاسفانه این تابع هم زیاد کاربردی نبود . سرعت من که 512 هستش و با 64K دانلود می کنم وقتی از این تابع استفاده می کنم به حدود 10K می رسه . علاوه بر اون قطعی هم زیاد داره . بعضی وقت ها که اصلا هیچی دانلود نمیشه .
دوستان اگه راه حل مناسبی دارن خواهش می کنم پیشنهاد بدن .

php_love
سه شنبه 28 خرداد 1392, 22:45 عصر
عزیزان خواهش می کنم کمک کنید . یعنی هیچ راهی نداره !!!!!!!!!!! :افسرده:

php_love
جمعه 31 خرداد 1392, 12:50 عصر
دوستان کسی راه حلی نداره . مدیران عزیز لطفا کمک :ناراحت:

Unique
جمعه 31 خرداد 1392, 22:01 عصر
سعی کردین از روش X-Sendfile استفاده کنین ؟

php_love
شنبه 01 تیر 1392, 14:10 عصر
از روش X-Sendfile استفاده کردم . اما موقعی که می خواد دانلود کنه یه جورایی هیچی رو دانلود می کنه . آدرس فایل درسته ولی هیچی دانلود نمیشه . به مدیر هاست گفتم که X-Sendfile رو هاست نصب هست یا نه . گفت نصبه . ممکنه نصب نباشه و این مشکل به خاطر نصب نبودن X-Sendfile باشه . یا مشکل چیزه دیگه ای هستش ؟

Unique
یک شنبه 02 تیر 1392, 03:50 صبح
یا توی مسیردهی مشکل دارین یا ماژول نصب نیست.

php_love
یک شنبه 02 تیر 1392, 08:22 صبح
چطور می تونم مطمئن شم که ماژول نصبه یا نه . منطور اینم که قطعه کدی هست که به صورت true یا false به من بگه ؟

php_love
یک شنبه 02 تیر 1392, 08:50 صبح
از این قطعه کد واسه چک کردن نصب بودن ماژول X-Sendfile‌ استفاده کردم . اما انگار این Function تو PHP‌ تعریف نشده است !!!!
شما قطعه کدی دیگه ای رو می شناسید که نصب بودن این ماژول رو بهم بگه ؟



if (in_array('mod_xsendfile', apache_get_modules())) {
header("X-Sendfile: $file");
} else {
error_log("Warning! mod-xsendfile is NOT INSTALLED - sending file the old fashion way.....");
header('Content-Length: ' . filesize($file) );
print file_get_contents($file);
}

mehdiv
یک شنبه 02 تیر 1392, 16:32 عصر
سلام بچه ها یه سوال در مورد همین
ما 2 تا سرور داریم میخوایم با یه کد php وصل بشیم به سرور اول یعنی به پورتی که براش تعریف شده
و بعد فایل مورد نظرمونرو به سرور مقصد انتقال بدیم
فایل php روی سرور مقصد نصب میشه من این کدرو دارم


<?php
define('BUFSIZ', 4095);
$url = 'آدرس فایل';
$rfile = fopen($url, 'r');$lfile = fopen(basename($url), 'w');
while(!feof($rfile))fwrite($lfile, fread($rfile, BUFSIZ), BUFSIZ);
fclose($rfile);fclose($lfile);
?>

اما مشکل من اینه که واسه دانلود فایل یوزر نیم و پسورد باید وارد بشه
میواستم بدونم میشه میشه این کد رو طوری تغییر داد که یوزر و پسورد رو توش وارد کنیم
و بعد بتونه فایل رو دانلود که

Unique
دوشنبه 03 تیر 1392, 02:17 صبح
خروجی این را روی سررو بگیر : (این تابع از نسخه 4.3.2 روی php وجود داره)


print_r(apache_get_modules());

php_love
دوشنبه 03 تیر 1392, 14:23 عصر
با چنین اروری مواجه شد !
Fatal error: Call to undefined function apache_get_modules() in /home4/dl_mysite/public_html/index.php on line 168

با مدیریت سرور هم صحبت کردم گفت ماژول X- Sendfile نصبه !!!!
پس چرا موقعی که از قطعه کد زیر استفاده می کنم دانلود منجر هیچی رو دانلود می کنه . به آدرسی هم که دانلود منجر می خواد دانلود کنم نگاه کردم , آدرس فایل رو هم درست وارد می کنم . اما هیچی دانلود می کنه

جایه somefile$ هم آدرسه Base فایل رو گذاشتم و هم آدرس کل فایل رو ولی هیچ تغییری نکرد !! :عصبانی++: :عصبانی++: :عصبانی++:


header("X-Sendfile: $somefile");
header("Content-type: application/octet-stream");
header('Content-Disposition: attachment; filename="' . basename($file) . '"');

php_love
دوشنبه 03 تیر 1392, 20:04 عصر
دوستان مهندس خواهشا به دادم برسید . یعنی جز Unigue عزیز کسه دیگه ای نیست کمک کنه ؟!!
(http://barnamenevis.org/member.php?11933-Unique)

Unique
سه شنبه 04 تیر 1392, 03:17 صبح
فکر کنم apache روی سرور به صورت CGI نصب شده ! میشه چک کنی توی phpinfo ببینی دقیقا چطور نصب شده ؟ (برای چک کردن Call to undefined function apache_get_modules() میگم.

برای اینکه مطمئن تر بشی طرفت چرت و پرت نمیگه ازشون بپرس XSendFilePath را توی config وب سرور چی تعریف کردند. حتی باید این تعریف شده باشه که x-sendfile کار کنه ! در ضمن ببین وب سرور چیه. آخه توی apache بعد از نصب module کافیه این دو خط را بگذارند توی config خود apache یا اگه اجازه داده باشند توی htaccess. :


XSendFile on
XSendFilePath /home/www/example.com/htdocs/files/

اما توی Lighttpd اینطوری باید ست بشه : (البته توی fastcgi)

"allow-x-send-file" => "enable"

در ضمن header اصلی هم X-LIGHTTPD-send-file هست اما گفتند X-SendFile هم کار میکنه !

Nginx هم که کلا ماژول خودش را داره X-Accel-Redirect و اصلا نیاز به نصب نداره و اتومات نصبه ! فرقش هم اینه که باید url بدی جای path روی فایل سیستم.

راستی میگی هیچی دانلود نمیشه یعنی یک فایل 0 کیلو هم برات نمیفرسته ؟ آخه عجیبه !

php_love
چهارشنبه 05 تیر 1392, 02:43 صبح
تازه فهمیدم که وب سرور لایت اسپید هستش و اینکه به جای X-sendfile از X-LIGHTTPD-send-file استفاده کردم . ولی باز هم همون مشکل رو داشت .
فکر کنم طرف درست ست نکرده باشه ؟!!!

Unique
چهارشنبه 05 تیر 1392, 03:32 صبح
البته روی لایت اسپید طبق مستندات سایت خودشون X-sendfile هم باید جواب بده ! به هر حال مشکل از هاست شما هست و باید طرفت را قانع کنی یه اسکریپت را چک کنه یا این موضوعی که میگه X-sendfile نصبه را معلوم کنه.

rezaonline.net
چهارشنبه 05 تیر 1392, 17:13 عصر
خروجی صفر کیلو بایت دارید؟

php_love
پنج شنبه 06 تیر 1392, 13:38 عصر
وقتی که لینک رو کلیک می کنم , آدرس فایل درسته که نرم افزار دانلود منجر باز میشه و وقتی شروع می کنم به فرض یک فایل 500 مگابایتی رو دانلود کنم در عرض 1 ثانیه دانلود منجر دانلودش می کنه که طبیعتا همون هیچی رو داره دانلود می کنه و وقتی هم که فایل فشرده دانلود شده رو می خوام بازش کنم , پیغام اروری ظاهر می شه .

Unique
جمعه 07 تیر 1392, 02:11 صبح
تا اونجایی که من میدونم دارین همون ۰ کیلو دانلود میکنید و مشکل از تنظیمات سرور هستش ! ماژول به درستی نصب نیست.

rezaonline.net
جمعه 07 تیر 1392, 18:01 عصر
ماژول به درستی نصب شده ، فقط باید مسیر xsend فایل رو برای هاست شما فعال کنند ، بصورت دستی باید در شاخه /etc/apache2/sites-avalables فایل default رو ویرایش کنند .

php_love
شنبه 08 تیر 1392, 01:10 صبح
دوستان خوبم نمیشه یه لینک که آموزش کامل تنظیمات xsend باشه رو به من معرفی کنید تا من هم اون لینک رو در اختیار مدیر هاست قرار بدم . به نظرم متاسفانه مدیر هاست از علم لازم در این زمینه برخوردار نیست !!! :ناراحت:

اگه میشه یه لینک معرفی کنید تا بهش بدم مطالعه کنه . خیلی ممنون

Unique
شنبه 08 تیر 1392, 03:05 صبح
ماژول به درستی نصب شده ، فقط باید مسیر xsend فایل رو برای هاست شما فعال کنند ، بصورت دستی باید در شاخه /etc/apache2/sites-avalables فایل default رو ویرایش کنند .
آقا رضا این هم جزو مراحل نصب درست ماژول هست دیگه ! ;)


دوستان خوبم نمیشه یه لینک که آموزش کامل تنظیمات xsend باشه رو به من معرفی کنید تا من هم اون لینک رو در اختیار مدیر هاست قرار بدم
متاسفانه هاست های ایرانی یا خودشون اصلا config نمیکنند و دارند از یک third party میگیرند یا اگه خودشون config مینند خدا را بنده نیستند و فکر میکنند آخر متخصص شبکه هستند و کارشون ایراد نداره. شما نیاز به آموزش دادن بهشون ندارین ! ticket بزنین و بگین شاخه default را برای x-sendfile تنظیم نکردند اگه ماژول را درست نصب کرده اند و بخواهین بررسی کنند. در ضمن سعی کنین از هاست های غیر ایرانی استفاده کنین ، من ضد ایرانی نیستما اما خدایی هاست خوب ایرانی خیلی خیلی کم دیدم.

php_love
شنبه 08 تیر 1392, 03:18 صبح
یه سئواله دیگه حالا اگه شانس ما گرفت و این مدیر هاست از پسه تنظیمات بر اومد این xsendfile قابلیت resume‌ هم داره یا نداره ؟؟

Unique
یک شنبه 09 تیر 1392, 04:25 صبح
xsendfile کنترل را میده دست apache و تا اونجا که من میدونم دقیقا مثل اینه ک هفایل را مستقیم دانلود کنین ! یعنی resume داره !

php_love
پنج شنبه 13 تیر 1392, 01:58 صبح
متاسافنه مدیر هاست اعلام کرد که با این ماژول کار نکرده و قابلیت کانفیگ کردنش و نداره . دوستان ممنون میشم اگه لینک آموزش مراحل تنظیمات ماژول X-sendfile رو واسم بزارید تا بهش بدم .

البته دوستمون Unique این لینک (https://tn123.org/mod_xsendfile/) رو تویه یه تاپیکی گذاشته بودن اما باز نمیشه . اگه دوستان لطف کنن ممنون میشم