日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

上传问题总结(文件大小检测,大文件上传)

發(fā)布時間:2024/9/20 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 上传问题总结(文件大小检测,大文件上传) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

PHP上傳問題總結(jié)(文件大小檢測,大文件上傳)

????? 由于涉及到本地和服務(wù)器兩方面的安全問題,所以基于input type="file"形式的頁面文件上傳一直處于一個很尷尬的位置。一方面,用戶不希望隱私泄露,所以瀏覽器無法對用戶在上傳時選擇的文件做有效的判 斷。另一方面,為了服務(wù)器端的安全,減輕傳輸負擔,系統(tǒng)又希望能在用戶開始上傳之前就將非法的文件拒之門外。

?????? 一來一去,基于原始input方式的上傳,成為網(wǎng)絡(luò)存儲網(wǎng)站避之唯恐不及的遺留性問題,也造就了現(xiàn)在千奇百怪的插件、上傳客戶端。

?????? input方式的上傳就如此之差么?當然不是。上傳文件不大的時候,它還是非常簡單可靠的,在PHP中,我們只需要一個復合型表單

[xml]?view plaincopy
  • <form?enctype="multipart/form-data"?action="__URL__"?method="POST">??
  • ????? 一個輸入框

    [xml]?view plaincopy
  • <input?name="userfile"?type="file"?/>??
  • ?????? 和服務(wù)器端的一行代碼

    [php]?view plaincopy
  • move_uploaded_file($_FILES['userfile']['tmp_name'],?'/var/www/uploads/'.?basename($_FILES['userfile']['name']));??
  • ?????? 就可以實現(xiàn)整個上傳過程。

    ?????? 但隨文件增大,表單上傳的不足就會暴露出來。尤其是我們想取得最基本的文件大小來阻止過大文件上傳這一簡單的想法,也變得如此困難。以下一一道來:

    通過MAX_FILE_SIZE

    ??????? 我們經(jīng)常會在手冊里讀到:

    MAX_FILE_SIZE 隱藏字段(單位為字節(jié))必須放在文件輸入字段之前,其值為接收文件的最大尺寸。這是對瀏覽器的一個建議,PHP 也會檢查此項。在瀏覽器端可以簡單繞過此設(shè)置,因此不要指望用此特性來阻擋大文件。實際上,PHP 設(shè)置中的上傳文件最大值是不會失效的。但是最好還是在表單中加上此項目,因為它可以避免用戶在花時間等待上傳大文件之后才發(fā)現(xiàn)文件過大上傳失敗的麻煩。

    ?????? 顯然PHP的開發(fā)者們也考慮到了大文件上傳的問題,但就像手冊所說,MAX_FILE_SIZE只是對瀏覽器的一個建議,事實上目前為止所有主流的瀏覽器并沒有采納這個建議,所以采用MAX_FILE_SIZE約束文件大小形同擺設(shè),不可行。

    通過服務(wù)器端

    ?????? MAX_FILE_SIZE既然無效,那么用戶可以將文件上傳到服務(wù)器,服務(wù)器端通過$_FILES['userfile']['size']判斷用戶上 傳的文件大小,然后決定是否接受上傳并返回信息。暫且排除服務(wù)器的負荷以及可能存在的惡意破壞行為,這種解決方案聽起來無非是浪費一部分帶寬,也能對用戶 上傳文件作出約束。

    ?????? 但這也是不可行的,PHP的文件上傳受到php.ini以下這些設(shè)置的影響:

    • post_max_size
    • upload_max_filesize
    • max_execution_time
    • memory_limit

    ?????? 雖然設(shè)置方法在手冊?中都有比較詳細的說明,之所以仍然說此方法不可行,是因為php執(zhí)行腳本在超過memory_limit時,該次的POST數(shù)據(jù)會全部丟失并且不會報錯!

    ?????? 試想用戶填寫了一個超長的表單,并伴隨一個超過memory_limit的文件一起上傳,經(jīng)過了漫長的等待時間之后發(fā)現(xiàn)等來的又是一張干干凈凈的空白表 單,那是何等印象深刻的用戶體驗啊。更何況數(shù)十M的服務(wù)器流量僅僅用來檢測文件大小,是現(xiàn)在的網(wǎng)絡(luò)環(huán)境不允許的。

    通過Javascript

    ??????? Javascript是基于瀏覽器的,雖然JS能完成很多看似不可能的任務(wù),但瀏覽器做不到的事情JS同樣無法做到。先天不足注定了這項工作僅僅靠Javascript是無法勝任的。不過一些IE Only的方法?也還是存在的,僅作參考?。

    通過Flash

    ???????? Flash的FileReference類提供了一套比較全面的文件處理方法,現(xiàn)在大多數(shù)大文件上傳也都采用了基于Flash的方案。如果利用Flash與Js交互,能否實現(xiàn)客戶端對文件大小的檢測呢?答案是可行的。

    ?????? 首先在flash文件中實例化FileReference類。

    [jscript]?view plaincopy
  • var?fr?=?new?FileReference();??
  • ?????? 基于這個類就可以用Flash提供的file browse和SelectFile事件替代瀏覽器的事件。我們需要:

    ?????? 1.綁定SelectFile

    [jscript]?view plaincopy
  • fr.addEventListener(Event.SELECT,?onSelectFile);??
  • ?????? 2.創(chuàng)建一個供Js訪問的對象,用來放置flash得到的文件信息

    [jscript]?view plaincopy
  • var?s?=?{<br>??
  • ???size:0,<br>??
  • ???name:'',<br>??
  • ???type:''<br>??
  • ????}??
  • ?????? 3.創(chuàng)建file browse方法

    [jscript]?view plaincopy
  • function?browseFile():void?{<br>??
  • ?fr.browse();<br>??
  • ????}??
  • ?????? 4.當SelectFile事件觸發(fā)的時候,傳遞文件信息

    [jscript]?view plaincopy
  • function?onSelectFile(e:Event):void?{<br>??
  • ??s.size?=?fr.size;<br>??
  • ??s.name?=?fr.name;<br>??
  • ??s.type?=?fr.type;<br>??
  • ????}??
  • ?????? 5.將browseFile方法公開可供Js調(diào)用

    [jscript]?view plaincopy
  • ExternalInterface.addCallback("browseFile",?browseFile);??
  • ?????? 6.將得到的文件信息傳遞給Js

    [jscript]?view plaincopy
  • ExternalInterface.call("onSelectFile",s);??
  • ?????? 現(xiàn)在我們已經(jīng)可以通過Js獲得由flash傳遞來的文件大小信息了,具體的實現(xiàn)可以參看Demo?。

    結(jié)論

    ?????? 問題至此似乎已經(jīng)得到解決了,我們已經(jīng)成功的校驗了文件大小不是么。但本文的最終結(jié)論是,基于Flash的文件大小校驗,仍然不可行。

    ?????? 文件大小校驗的唯一目的,是為了上傳。在上面的Demo中可以看到校驗成功的文件名會顯示在一個輸入框里。熟悉上傳的同學不覺得少了什么嗎?沒錯,通過 flash只能得到文件名,而無法得到文件的完整路徑,而文件路徑卻是input方式上傳的必要條件。所以雖然可以成功的通過Flash與Js交互校驗文 件大小,但我們能做到的也僅僅只是校驗而已,之后想要上傳,唯有繼續(xù)通過flash方式進行。

    ?????? Flash開發(fā)出于安全考慮屏蔽了文件的完整路徑這無可厚非,不過文件上傳,尤其是PHP環(huán)境下的文件校驗上傳方案仍然沒有得到最好的解決。

    ?????? 當然彌補的方法有很多:

    • 基于Perl的項目?FileChucker?,?XUpload?,?Uber-Uploader
    • 基于Flash的項目?SWFUpload
    • 還有筒子用PHP直接在服務(wù)器華麗的建立socket鏈接?。

    ????? 但終究我希望有一天能看到僅基于HTML就能實現(xiàn)的嚴整健壯的上傳方案,但愿這一天不會太遠。

    ????? 最后是本次的代碼下載?。

    ?

    ?

    php文件上傳大小設(shè)置詳解

    用php上傳文件,問題最多的就是上傳大體積文件時出現(xiàn)錯誤。?
    這就涉及到php的配置文件:php.ini?

    在此配置文件中,有這么幾個值是跟文件上傳有密切關(guān)系的:?
    file_uploads = on //是否允許系統(tǒng)支持文件上傳?
    ;upload_tmp_dir //臨時文件的存儲路徑,linux下為系統(tǒng)默認路徑,win32下需要指定?
    upload_max_filesize = 2m //允許文件上傳最大體積?

    post_max_size = 2m //通過post方法給php時,php所能接受的最大數(shù)據(jù)容量?

    如果你上傳的文件體積在8m一下(通常情況),那修改以上設(shè)置就可以滿足你的要求了。。?

    但要>8m,那除了上面幾個值,還要特別關(guān)注另外兩個值了:?
    max_execution_time = 30 //每個script所執(zhí)行的最大時間(php上傳就時,體積大了,就是個時間問題)?
    memory_limit = 8m //每個script所能消耗的最大memory?

    試著把這兩個值改大些。一般就可以解決大多數(shù)問題了。?

    就此推斷,上傳文件的體積是可以無窮大的。但還要考慮你的網(wǎng)絡(luò)情況,等等。?

    在php.net上,有人說按照這個方法改了后,大于100m的文件還是會出錯。?
    不知道是不是php本身的問題了:

    ?

    ?

    php實現(xiàn)文件上傳的一些經(jīng)驗

    • //圖片上傳處理
      $upload_file=$_FILES['upload_file']['tmp_name'];
      echo $upload_file;
      $upload_file_name=$_FILES['upload_file']['name'];
      $type=strstr($upload_file_name, '.');
      if($upload_file=="")
      {
      $newname="0.jpg";?
      }
      else
      {
      $newname=$newid.$type;
      }
      //$newname=$newid.$type;

      $intonew2="update mms_news_info set col_image='$newname' where col_id='$newid'";
      mysql_query($intonew2,$db);

      ?

      if($upload_file){
      $file_size_max = 1000*1000;// 1M限制文件上傳最大容量(bytes)
      $store_dir = "neirongimg/";// 上傳文件的儲存位置
      $accept_overwrite = 1;//是否允許覆蓋相同文件
      // 檢查文件大小
      if ($upload_file_size > $file_size_max) {
      echo "對不起,你的文件容量大于規(guī)定";
      exit;
      }

      // 檢查讀寫文件
      if (file_exists($store_dir . $upload_file_name) && $accept_overwrite) {
      Echo?? "存在相同文件名的文件";
      exit;
      }

      //復制文件到指定目錄
      if (!move_uploaded_file($upload_file,$store_dir.$newname)) {
      echo "復制文件失敗";
      exit;
      }

      }

      Echo?? "<p>你上傳了文件:";
      echo? $_FILES['upload_file']['name'];
      echo "<br>";
      //客戶端機器文件的原名稱。

      Echo?? "文件的 MIME 類型為:";
      echo $_FILES['upload_file']['type'];
      //文件的 MIME 類型,需要瀏覽器提供該信息的支持,例如“image/gif”。?
      echo "<br>";

      Echo?? "上傳文件大小:";
      echo $_FILES['upload_file']['size'];
      //已上傳文件的大小,單位為字節(jié)。?
      echo "<br>";

      Echo?? "文件上傳后被臨時儲存為:";
      echo $_FILES['upload_file']['tmp_name'];
      //文件被上傳后在服務(wù)端儲存的臨時文件名。?
      echo "<br>";


      $Erroe=$_FILES['upload_file']['error'];
      switch($Erroe){
      case 0:
      Echo?? "上傳成功"; break;
      case 1:
      Echo?? "上傳的文件超過了 php.ini 中 upload_max_filesize 選項限制的值."; break;
      case 2:
      Echo?? "上傳文件的大小超過了 HTML 表單中 MAX_FILE_SIZE 選項指定的值。";??? break;
      case 3:
      Echo?? "文件只有部分被上傳";break;
      case 4:
      Echo?? "沒有文件被上傳";break;
      }

      ??//圖片上傳處理

      ?>
      +++++++++++++++++++++++++++++++++
      關(guān)于錯誤信息的解釋
      從 PHP 4.2.0 開始,PHP 將隨文件信息數(shù)組一起返回一個對應(yīng)的錯誤代碼。該代碼可以在文件上傳時生成的文件數(shù)組中的 ['error'] 字段中被找到,也就是 $_FILES['userfile']['error']。

      ?

      UPLOAD_ERR_OK
      值:0; 沒有錯誤發(fā)生,文件上傳成功。

      UPLOAD_ERR_INI_SIZE
      值:1; 上傳的文件超過了 php.ini 中 upload_max_filesize 選項限制的值。

      UPLOAD_ERR_FORM_SIZE
      值:2; 上傳文件的大小超過了 HTML 表單中 MAX_FILE_SIZE 選項指定的值。

      UPLOAD_ERR_PARTIAL
      值:3; 文件只有部分被上傳。

      UPLOAD_ERR_NO_FILE
      值:4; 沒有文件被上傳。


      注: 這些在 PHP 4.3.0 之后變成了 PHP 常量。


      PHP 能夠接受任何來自符合 RFC-1867 標準的瀏覽器(包括 Netscape Navigator 3 及更高版本,Microsoft Internet Explorer 3 加微軟補丁,或者更高版本)上傳的文件。PHP 的這種特性使得我們既可以上傳文本文件,也可以上傳二進制文件。利用 PHP 的認證和文件操作函數(shù),您就可以控制誰有上傳的權(quán)限,以及在文件上傳后進行哪些處理。

      相關(guān)的設(shè)置: 請參閱 php.ini 的 file_uploads、 upload_max_filesize、upload_tmp_dir 以及 post_max_size 設(shè)置選項。

      請注意 PHP 也支持 PUT 方法的文件上傳,Netscape Composer 和 W3C 的 Amaya 客戶端使用這種方法。請參閱 PUT 方法支持以獲取更多信息。

      您可以如下建立一個特殊的表單來支持文件上傳:

      例子 18-1. 文件上傳表單

      <form enctype="multipart/form-data" action="_URL_" method="POST">
      <input type="hidden" name="MAX_FILE_SIZE" value="30000">
      Send this file: <input name="userfile" type="file">
      <input type="submit" value="Send File">
      </form>


      以上范例中的“_URL_”應(yīng)該替換成指向一個 PHP 文件的真實 URL。MAX_FILE_SIZE 隱藏域(單位為字節(jié))必須先于文件輸入域,其值為接收文件的最大尺寸。同時,要保證您的文件上傳表單中要有 enctype="multipart/form-data",否則文件上傳將不能工作。


      警告?
      MAX_FILE_SIZE 的值只是對瀏覽器的一個建議,實際上它可以被簡單的繞過。因此不要把對瀏覽器的限制寄希望于該值。實際上,PHP 設(shè)置中的上傳文件最大值,是不會失效的。但是最好還是在表單中加上 MAX_FILE_SIZE,因為它可以避免用戶在花時間等待上傳大文件之后才發(fā)現(xiàn)該文件太大了的麻煩。


      為上傳文件定義的變量會根據(jù) PHP 的版本及設(shè)置的不同而不同。自動全局變量 $_FILES 從 PHP 4.1.0 版本開始被支持。在這之前,從 4.0.0 版本開始,PHP 支持 $HTTP_POST_FILES 數(shù)組。這些數(shù)組將包含所有關(guān)于您上傳的文件的信息,其中,我們推薦您使用 $_FILES。如果 PHP 的設(shè)置選項 register_globals 為 on,則相關(guān)的變量名將也會存在。從 PHP 4.2.0 版本開始,register_globals 的默認值被設(shè)為 off。

      以上范例中 $_FILES 數(shù)組的內(nèi)容如下所示。我們假設(shè)文件上傳字段的名稱如上例所示,為 userfile。名稱可隨意命名。


      $_FILES['userfile']['name']
      客戶端機器文件的原名稱。

      $_FILES['userfile']['type']
      文件的 MIME 類型,需要瀏覽器提供該信息的支持,例如“image/gif”。

      $_FILES['userfile']['size']
      已上傳文件的大小,單位為字節(jié)。

      $_FILES['userfile']['tmp_name']
      文件被上傳后在服務(wù)端儲存的臨時文件名。

      $_FILES['userfile']['error']
      和該文件上傳相關(guān)的錯誤代碼。['error'] 是在 PHP 4.2.0 版本中增加的。


      注: 在 PHP 4.1.0 版本以前該數(shù)組的名稱為 $HTTP_POST_FILES,它并不像 $_FILES 一樣是自動全局變量。PHP 3 不支持 $HTTP_POST_FILES 數(shù)組。

      當 php.ini 中的 register_globals 被設(shè)置為 on 時,您可以使用更多的變量。例如,$userfile_name 等價于 $_FILES['userfile']['name'],$userfile_type 等價于 $_FILES['userfile']['type'] 等。請記住從 PHP 4.2.0 開始,register_globals 的默認值為 off,因此我們建議您不要依賴于改設(shè)置項而使用剛剛提到的那些附加變量。

      文件被上傳后,默認地會被儲存到服務(wù)端的默認臨時目 錄中,除非您將 php.ini 中的 upload_tmp_dir 設(shè)置為了其它的路徑。服務(wù)端的默認臨時目錄可以通過更改 PHP 運行環(huán)境的環(huán)境變量 TMPDIR 來重新設(shè)置,但是在 PHP 腳本內(nèi)部通過運行 putenv() 函數(shù)來設(shè)置是不起作用的。該環(huán)境變量也可以用來確認其它的操作也是在上傳的文件上進行的。 例子 18-2. 使文件上傳生效

      請查閱函數(shù) is_uploaded_file() 和 move_uploaded_file() 以獲取進一步的信息。以下范例處理由表單提供的文件上傳。

      <?php
      // 在 4.1.0 以前的 PHP 中,需要用 $HTTP_POST_FILES 代替 $_FILES。
      // 在 4.0.3 以前的 PHP 中,需要用 copy() 和 is_uploaded_file() 來代替 move_uploaded_file()。

      $uploaddir = '/var/www/uploads/';
      $uploadfile = $uploaddir. $_FILES['userfile']['name'];
      print "<pre>";
      if (move_uploaded_file($_FILES['userfile']['tmp_name'], $uploaddir . $_FILES['userfile']['name'])) {
      print "File is valid, and was successfully uploaded.? Here's some more debugging info:/n";
      print_r($_FILES);
      } else {
      print "Possible file upload attack!? Here's some debugging info:/n";
      print_r($_FILES);
      }
      print "</pre>";
      ?>


      接受上傳文件的 PHP 腳本必須在文件上傳后進行判斷,來決定接下來要對該文件進行那些操作。例如,您可以通過 $_FILES['userfile']['size'] 變量來忽略尺寸太大或太小的文件,也可以通過

    轉(zhuǎn)自:http://hi.baidu.com/%BA%EE%BB%E1%C1%C1boke/blog/item/b92909a01c0e918147106431.html


    來源:http://blog.csdn.net/johe931012/article/details/39780001

    總結(jié)

    以上是生活随笔為你收集整理的上传问题总结(文件大小检测,大文件上传)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。