در این آموزش می خواهیم نحوه ایجاد لینک غیر مستقیم برای فایل ها را در زبان برنامه نویسی PHP فرا بگیریم. ایجاد لینک غیر مستقیم برای فایل ها می تواند امکانات سودمندی برای ما فراهم آورد. از جمله این امکانات می توان به محدود کردن سرعت دانلود، فعال/غیرفعال کردن قابلیت ادامه دادن دانلود، تغییر دادن لینک دانلود فایلها بدون نیاز به جابجایی آنها به منظور جلوگیری از سوء استفاده دیگر سایت ها، اعمال محدودیت برای دسترسی به فایل ها و… اشاره کرد. برای ساخت لینک غیرمستقیم برای فایل ها، باید اقدامات زیر را انجام دهیم:
[checklist]
-
-
- دایرکتوری فایل های مورد نظر را از دسترس مستقیم خارج کنیم
- آدرس واقعی هر فایل را به همراه یک کد منحصر به فرد در جدولی از دیتابیس ذخیره کنیم
- صفحه ای برای دانلود کاربران ایجاد کرده و در آن صفحه به کمک کد منحصر به فرد که در مرحله قبل ایجاد کردیم، فایل مربوطه را خوانده و همانند آن را برای کاربر ارسال می کنیم.
-
[/checklist]
[divider]
نحوه ی محدود کردن دسترسی به دایرکتوری در لینوکس
محدود کردن دسترسی به دایرکتوری ها توسط فایل .htaccess انجام می شود. برای انجام این کار به دایرکتوری مورد نظر بروید و فایل .htaccess را در آن ایجاد کرده و کد زیر را در آن قرار دهید:
Deny From All
از این پس اگر کاربری تلاش کند تا بطور مستقیم به این دایرکتوری و فایل های آن دسترسی داشته باشد، با خطای ۴۰۳ به معنای ممنوعیت دسترسی مواجه خواهد شد.
[divider]
تولید لینک غیر مستقیم منحصر به فرد برای هر فایل
فرض کنید صفحه ای که قرار است اطلاعات را ذخیره کند، save.php باشد. برای اینکه این صفحه بتواند کار خود را به درستی انجام دهد، باید اطلاعات را به وسیله فرم به آن ارسال کنیم(آپلود کنیم). برای این منظور به یک فرم ساده آپلود نیاز خواهیم داشت :
<!DOCTYPE html> <html> <body> <form action="save.php" method="post" enctype="multipart/form-data"> <label for="file">نام فایل: </label> <input type="file" name="file" id="file"><br> <input type="submit" name="submit" value="ارسال"> </form> </body> </html>
در صفحه save.php ضمن ذخیره کردن فایل در دایرکتوری مورد نظر(که محدودیت دسترسی بر روی آن اعمال شده)، باید نام فایل، نوع و حجم آن را در دیتابیس ذخیره کنیم. همچنین باید برای هر فایل یک ID منحصر به فرد تولید کنیم. برای تولید این ID می توانیم از تابع زیر کمک بگیریم.
محتوای فایل GUID.php:
<?php function GUID() { if (function_exists('com_create_guid') === true) { return trim(com_create_guid(), '{}'); } return sprintf('%04X%04X-%04X-%04X-%04X-%04X%04X%04X', mt_rand(0, 65535), mt_rand(0, 65535), mt_rand(0, 65535), mt_rand(16384, 20479), mt_rand(32768, 49151), mt_rand(0, 65535), mt_rand(0, 65535), mt_rand(0, 65535)); } ?>
هر بار که این تابع فراخوانی شود، خروجی آن یک مقدار متفاوت و غیرتکراری خواهد بود. در کنار این تابع نیازمند تابع دیگری برای ذخیره ی اطلاعات در دیتابیس خواهیم بود. این تابع می تواند مانند کد زیر باشد.
محتوای فایل SaveData.php
<?php include 'GUID.php'; function SaveData($fileName, $fileType, $fileSize){ $con=mysqli_connect("localhost","user","pass","database"); // Check connection if (mysqli_connect_errno()) { return "Failed to connect to MySQL: " . mysqli_connect_error(); } $gid = GUID(); $sql = "INSERT INTO myfiles VALUES ('$fileName', '$fileType','$fileSize','$gid')"; if(!mysqli_query($con,$sql)) die('Error: ' . mysqli_error($con)); mysqli_close($con); return "Successfully Saved!"; } ?>
در کد بالا به جای user و pass و database به ترتیب نام کاربری و کلمه عبور مربوط به کاربر اضافه شده به دیتابیس و نام دیتابیس را قرار دهید. اکنون به کمک این توابع می توانیم صفحه save.php را کدنویسی کنیم.
محتوای فایل save.php:
<?php include 'SaveData.php'; $fname = $_FILES["file"]["name"]; $ftype = $_FILES["file"]["type"]; $fsize = $_FILES["file"]["size"]; if ($_FILES["file"]["error"] > 0) { echo "Return Code: " . $_FILES["file"]["error"] . "<br>"; } else { echo "Upload: " . $fname . "<br>"; echo "Type: " . $ftype . "<br>"; echo "Size: " . ($fsize / 1024) . " kB<br>"; echo "Temp file: " . $_FILES["file"]["tmp_name"] . "<br>"; if (file_exists("upload/" . $_FILES["file"]["name"])) { echo $fname . " already exists. "; } else { move_uploaded_file($_FILES["file"]["tmp_name"], "upload/" . $fname); echo "Stored in: " . "upload/" . $fname; SaveData($fname, $ftype, $fsize); } } ?>
برای ساخت جدول مربوطه نیز می توان از کد SQL زیر کمک گرفت:
CREATE TABLE `myfiles` ( `FileName` varchar(50) COLLATE utf8_persian_ci NOT NULL, `FileType` varchar(50) COLLATE utf8_persian_ci NOT NULL, `FileSize` varchar(20) COLLATE utf8_persian_ci NOT NULL, `FileLink` varchar(50) COLLATE utf8_persian_ci NOT NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_persian_ci; ALTER TABLE `myfiles` ADD PRIMARY KEY (`FileLink`);
خب، قسمت آپلود و محدود کردن دسترسی مستقیم به فایل ها کدنویسی شد! در آموزش بعدی نحوه دانلود فایل ها از لینک غیر مستقیم را بررسی خواهیم کرد.
موفق و پیروز باشید…
کی قسمت دوم آموزش رو میزاین
با سلام
بخش دوم آموزش تهیه شده و تا چند روز آینده منتشر می شود.
سلام
راه حل برای سایتی که در حال حاظر بیش ۱۰۰ فایل با لینک مستقیم داره چیه؟
در این روشی که فرمودید باید تک تک برای هر فایل این مراحل انجام شود؟!
سلام،
در این آموزش فرض بر این بوده که قبلا فایلی آپلود نشده باشه، اما برای سایت هایی که فایل هایی با لینک مستقیم دارن و میخوان لینک ها رو غیر مستقیم کنن هم میشه دایرکتوری فایل رو به روش گفته شده در آموزش، ببندید و بعد یک فایل php برای دانلود قرار بدید(مثلا download.php) و نام فایلی رو که میخواین دانلود بشه رو به این فایل بدید(مثلا download.php?file=myfile.mp3) و در فایل php مذکور کدهای مربوط به خواندن فایل و چاپ آن را قرار دهید تا بتونین به طور غیرمستقیم دانلود کنین.
توضیحات بیشتر در این زمینه در بخش دوم آموزش بیان خواهد شد.
سلام
ممنون از آموزش خوبتون
می شه بخش دوم رو هم بگذارید
سلام،
با تشکر از دیدگاه شما،
به زودی بخش دوم آموزش منتشر خواهد شد.
موفق و پیروز باشید
سلام ممنون از آموزشتون
چندتا سوال داشتم و نیاز به کمک دارم
۱-میخوام کاربر فقط بتونه فایل pdf و jpg آپلود کنه و امنیت آپلود هم حفظ بشه تا شل آپلود نکنن
۲-بعد از آپلود بجای نمایش مشخصات فایل میخوام فقط پیغام نمایش داده بشه که مدارک شما با موفقیت ارسال شد و بعد از نمایش پیغام هر فایلی که کاربرا ارسال کردن براشون نمایش داده بشه ،بطور کلی و شفاف بگم :کاربر مدارک رو آپلود کرده و پیغام موفقیت آمیز یا خطا در آپلود نمایش داده بشه و بعد همون فایل هایی که آپلود کرده تو همون قسمت براش به نمایش در بیاد
یجورایی مثل سایتهای سازمانی و شرکتی باشه که مدارک میخوان و ارسال میکنی بعد تو پروفایلت تو همون صفحه ارسال مدارکت به نمایش در میاد .
ممنون میشم راهنمایی کنید یا یه نمونه کدی بهم بدید ،از این آموزشتون تونستم استفاده کنم ولی این مواردی که ذکر کردم برام یکم مشکله راه اندازیش و به php کامل مسلط نیستم .
سلام،
برای اینکه کاربر رو مجبور کنی که فقط پسوندهای خاصی رو بتونه آپلود کنه باید به تگ input که برای انتخاب فایل قرار دادی خصوصیت accept رو اضافه کنی و پسوندهای دلخواهت رو داخلش قرار بدی. “لینک آموزش”
البته این روش لازمه اما کافی نیست. باید با پی اچ پی هم نوع فایل رو چک کنی و ببینی مطابقت داره یا نه. برای اینکار هم میتونی از راهنمای سایت رسمی php کمک بگیری. “لینک آموزش”
موفق و پیروز باشی
سلام
ممنون از پاسخ و راهنماییتون
برای اینکه بعد از آپلود ،فایل آپلودی هر کاربر تو صفحه ارسال مدارک نماش داده بشه باید چیکار کنم عزیز ؟
سلام دوباره و عرض معذرت بابت تاخیر در جواب،
برای اینکه بتونی مدرک هر کاربر رو در صفحه ارسال مدارکش نشون بدی به دو چیز نیاز داری. اول آدرس فایل مدرک و دوم کاربری که فایل مدرک به اون تعلق داره.
پیشنهاد میکنم در جدولی که نام فایل ها و محل ذخیره کردنشون رو قرار دادی یه ستون دیگه اضافه کنی و ID کاربری که صاحب مدرک هست رو قرار بدی. اینطوری میتونی به راحتی مدارک هر کاربر رو پیدا کرده و نمایش بدی.
اگر توضیحات بیشتر لازم داشتی بگو تا بیشتر توضیح بدم.
موفق و پیروز باشی…
سلام
ممنون از آموزش های واقعا عالیتون
من شنیدم اگه فایل ها رو بر روی دیتابیس ذخیره کنیم سرعت سایت پایین میاد مخصوصا اگه تعداد فایل زیاد باشه (تعداد فایل های من حدود ۲۰ تا ۳۰ هزار فایل)
۱ – اگر فایل ها رو بر روی دایرکتوری ذخیره کنیم چه جوری باید عمل کنیم
۲ – فایل ها بر روی دایرکتوری باشه بهتره یا اینکه روی همون دیتابیس ذخیره بشه بهتره؟
با سلام
ذخیره فایل ها در دیتابیس باعث بالا رفتن حجم دیتابیس و در نتیجه کاهش سرعت اون میشه. میتونید فایل هاتون رو داخل یک دایرکتوری قرار بدین و آدرس فایل ها رو در دیتابیس نگهداری کنید. با این کار بهتر می تونید فایل هاتون رو مدیریت کنید و هم چنین با افت سرعت هم مواجه نمیشین.