2017-04-22 79 views
0

我有一個工作的上傳文件腳本,現在我希望做腳本通過限制文件擴展名的安全,我不知道該怎麼做限制在PHP上傳腳本擴展上傳

<?php 
$extensions = array("docx","pdf","png"); 
if(isset($_FILES['files'])){ 
    $errors= array(); 
    foreach($_FILES['files']['tmp_name'] as $key => $tmp_name){ 
     $file_name = $key.$_FILES['files']['name'][$key]; 
     $file_size =$_FILES['files']['size'][$key]; 
     $file_tmp =$_FILES['files']['tmp_name'][$key]; 
     $file_type=$_FILES['files']['type'][$key];  
     $query="INSERT into upload_data (`USER_ID`,`FILE_NAME`,`FILE_SIZE`,`FILE_TYPE`) VALUES('$user_id','$file_name','$file_size','$file_type'); "; 
     $desired_dir="uploads"; 
     if(empty($errors)==true){ 
      if(is_dir($desired_dir)==false){ 
       mkdir("$desired_dir", 0700);  // Create directory if it does not exist 
      } 

      if(is_dir("$desired_dir/".$file_name)==false){ 
       move_uploaded_file($file_tmp,"user_data/".$file_name); 
      }else{         //rename the file if another one exist 
       $new_dir="user_data/".$file_name.time(); 
       rename($file_tmp,$new_dir) ;    
      } 
      mysql_query($query);    
     }else{ 
       print_r($errors); 
     } 
    } 
    if(empty($error)){ 
     echo "Successfully uploaded"; 
    } 
} 
?> 

這裏是形式提交方法我使用

<form action="" method="POST" enctype="multipart/form-data"> 
<input type="file" name="files[]" multiple="" class="btn btn-inverse btn-icon input-block-level" /> 
<input type="submit" class="save btn btn2" style="padding: 0px; margin: 10px; "/> 
</form> 
+1

哇!已經過了17分鐘,我沒有看到任何不使用'mysql_ *'函數的警告,它們已被棄用。 – Jigar

回答

1

php.net | Handling file uploads

// DO NOT TRUST $_FILES['upfile']['mime'] VALUE !! 
// Check MIME Type by yourself. 
$finfo = new finfo(FILEINFO_MIME_TYPE); 
if (false === $ext = array_search(
    $finfo->file($_FILES['upfile']['tmp_name']), 
    array(
     'jpg' => 'image/jpeg', 
     'png' => 'image/png', 
     'gif' => 'image/gif', 
    ), 
    true 
)) { 
    throw new RuntimeException('Invalid file format.'); 
} 

完整上傳代碼:

upload.php的

<?php 

header('Content-Type: text/plain; charset=utf-8'); 

try { 

    // Undefined | Multiple Files | $_FILES Corruption Attack 
    // If this request falls under any of them, treat it invalid. 
    if (
     !isset($_FILES['upfile']['error']) || 
     is_array($_FILES['upfile']['error']) 
    ) { 
     throw new RuntimeException('Invalid parameters.'); 
    } 

    // Check $_FILES['upfile']['error'] value. 
    switch ($_FILES['upfile']['error']) { 
     case UPLOAD_ERR_OK: 
      break; 
     case UPLOAD_ERR_NO_FILE: 
      throw new RuntimeException('No file sent.'); 
     case UPLOAD_ERR_INI_SIZE: 
     case UPLOAD_ERR_FORM_SIZE: 
      throw new RuntimeException('Exceeded filesize limit.'); 
     default: 
      throw new RuntimeException('Unknown errors.'); 
    } 

    // You should also check filesize here. 
    if ($_FILES['upfile']['size'] > 1000000) { 
     throw new RuntimeException('Exceeded filesize limit.'); 
    } 

    // DO NOT TRUST $_FILES['upfile']['mime'] VALUE !! 
    // Check MIME Type by yourself. 
    $finfo = new finfo(FILEINFO_MIME_TYPE); 
    if (false === $ext = array_search(
     $finfo->file($_FILES['upfile']['tmp_name']), 
     array(
      'jpg' => 'image/jpeg', 
      'png' => 'image/png', 
      'gif' => 'image/gif', 
     ), 
     true 
    )) { 
     throw new RuntimeException('Invalid file format.'); 
    } 

    // You should name it uniquely. 
    // DO NOT USE $_FILES['upfile']['name'] WITHOUT ANY VALIDATION !! 
    // On this example, obtain safe unique name from its binary data. 
    if (!move_uploaded_file(
     $_FILES['upfile']['tmp_name'], 
     sprintf('./uploads/%s.%s', 
      sha1_file($_FILES['upfile']['tmp_name']), 
      $ext 
     ) 
    )) { 
     throw new RuntimeException('Failed to move uploaded file.'); 
    } 

    echo 'File is uploaded successfully.'; 

} catch (RuntimeException $e) { 

    echo $e->getMessage(); 

} 

?> 

upload.html

<form action="upload.php" method="post" enctype="multipart/form-data"> 
    Select image to upload: 
    <input type="file" name="upfile" id="fileToUpload"> 
    <input type="submit" value="Upload Image" name="submit"> 
</form> 

注意
1 - mysql_*擴展是很久以前的過時,使用mysqliPDOprepared statements

2 - Windows用戶必須在php.ini取消註釋extension=php_fileinfo.dll啓用Fileinfo擴展。從docs (榮譽@Jigar)

3 - 確保在同一目錄作爲php存在名爲uploads一個文件夾。

+0

注意評論倒票? –

+1

注意:Windows用戶必須在php.ini中包含綁定的php_fileinfo.dll DLL文件以啓用Fileinfo擴展名。從[docs](http://php.net/manual/en/fileinfo.installation.php) – Jigar

+0

@Jigar注意到,指出這一點。 –

0

只需使用pathinfo()獲得file extension

<?php 

    $extensions = array("docx","pdf","png"); 

    $_FILES["file"]["name"] ="file_name.png"; 

    $ext = pathinfo($_FILES["file"]["name"], PATHINFO_EXTENSION);; 

    if(in_array($ext,$extensions)) 
    { 
     echo $ext." accepted extenstion"; 
    } 
    else 
    { 
     echo $ext." this file extenstion not accepted"; 
    } 

    ?> 

注:

警告的mysql_query,mysql_fetch_array,的mysql_connect等擴展在PHP 5.5.0被棄用,並且它在去除PHP 7.0.0。 應該使用MySQLi或PDO_MySQL擴展。

+1

您應該**從不僅僅依靠文件擴展名來檢查文件類型**,因爲它很容易被欺騙,您應該檢查MIME類型。 –

+0

感謝您的信息。我要刪除這個答案@PedroLobito – JYoThI