آپلود فایل در PHP — راهنمای کاربردی

۳۲۲ بازدید
آخرین به‌روزرسانی: ۰۸ مهر ۱۴۰۲
زمان مطالعه: ۸ دقیقه
آپلود فایل در PHP — راهنمای کاربردی

در این مقاله در مورد مقدمات آپلود فایل در PHP صحبت خواهیم کرد. در ابتدا گزینه‌های پیکربندی PHP که برای آپلود موفق فایل‌ها ضروری هستند را بررسی می‌کنیم. سپس یک مثال واقعی از روش انجام این کار را معرفی خواهیم کرد.

پیکربندی تنظیمات PHP

چند تنظیم در PHP وجود دارند که باید پیش از انجام عملیات آپلود فایل به صورت موفق بررسی شوند. در این بخش هر یک از را بررسی کرده و در مورد آن‌ها توضیحاتی ارائه می‌کنیم. این گزینه‌ها را می‌توانید در فایل php.ini پیکربندی کنید.

اگر مطمئن نیستید که این فایل روی سیستم شما در کدام مسیر قرار دارد می‌توانید از دستور ()php_ini_loaded_file برای یافتن آن استفاده کنید. کافی است یک فایل PHP روی سرور خود ایجاد کرده و خط کد زیر را درون آن قرار دهید و سپس آن را در مرورگر باز کنید:

1<?php echo php_ini_loaded_file();?>

در ادامه خلاصه‌ای از این فایل به همراه مقادیر پیش‌فرض مفید ارائه شده است:

1; Whether to allow HTTP file uploads.
2file_uploads = On
3 
4; Temporary directory for HTTP uploaded files.
5; Will use system default if not set.
6;upload_tmp_dir = 
7 
8; Maximum allowed size for uploaded files.
9upload_max_filesize = 16M
10 
11; Maximum number of files that can be uploaded via a single request
12max_file_uploads = 20
13 
14; Maximum size of POST data that PHP will accept.
15post_max_size = 20M
16 
17max_input_time = 60
18memory_limit = 128M
19max_execution_time = 30

تنظیمات کلیدی

در ادامه برخی تنظیمات کلیدی  که برای آپلود فایل در PHP ضروری هستند را با هم بررسی می‌کنیم.

file_uploads

مقدار دایرکتیو file_uploads باید برابر با on تنظیم شود تا امکان آپلود فایل وجود داشته باشد. مقدار پیش‌فرض این دایرکتیو on است.

upload_max_filesize

دایرکتیو upload_max_filesize امکان پیکربندی اندازه بیشینه فایلی که آپلود خواهد شد را تعیین می‌کند. به طور پیش‌فرض این مقدار برابر با 2M (دو مگابایت) تعیین شده است و می‌توانید آن تنظیمات را در فایل htaccess. نیز تغییر دهید. دو مگابایت با استانداردهای امروزی عدد بزرگی محسوب نمی‌شود و ممکن است بخواهید این مقدار را افزایش دهید. اگر در زمان آپلود کردن فایل با خطای file exceeds upload_max_filesize مواجه شدید، باید این مقدار را افزایش دهید. اگر قصد چنین کاری را دارید، دقت کنید که باید مقدار post_max_size را نیز افزایش دهید. در ادامه در این مورد نیز توضیح داده‌ایم.

upload_tmp_dir

این دایرکتیو یک پوشه موقت تعیین می‌کند که برای ذخیره‌سازی فایل‌های آپلود شونده استفاده خواهد شد. در اغلب موارد لازم نیست در مورد این تنظیمات دغدغه‌ای داشته باشید. اگر آن را تنظیم نکنید، دایرکتوری پیش‌فرض temp سیستم استفاده خواهد شد.

post_max_size

دایرکتیو post_max_size امکان پیکربندی اندازه بیشینه داده‌های POST را فراهم می‌سازد. از آنجا که فایل‌ها با درخواست‌های POST آپلود می‌شوند، این مقدار باید بزرگ‌تر از مقداری باشد که برای دایرکتیو upload_max_filesize تعیین کرده‌اید. برای نمونه اگر upload_max_filesize برابر با 16M یعنی 16 مگابایت است، باید مقدار post_max_size را نیز برابر با 20M قرار دهید.

max_file_uploads

این دایرکتیو امکان تعیین تعداد بیشینه فایل‌هایی که می‌توانند همزمان آپلود شوند را فراهم می‌سازد. مقدار پیش‌فرض 20 است که عدد معقولی محسوب می‌شود.

max_input_time

این دایرکتیو تعداد بیشینه ثانیه‌هایی که یک اسکریپت مجاز به تفسیر داده‌های ورودی است را تعیین می‌کند. این مقدار در صورتی که قصد دارید فایل‌های بزرگی را دانلود کنید، باید به صورت یک مقدار معقول برای نمونه 60 (60 ثانیه) تعیین شود که برای اغلب اپلیکیشن‌ها مقدار مناسبی است.

memory_limit

دایرکتیو memory_limit مقدار بیشینه حافظه‌ای که یک اسکریپت مصرف می‌کند را تعیین خواهد کرد. اگر در طی آپلود کردن فایل‌های بزرگ با مشکلاتی مواجه شده‌اید، باید مطمئن شوید که مقدار تعیین شده برای این دایرکتیو بزرگ‌تر از مقداری است که برای post_max_size تعیین کرده‌اید. مقدار پیش‌فرض آن 128M یا (128 مگابایت) است و از این رو به جز در مواردی که مقدار post_max_size و upload_max_filesize خیلی بالا تنظیم شده باشند، نباید در مورد آن نگرانی داشته باشید.

max_execution_time

این دایرکتیو تعداد بیشینه ثانیه‌هایی که یک اسکریپت، مجاز به اجرا شدن است را تعیین می‌کند. اگر با مشکلاتی در طی آپلود فایل‌های بزرگ مواجه شدید، باید این مقدار را افزایش دهید. مقدار 30 (30 ثانیه) در مورد اغلب اپلیکیشن‌ها به خوبی کار می‌کند. در ادامه مثال واقعی خود را برای نمایش روش آپلود فایل‌ها در PHP می‌نویسیم.

ایجاد یک فرم HTML

زمانی که تنظیمات PHP موردنیاز را که در بخش قبل اشاره کردیم پیکربندی نمودید، می‌توانید شروع به استفاده از ظرفیت آپلود فایل در PHP بکنید. ما قصد داریم دو فایل PHP به نام‌های index.php و upload.php بسازیم. فایل index.php کدی را در خود جای می‌دهد که مسئول نمایش فرم آپلود است. در سوی دیگر فایل upload.php مسئول آپلود کردن فایل به سرور خواهد بود.

ضمناً یک فایل در دایرکتوری uploaded_files آپلود خواهد شد تا مطمئن شویم که پوشه مورد نظر وجود دارد و از سوی کاربر web-server قابل نوشتن است. در ادامه بخش‌های کلیدی فایل index.php را بررسی می‌کنیم.

1<?php
2session_start(); 
3?>
4<!DOCTYPE html>
5<html>
6<head>
7  <title>PHP File Upload</title>
8</head>
9<body>
10  <?php
11    if (isset($_SESSION['message']) && $_SESSION['message'])
12    {
13      printf('<b>%s</b>', $_SESSION['message']);
14      unset($_SESSION['message']);
15    }
16  ?>
17  <form method="POST" action="upload.php" enctype="multipart/form-data">
18    <div>
19      <span>Upload a File:</span>
20      <input type="file" name="uploadedFile" />
21    </div>
22 
23    <input type="submit" name="uploadBtn" value="Upload" />
24  </form>
25</body>
26</html>

با این که کد فوق شبیه یک فرم معمولی PHP به نظر می‌رسد؛ اما یک تفاوت مهم در آن وجود دارد و آن مقدار خصوصیت enctype در تگ <form> است. این مقدار باید به صورت multipart/form-data تعیین شود تا فرم بتواند شامل فیلد فایل باشد.

خصوصیت enctype نوع انکودینگی که باید هنگام تحویل فرم استفاده شود را تعیین می‌کند و یکی از سه مقدار زیر را می‌گیرد:

  • application/x-www-form-urlencoded: این مقدار پیش‌فرضی است که وقتی مقدار خصوصیت enctype به صورت صریح تعیین نشده باشد مورد استفاده قرار می‌گیرد. در این حالت، کاراکترها پیش از آن که به سرور ارسال شوند. کدگذاری می‌شوند. اگر فیلد فایل را روی فرم خود ندارید باید از این مقدار برای خصوصیت enctype استفاده کنید.
  • multipart/form-data: زمانی که از مقدار multipart/form-data برای خصوصیت enctype استفاده می کید؛ امکان آپلود فایل‌ها با استفاده از متد POST ایجاد می‌شود. ضمناً این مقدار تضمین می‌کند که کاراکترها هنگامی که فرم تحویل می‌شود کدگذاری نمی‌شوند.
  • text/plain: این مقدار به طور کلی استفاده نمی‌شود. در این تنظیمات داده‌ها به صورت کدگذاری نشده ارسال می‌شوند.

سپس فیلد فایل را در خروجی ارائه می‌کنیم تا امکان انتخاب فایل از روی رایانه کاربر پدید آید:

1<input type="file" name="uploadedFile" />

جدا از آن یک پیام را در ابتدای فرم نمایش می‌دهیم. این پیام وضعیت فایلی که آپلود می‌شود را نشان می‌دهد و در متغیر session با استفاده از اسکریپت upload.php ارسال می‌شود. در ادامه این بخش این مورد را دقیق‌تر بررسی خواهیم کرد.

1<?php
2    if (isset($_SESSION['message']) && $_SESSION['message'])
3    {
4      printf('<b>%s</b>', $_SESSION['message']);
5      unset($_SESSION['message']);
6    }
7?>

بدین ترتیب فایل index.php را توضیح دادیم. در بخش بعدی روش مدیریت فایل آپلود شده در سمت سرور را مشاهده خواهیم کرد.

ایجاد منطق آپلود

در بخش قبلی یک فرم HTML ساختیم که در سمت کلاینت نمایش می‌یابد و امکان آپلود فایل از روی رایانه کاربر را فراهم می‌کند. در این بخش همتای بخش سرور آن فایل را می‌بینیم که امکان مدیریت فایل‌های آپلود شده را روی سرور فراهم می‌کند. فایل موردنیاز در سمت سرور upload.php نام دارد و محتوای آن به صورت زیر است:

1<?php
2session_start();
3$message = ''; 
4if (isset($_POST['uploadBtn']) && $_POST['uploadBtn'] == 'Upload')
5{
6  if (isset($_FILES['uploadedFile']) && $_FILES['uploadedFile']['error'] === UPLOAD_ERR_OK)
7  {
8    // get details of the uploaded file
9    $fileTmpPath = $_FILES['uploadedFile']['tmp_name'];
10    $fileName = $_FILES['uploadedFile']['name'];
11    $fileSize = $_FILES['uploadedFile']['size'];
12    $fileType = $_FILES['uploadedFile']['type'];
13    $fileNameCmps = explode(".", $fileName);
14    $fileExtension = strtolower(end($fileNameCmps));
15    // sanitize file-name
16    $newFileName = md5(time() . $fileName) . '.' . $fileExtension;
17    // check if file has one of the following extensions
18    $allowedfileExtensions = array('jpg', 'gif', 'png', 'zip', 'txt', 'xls', 'doc');
19    if (in_array($fileExtension, $allowedfileExtensions))
20    {
21      // directory in which the uploaded file will be moved
22      $uploadFileDir = './uploaded_files/';
23      $dest_path = $uploadFileDir . $newFileName;
24      if(move_uploaded_file($fileTmpPath, $dest_path)) 
25      {
26        $message ='File is successfully uploaded.';
27      }
28      else 
29      {
30        $message = 'There was some error moving the file to upload directory. Please make sure the upload directory is writable by web server.';
31      }
32    }
33    else
34    {
35      $message = 'Upload failed. Allowed file types: ' . implode(',', $allowedfileExtensions);
36    }
37  }
38  else
39  {
40    $message = 'There is some error in the file upload. Please check the following error.<br>';
41    $message .= 'Error:' . $_FILES['uploadedFile']['error'];
42  }
43}
44$_SESSION['message'] = $message;
45header("Location: index.php");

در ادامه بخش‌های مهم این فایل را توضیح می‌دهیم. در فایل upload.php در ابتدا بررسی می‌کنیم که آیا درخواست POST معتبری صورت گرفته است یا نه:

1if (isset($_POST['uploadBtn']) && $_POST['uploadBtn'] == 'Upload') {
2...
3}

در PHP وقتی که فایلی آپلود می‌شود، متغیر superglobal به نام FILES_$ با اطلاعاتی در مورد فایل آپلود شده ایجاد می‌شود. مقداردهی اولیه این متغیر به صورت آرایه‌ای شامل اطلاعات زیر برای فایل آپلود شده است:

  • tmp_name: مسیر موقتی که فایل آپلود می‌شود در این متغیر ذخیره شده است.
  • Name: نام واقعی فایل آپلود شده در این متغیر ذخیره شده است.
  • Size: نشان‌دهنده اندازه فایل آپلود شده بر حسب بایت است.
  • Type: شامل نوع mime فایل آپلود شده است.
  • Error: اگر خطایی در طی آپلود فایل رخ داده باشد، این متغیر با پیام خطای مربوطه مقداردهی می‌شود. در حالت آپلود موفق فایل این متغیر شامل مقدار 0 خواهد بود که می‌توان آن را با ثابت UPLOAD_ERR_OK مقایسه کرد.

پس از اعتبارسنجی درخواست POST باید به بررسی بودن آپلود فایل بپردازیم.

1if (isset($_FILES['uploadedFile']) && $_FILES['uploadedFile']['error'] === UPLOAD_ERR_OK) {
2...
3}

می‌بینید که متغیر FILES_$ یک آرایه چندبعدی است. عنصر اول نام فیلد فایل است و عنصر دوم نیز اطلاعاتی در مورد فایل آپلود شده است که قبلاً بررسی کردیم.

اگر آپلود فایل موفقیت‌آمیز باشد، چند متغیر را با اطلاعاتی در مورد فایل آپلود شده مقداردهی می‌کنیم:

1// get details of the uploaded file
2$fileTmpPath = $_FILES['uploadedFile']['tmp_name'];
3$fileName = $_FILES['uploadedFile']['name'];
4$fileSize = $_FILES['uploadedFile']['size'];
5$fileType = $_FILES['uploadedFile']['type'];
6$fileNameCmps = explode(".", $fileName);
7$fileExtension = strtolower(end($fileNameCmps));

در قطعه کد فوق، پسوند فایل آپلود شده را نیز تشخیص داده و در متغیر fileExtension$ ذخیره می‌کنیم. از آنجا که فایل آپلود شده شامل فاصله و دیگر کاراکترهای خاص باشد، بهتر است نام فایل «پاکسازی» (sanitize) شود و این دقیقاً همان کاری است که در خط کد زیر انجام می‌دهیم:

1$newFileName = md5(time(). $fileName). '.'. $fileExtension;

بسیار مهم است که نوع فایل‌هایی که می‌توانند آپلود شوند را محدود کنیم و اجازه آپلود هر نوع فایلی را به کاربران ندهیم. این کار از طریق بررسی پسوند فایل آپلود شده صورت می‌گیرد و صرفاً به برخی پسوندها امکان آپلود فایل داده می‌شود:

1$allowedfileExtensions = array('jpg', 'gif', 'png', 'zip', 'txt', 'xls', 'doc');
2
3if (in_array($fileExtension, $allowedfileExtensions)) {
4
5...
6
7}

در نهایت از تابع move_uploaded_file برای جا به جایی فایل آپلود شده به مکان خاص انتخابی استفاده می‌کنیم:

1// directory in which the uploaded file will be moved
2$uploadFileDir = './uploaded_files/';
3$dest_path = $uploadFileDir . $newFileName;
4 
5if(move_uploaded_file($fileTmpPath, $dest_path))
6{
7  $message ='File is successfully uploaded.';
8}
9else
10{
11  $message = 'There was some error moving the file to upload directory. Please make sure the upload directory is writable by web server.';
12}

تابع move_uploaded_file دو آرگومان می‌گیرد. آرگومان نخست نام فایل آپلود شده و آرگومان دوم مسیر مقصدی که می‌خواهیم فایل انتقال یابد. درنهایت کاربر را به فایل index. php بازهدایت می‌کنیم. ضمناً پیام مناسبی در متغیر session قرار می‌دهیم که پس از بازهدایت کاربر به این فایل نمایش یابد.

جمع‌بندی طرز کار آپلود فایل در PHP

فراموش نکنید که دایرکتوری uploaded_files را ایجاد کنید و آن را برای کاربر web-server قابل نوشتن بسازید. سپس فایل index.php را اجرا کنید که فرم آپلود فایل را به صورت زیر نمایش می‌دهد:

uploaded_files

با کلیک روی دکمه Browse یک کادر گفتگو باز می‌شود که امکان انتخاب فایل از روی رایانه محلی را فراهم می‌سازد. یک فایل را با پسوندهای مجاز انتخاب کرده و روی دکمه Upload کلیک کنید. بدین ترتیب فرم تحویل می‌شود و اگر همه چیز درست پیش برود می‌بینید که فایل در دایرکتوری uploaded_files آپلود شده است. همچنین می‌توانید فایل‌های دیگری را با پسوندهایی که مجاز نیستند آپلود کنید تا وضعیت مقابله اسکریپت با آپلود فایل را تست کنید.

سخن پایانی

در این نوشته به برسی مقدماتی از آپلود فایل در PHP پرداختیم. در نیمه نخست این مقاله به بررسی گزینه‌های مختلف پیکربندی که برای عملکرد آپلود فایل ضروری هستند پرداختیم. سپس یک مثال واقعی را بررسی کردیم که روش آپلود عملی فایل‌ها در PHP را معرفی می‌کند.

اگر این مطلب برای شما مفید بوده است، آموزش‌های زیر نیز به شما پیشنهاد می‌شوند:

==

بر اساس رای ۵ نفر
آیا این مطلب برای شما مفید بود؟
اگر بازخوردی درباره این مطلب دارید یا پرسشی دارید که بدون پاسخ مانده است، آن را از طریق بخش نظرات مطرح کنید.
منابع:
tutsplus
نظر شما چیست؟

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *