
آموزش برنامه نویسی PHP-جلسه سیزدهم
برای آپلود یک فایل در سرور ابتدا باید configure سرور را چک کنید. تا ببینید اجازه آپلود فایل داده شده یا نه برای این کار داخل زمپ در بخش apache، روی configکلیک میکنید و گزینه php.ini را انتخاب میکنید.
یکی از قابلیتهای کاربردی PHP، امکان آپلود فایل توسط کاربر و ذخیره آن روی سرور است. این قابلیت در بسیاری از وبسایتها مانند فروشگاههای اینترنتی، سایتهای آموزشی، پنلهای کاربری و شبکههای اجتماعی استفاده میشود.
در این جلسه یاد میگیریم چگونه در PHP یک فرم آپلود فایل ایجاد کنیم، فایل را دریافت و در یک پوشه مشخص ذخیره کنیم و قبل از ذخیره، مواردی مانند نوع فایل، حجم فایل و وجود فایل مشابه را بررسی کنیم.
نکته: کدهای این آموزش برای یادگیری مفهوم آپلود فایل نوشته شدهاند. در پروژههای واقعی بهتر است کنترلهای امنیتی بیشتری نیز اضافه شود.
Table of contents [Show]
- 1 PHP File Upload چیست؟
- 2 تنظیمات PHP برای آپلود فایل
- 3 ایجاد پوشه برای ذخیره فایلها
- 4 دریافت نام فایل در PHP
- 5 آشنایی با آرایه $_FILES
- 6 بررسی پسوند فایل
- 7 بررسی وجود فایل
- 8 بررسی حجم فایل
- 9 بررسی فرمت فایل
- 10 بررسی اینکه فایل واقعاً تصویر است
- 11 آپلود نهایی فایل با move_uploaded_file()
- 12 کد کامل سیستم آپلود فایل در PHP
- 13 نکات امنیتی مهم در آپلود فایل
- 14 تفاوت بررسی پسوند و نوع واقعی فایل
- 15 جمعبندی آموزش آپلود فایل در PHP
PHP File Upload چیست؟
در PHP برای دریافت فایل از کاربر، معمولاً از یک فرم HTML با ویژگی زیر استفاده میکنیم:
enctype="multipart/form-data"این ویژگی بسیار مهم است؛ زیرا اگر فرم شامل آپلود فایل باشد، بدون multipart/form-data اطلاعات فایل به شکل صحیح به سرور ارسال نمیشود.
همچنین برای ارسال فایل بهتر است از متد POST استفاده کنیم.
ساختار کلی فرم به شکل زیر است:
<form action="upload.php" method="post" enctype="multipart/form-data">
<label for="fileToUpload">انتخاب فایل:</label>
<input type=file name=fileToUpload id="fileToUpload">
<input type=submit value="آپلود فایل" name=submit> </form>در این فرم:
actionمشخص میکند اطلاعات فرم به کدام فایل PHP ارسال شود.method="post"اطلاعات را با متد POST ارسال میکند.enctype="multipart/form-data"برای ارسال فایل ضروری است.type="file"یک فیلد انتخاب فایل ایجاد میکند.name="fileToUpload"نامی است که در PHP برای دسترسی به فایل استفاده میکنیم.
تنظیمات PHP برای آپلود فایل
قبل از اجرای سیستم آپلود، باید مطمئن شویم PHP اجازه آپلود فایل را دارد.
اگر از XAMPP استفاده میکنید، میتوانید فایل php.ini را باز کنید. در XAMPP معمولاً از مسیر زیر نیز قابل دسترسی است:
XAMPP → Apache → Config → PHP (php.ini)
در فایل php.ini گزینه زیر را پیدا کنید:
file_uploads = Onاین گزینه باید روی On باشد.
همچنین دو تنظیم مهم دیگر وجود دارند:
upload_max_filesize = 2M
post_max_size = 8Mupload_max_filesize حداکثر اندازه مجاز برای یک فایل را مشخص میکند و post_max_size حداکثر حجم اطلاعاتی را مشخص میکند که از طریق POST ارسال میشود.
بعد از تغییر تنظیمات php.ini، در صورت نیاز Apache را Restart کنید.
ایجاد پوشه برای ذخیره فایلها
فرض کنید پروژه ما ساختار زیر را داشته باشد:
my-project/
│
├── index.php
├── upload.php
└── uploads/پوشه uploads محلی است که فایلهای آپلودشده در آن ذخیره میشوند.
در PHP میتوانیم مسیر این پوشه را در یک متغیر قرار دهیم:
$target_dir = "uploads/";دریافت نام فایل در PHP
اطلاعات فایل ارسالشده توسط کاربر در آرایه $_FILES قرار میگیرد.
برای دریافت نام فایل میتوانیم از کد زیر استفاده کنیم:
$target_file = $target_dir . basename($_FILES["fileToUpload"]["name"]);در اینجا:
$_FILES["fileToUpload"]به فایلی اشاره میکند که در فرم HTML نام آن fileToUpload بوده است.
همچنین:
$_FILES["fileToUpload"]["name"]نام اصلی فایل را در اختیار ما قرار میدهد.
تابع basename() نیز برای استخراج نام فایل از مسیر استفاده میشود.
آشنایی با آرایه $_FILES
یکی از مهمترین بخشهای آپلود فایل در PHP، آرایه $_FILES است.
برای مثال:
$_FILES["fileToUpload"]["name"]نام فایل را برمیگرداند.
$_FILES["fileToUpload"]["type"]نوع MIME اعلامشده توسط مرورگر را برمیگرداند.
$_FILES["fileToUpload"]["size"]حجم فایل را بر حسب بایت مشخص میکند.
$_FILES["fileToUpload"]["tmp_name"]مسیر فایل موقت روی سرور را در اختیار ما قرار میدهد.
$_FILES["fileToUpload"]["error"]وضعیت خطای آپلود را مشخص میکند.
بررسی پسوند فایل
برای بررسی پسوند فایل میتوانیم از pathinfo() استفاده کنیم:
$imageFileType = strtolower(
pathinfo($target_file, PATHINFO_EXTENSION)
);در اینجا:
PATHINFO_EXTENSIONپسوند فایل را استخراج میکند.
سپس با استفاده از:
strtolower()پسوند را به حروف کوچک تبدیل میکنیم.
برای مثال:
JPGبه:
jpgتبدیل میشود.
بررسی وجود فایل
یکی از مشکلات سیستمهای آپلود این است که ممکن است کاربر فایلی با همان نام یک فایل قبلی ارسال کند.
برای بررسی این موضوع میتوانیم از file_exists() استفاده کنیم:
if (file_exists($target_file)) {
echo "Sorry, file already exists.";
$uploadOk = 0;
}اگر فایل موردنظر از قبل وجود داشته باشد، مقدار $uploadOk را صفر میکنیم تا عملیات آپلود انجام نشود.
بررسی حجم فایل
برای محدود کردن حجم فایل میتوانیم مقدار size را بررسی کنیم.
برای مثال، کد زیر فایلهای بزرگتر از ۵۰۰ کیلوبایت را رد میکند:
if ($_FILES["fileToUpload"]["size"] > 500000) {
echo "Sorry, your file is too large.";
$uploadOk = 0;
}البته بهتر است محدودیت حجم را متناسب با نیاز پروژه تعیین کنیم.
برای مثال اگر بخواهیم حداکثر حجم را 2MB در نظر بگیریم:
if ($_FILES["fileToUpload"]["size"] > 2 * 1024 * 1024) {
echo "حجم فایل بیشتر از 2 مگابایت است.";
$uploadOk = 0;
}بررسی فرمت فایل
اگر سیستم ما فقط باید تصاویر را دریافت کند، بهتر است فقط فرمتهای موردنظر را اجازه دهیم.
برای مثال:
if (
$imageFileType != "jpg" &&
$imageFileType != "jpeg" &&
$imageFileType != "png" &&
$imageFileType != "gif"
) {
echo "فقط فایلهای JPG، JPEG، PNG و GIF مجاز هستند.";
$uploadOk = 0;
}در این حالت اگر کاربر فایل دیگری مانند pdf یا zip ارسال کند، آپلود متوقف میشود.
بررسی اینکه فایل واقعاً تصویر است
یکی از نکات مهم این است که صرفاً به پسوند فایل اعتماد نکنیم.
برای بررسی اینکه فایل واقعاً یک تصویر است، میتوانیم از getimagesize() استفاده کنیم:
$check = getimagesize($_FILES["fileToUpload"]["tmp_name"]);
if ($check !== false) {
echo "فایل یک تصویر معتبر است.";
} else {
echo "فایل تصویر معتبر نیست.";
$uploadOk = 0;
}تابع getimagesize() اطلاعات مربوط به تصویر را بررسی میکند و اگر فایل تصویر معتبر نباشد، نتیجه مناسبی برنمیگرداند.
آپلود نهایی فایل با move_uploaded_file()
بعد از اینکه تمام بررسیها با موفقیت انجام شدند، میتوانیم فایل را از محل موقت به پوشه موردنظر منتقل کنیم.
برای این کار از move_uploaded_file() استفاده میکنیم:
if (move_uploaded_file(
$_FILES["fileToUpload"]["tmp_name"],
$target_file
)) {
echo "فایل با موفقیت آپلود شد.";
} else {
echo "در هنگام آپلود فایل خطایی رخ داد.";
}پارامتر اول، مسیر فایل موقت است و پارامتر دوم، مسیر نهایی ذخیره فایل.
کد کامل سیستم آپلود فایل در PHP
حالا تمام قسمتهایی که تا اینجا یاد گرفتیم را در یک فایل upload.php قرار میدهیم:
<?php
$target_dir = "uploads/";
$target_file = $target_dir . basename($_FILES["fileToUpload"]["name"]);
$uploadOk = 1;
$imageFileType = strtolower(
pathinfo($target_file, PATHINFO_EXTENSION)
);
// بررسی ارسال فرم if (isset($_POST["submit"])) {
// بررسی اینکه فایل واقعاً تصویر است
$check = getimagesize($_FILES["fileToUpload"]["tmp_name"]);
if ($check !== false) {
echo "File is an image - " . $check["mime"] . "<br>";
} else {
echo "File is not an image.<br>";
$uploadOk = 0;
}
}
// بررسی وجود فایل if (file_exists($target_file)) {
echo "Sorry, file already exists.<br>";
$uploadOk = 0;
}
// بررسی حجم فایل if ($_FILES["fileToUpload"]["size"] > 500000) {
echo "Sorry, your file is too large.<br>";
$uploadOk = 0;
}
// بررسی فرمت فایل if (
$imageFileType != "jpg" &&
$imageFileType != "jpeg" &&
$imageFileType != "png" &&
$imageFileType != "gif"
) {
echo "Sorry, only JPG, JPEG, PNG & GIF files are allowed.<br>";
$uploadOk = 0;
}
// بررسی نهایی if ($uploadOk == 0) {
echo "Sorry, your file was not uploaded.";
} else {
if (
move_uploaded_file(
$_FILES["fileToUpload"]["tmp_name"],
$target_file
)
) {
echo "The file " .
htmlspecialchars(
basename($_FILES["fileToUpload"]["name"])
) .
" has been uploaded.";
} else {
echo "Sorry, there was an error uploading your file.";
}
}
?>نکات امنیتی مهم در آپلود فایل
سیستم آپلود فایل یکی از بخشهایی است که در پروژههای واقعی باید با دقت بیشتری پیادهسازی شود. هرگز نباید فقط به پسوند فایل اعتماد کنیم.
برای مثال بهتر است علاوه بر پسوند، نوع واقعی فایل نیز بررسی شود.
همچنین توصیه میشود نام فایل ذخیرهشده را مستقیماً از نامی که کاربر ارسال کرده انتخاب نکنیم. میتوانیم یک نام تصادفی برای فایل ایجاد کنیم:
$newFileName = uniqid() . "." . $imageFileType;
$target_file = $target_dir . $newFileName;در پروژههای واقعی همچنین بهتر است موارد زیر را در نظر بگیریم:
- محدود کردن حجم فایل
- محدود کردن فرمتهای مجاز
- بررسی MIME Type واقعی فایل
- جلوگیری از آپلود فایلهای اجرایی
- تولید نام تصادفی برای فایل
- جلوگیری از جایگزین شدن فایلهای قبلی
- بررسی خطاهای
$_FILES["fileToUpload"]["error"] - تنظیم صحیح دسترسی پوشه
uploads - جلوگیری از اجرای فایلهای اسکریپتی در پوشه آپلود
- اعتبارسنجی سمت سرور حتی اگر در سمت HTML نیز محدودیت ایجاد شده باشد
تفاوت بررسی پسوند و نوع واقعی فایل
فرض کنید کاربر فایلی با نام زیر ارسال کند:
image.php.jpgیا فایلی را با تغییر نام از یک فرمت دیگر به .jpg تبدیل کند.
بنابراین بررسی این قسمت:
pathinfo($target_file, PATHINFO_EXTENSION)بهتنهایی تضمین نمیکند که محتوای فایل واقعاً یک تصویر است.
به همین دلیل در سیستمهای حرفهای بهتر است از روشهای دیگری مانند finfo_file() نیز برای بررسی MIME واقعی فایل استفاده شود.
مثلاً:
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mimeType = finfo_file(
$finfo,
$_FILES["fileToUpload"]["tmp_name"]
);
finfo_close($finfo);
$allowedTypes = [
"image/jpeg",
"image/png",
"image/gif"
];
if (!in_array($mimeType, $allowedTypes)) {
die("فرمت فایل مجاز نیست.");
}این روش کنترل دقیقتری روی نوع فایل ایجاد میکند.
جمعبندی آموزش آپلود فایل در PHP
در این جلسه با نحوه ساخت یک سیستم ساده آپلود فایل در PHP آشنا شدیم. برای این کار ابتدا یک فرم HTML با method="post" و enctype="multipart/form-data" ایجاد کردیم.
سپس در فایل PHP با استفاده از $_FILES اطلاعات فایل را دریافت کردیم و موارد مختلفی مانند نام فایل، حجم، پسوند، وجود فایل و معتبر بودن تصویر را بررسی کردیم.
در نهایت با استفاده از تابع:
move_uploaded_file()فایل را از مسیر موقت به پوشه uploads منتقل کردیم.
فرآیند کلی آپلود فایل در PHP را میتوان به شکل زیر خلاصه کرد:
انتخاب فایل توسط کاربر
↓
ارسال فرم با POST
↓
دریافت فایل با $_FILES
↓
بررسی خطای آپلود
↓
بررسی حجم و نوع فایل
↓
بررسی امنیتی فایل
↓
تعیین نام و مسیر ذخیرهسازی
↓
move_uploaded_file()
↓
ذخیره فایل در سرور
مریم گوهرزاد
مدرس و بنیانگذار هلدینگ آرتا رسانه. برنامه نویس و محقق حوزه بلاکچین و توسعهدهنده بلاکچین | متخصص Solidity | توسعهدهنده وب Full-Stackمن یک توسعهدهنده علاقهمند به فناوریهای بلاکچین و وب ۳ هستم و در زمینه Solidity، توسعه قراردادهای هوشمند و ساخت برنامههای غیرمتمرکز (DApps) فعالیت میکنم. تمرکز من بر طراحی و پیادهسازی راهکارهایی است که در کنار بهرهگیری از فناوریهای نوین، عملکرد مناسب، امنیت و تجربه کاربری مطلوبی ارائه دهند.در کنار تخصص در حوزه بلاکچین، به عنوان یک توسعهدهنده وب Full-Stack نیز در طراحی و توسعه وبسایتها و برنامههای تحت وب فعالیت میکنم. تجربه کار در بخشهای Front-End و Back-End به من این امکان را داده است که پروژهها را از مرحله ایده و طراحی تا توسعه و اجرا، با دیدی جامع دنبال کنم. در فرآیند توسعه، توجه ویژهای به کدنویسی تمیز، معماری مناسب، طراحی واکنشگرا، عملکرد مطلوب و تجربه کاربری روان دارم.



