亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > PHP > 正文

PHP之文件的鎖定 上傳與下載

2020-03-22 18:16:19
字體:
來源:轉載
供稿:網友
  • 小結文件的鎖定機制、上傳和下載

    1.文件鎖定

    現在都在講究什么分布式、并發等,實際上文件的操作也是并發的,在網絡環境下,多個用戶在同一時刻訪問頁面,對同一服務器上的同一文件進行著讀取,如果,這個用戶剛好讀到一半,另一個用戶就寫入了消息,那么前一個用戶讀到的就是錯誤數據,在數據庫里面好像是稱為臟數據,而如果某用戶寫到一半時,另一用戶也對該文件進行寫操作,那么就造成了寫入數據的混亂和錯誤,因此才php有一個鎖機制,類似于數據庫的鎖,當某用戶在對文件操作時就加上某種鎖,使得在同一時間其他用戶不能對該文件進行操作或只能進行有限的操作,來保證在這些情況下的文件數據的正確性。

    主要使用flock函數,原型:bool flock(resource $handle , int $operation [, int &$wouldblock ]),第一個參數是指向文件的句柄變量,第二個是加鎖的方式,分別為

    LOCK_SH:共享鎖(share),在讀取文件時加的鎖,加鎖后就其他用戶不能再對該文件進行寫,但可以讀取該文件內容;

    LOCK_EX:排他鎖(exclude),或者叫獨占鎖,在寫文件時使用,加了該鎖后,只能是當前用戶進行寫操作,其他的用戶不能讀取和寫入;

    LOCK_NB:附加鎖,在文件鎖定短時間大量用戶的訪問操作可能會造成flock在鎖定時堵塞,如果再加上該鎖后可避免該情況(是不是這么一弄就能解決大量讀寫操作的問題,怕不行...);

    LOCK_UN:釋放鎖,對前面的各種鎖進行一次性釋放,解鎖。

    如果容易堵塞,還可使用第三個參數wouldblock,如果把它設置為1,在鎖定后就會阻擋其他進程來進行一些操作,但是windows上不支持,另外附加鎖LOCK_NB,windows也是不支持的。

    另外,關閉句柄變量的fclose操作也可以釋放這些鎖。

    廢話少說,看代碼

    <?php     function readFileData($filename){         if(true == ($handle = fopen($filename, 'r'))){             if(flock($handle, LOCK_SH+LOCK_NB)){  // 加共享鎖和附加鎖,附加鎖防止阻塞                 $str = '';                 while(!feof($handle)){                     $str .= fread($handle, 128);                  }                  flock($handle, LOCK_UN); // 釋放該鎖                      fclose($handle);                      return $str;              }              else{                 echo 'add a share lock failed';                 return '';              }          }          else{              return '';          }       }

    注意使用多重鎖的方式,是LOCK_SH+LOCK_NB,,在排他鎖時也可這么用,它們都是枚舉變量。對于寫操作類似

    <?php    function writeInFile($filename, $data){        if(true == ($handle = fopen($filename, 'a'))){            if(flock($handle, LOCK_EX)){   //加上排他鎖                fwrite($handle, $data);                flock($handle, LOCK_UN);  //釋放鎖                fclose($handle);            }            else{                echo 'add exclusive lock failed';                return;            }       }    }

    實際上這也是解決php來實現多進程/線程讀取文件的方式,php沒有多線程這么一說,但加鎖機制可以來模擬這種方式,實現對文件某些操作的隊列處理,面試時別說你不知道-_-

    2.文件上傳

    文件上傳就是將本地的文件上傳到服務器上,我們在用度場的云、鵝場的云上傳文件時均是如此,當然實際情況肯定比這簡單程序復雜。HTTP協議實現了文件的上傳機制,首先要在本地選擇上傳的文件,上傳到服務器后,服務端又要做一些處理,為此客戶端和服務端均要做一些設置。

    1、客戶端

    文件上傳最基本的方法是通過form表單進行POST傳遞文件,實際上通過PUT方法也可以上傳文件,只不過這種方法不安全,需要配置一些安全驗證機制,這里只寫最常用的方式。form表單的input標簽可以設置成文件上傳按鈕type="file",直接解決了如何選擇文件的問題,接下來需要設置form的兩個屬性:enctype和method

    enctype:設置成multipart/form-data

    method:設置成post

    關于enctype屬性設置可參考W3School的解釋

    第一條是默認的值,在我們使用HTTP協議傳遞一般的表單數據時,實際上默認對數據進行了分塊編碼,比如默認的urlencode方式(空格轉為+,其他非字母字符轉為%加兩個十六進制大寫數);當enctype設置為第二個時,不會進行字符編碼,使用上傳控件(input標簽type設為file時即是)上傳文件,必須設定為這個值;第三個則是值對空格編碼為+,但不對非字母字符進行編碼。

    我們知道GET方法一般用于獲取數據,且傳遞數據大小有限,而且POST方法可以傳遞比GET大得多的數據。

    form的屬性設置完成后,還要傳遞一個值過去,使用隱藏域(<input type="hidden">),它的name屬性設為MAX_FILE_SIZE,之所以要設定這個值,是先大概定一個文件尺寸值,避免在用戶傳一個大文件傳了半天再告訴他:sorry,你的文件太大了-_-它的html' target='_blank'>value屬性值就是文件的size,以字節為單位。當然某些書上說,這個值只是作為參考,可輕易進行欺騙,這里只是象征性的表示,很可惜我這只菜鳥對安全了解甚少,只知道普通注入、XSS等,暫且用著吧。

    那么就可以寫一個簡單得不能再簡單的頁面了,作為客戶端用:

    <form method="post" action="upload.php" enctype="multipart/form-data">    <input type="hidden" name="MAX_FILE_SIZE" value="1000000" />    選擇文件: <input type="file" name="uploadFile" value="upload"/><br/>    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;    <input type="submit" name="submit" value="上傳" /></form>

    2、服務端

    文件上傳到了服務器上還要經過一些處理過程,就像網購派送快遞,到了目的地也還得分個類,確認下目的地對錯吧。到了目的地的后續處理需要php腳本,上面在提交表單時的action屬性就指定了提交的處理腳本。我們知道在php中,$_POST保存的是post傳遞的數據,而上傳文件的相關信息保存在$_FILES里邊,假設服務端腳本是這樣的:

    <?php    echo '_FILES: <pre>';    print_r($_FILES);          echo '_POST: <pre>';    print_r($_POST);

    不管服務端如何處理的,先看看這兩個數組里面有什么:

    看FILES數組的選項就猜得到,這些就是上傳文件的名字、類型、尺寸、錯誤信息等等,還有這個FILES是二維數組。在弄清楚這些選項之前有必要了解幾個php配置選項,打開php.ini文件,找到下面四項(其實看注釋也明白了):

    file_uploads:是否允許通過HTTP傳遞文件,默認是On允許;

    upload_max_filesize:允許傳遞文件的最大大小,以M為單位,這是服務端配置文件設定的選項;

    max_file_uploads:一次請求所允許傳遞的做多文件個數;

    post_max_size:通過POST傳遞數據的最大大小,因為文件傳遞也是post方式,也算post傳遞,需要特別注意的是,它必須要大于upload_max_filesize選項,因為在一次post傳遞過程中不僅會上傳文件,還會傳遞其他數值,比如上面的Z喎?http://www.it165.net/pro/pkqt/" target="_blank" class="keylink">QT1NUyv3X6dbQtcTK/b7do6yx2NDrv7zCx7W9o6yxyMjndXBsb2FkX21heF9maWxlc2l6ZcnozqoxNTBNo6zV4rj2vs2/ydLUyejOqjIwME07PC9wPgo8cD4mbmJzcDsgJm5ic3A7ICZuYnNwOyB1cGxvYWRfdG1wX2RpcqO6yc+0q87EvP61xMHZyrHEv8K8o6zF5NbDzsS8/sDvw+bErMjPzqq/1aOsu+HKudPDstnX98+1zbPErMjPtcTB2cqxxL/CvKOs0vK0y8nPw+a1xEZJTEVTyv3X6dbQtcR0bXBfbmFtZdbQtcTR28rstcTCt762vs2/ydLUveLKzcHLo6zKudPDd2luZG93c8SsyM+1xLTmt8XB2cqxzsS8/rXExL/CvKOstvjH0rf+zvHG98SsyM+21M7EvP7D+9f3wcvQ3rjEoaM8L3A+CjxwPiZuYnNwOyAmbmJzcDsgJm5ic3A7IMTHw7RGSUxFU8r91+nW0LXEdXBsb2FkRmlsZcTEwO/AtLXEo6zOqsqyw7TSqtPDy/zX9rz8w/ujrNXiysfS8s6q1NrJz7Srv9i8/rXEbmFtZcr00NS+zcrHdXBsb2FkRmlsZaOsy/yx6rzHtcTKx9XiuPa/2Lz+tcTJz7SrzsS8/tDFz6KjrNLytMvO0sPHv8nS1LfFtuC49snPtKu/2Lz+o6zJ6NbDsrvNrLXEbmFtZaOstbHIu8no1sPSu9H5tcRuYW1l0rK/ydLUo6zN6sirv8nS1LDRy/zDx8irt8XU2tK7uPbK/dfpwO+x36OsyOcmbHQ7aW5wdXQgdHlwZT0="file" name="upload[]">。

    現在回過頭看FILE數組的鍵名代表的信息,type是MIME類型,以/分隔,前面是主要類型,后面是具體文件類型,error肯定表示錯誤,有這么幾種情況,0:沒有錯誤,上傳成功; 1:文件超過了PHP配置指令中的upload_max_filesize規定的大小; 2:文件超過HTML表單中MAX_FILE_SIZE規定的大小,3:文件只有部分上傳; 4:沒有文件上傳。現在關于FILES數組的問題全部明白了。

    問題是,是不是上傳成功就不做任何處理了,當然不是,總不能全堆在一個臨時目錄里面,上傳多了必然就要將文件移到別的地方,而php提供了專門而安全的函數。is_uploaded_file函數,判斷是否通過HTTP POST上傳,可以確保惡意的用戶去欺騙腳本而管理這些文件,例如/etc/pass(又是linux...),至于具體怎樣,我還不清楚。move_uploaded_file函數,將上傳文件移動到新位置,同時還可判斷文件是否為合法上傳,即通過HTTP POST方式,他們運行成功均返回布爾類型true。

    扯了半天,上傳文件大概要經過這樣幾個步驟:

    1、客戶端寫好上傳控件腳本,并傳遞一個限制文件大小的隱藏值;

    2、服務端首先判斷FILES數組error值,看是否出錯;

    3、判斷是否為允許上傳的類型(可以不判斷);

    4、判斷在服務端腳本里邊是否超過指定的文件大?。?/p>

    5、上傳到臨時位置,生成新文件名(防止把已有同名文件覆蓋掉),檢查并移動到新目錄下。

    客戶端準備工作剛已做,看服務端處理代碼:

    <?php    $typeWhiteList = array('txt', 'doc', 'php', 'zip', 'exe');   // 類型白名單,過濾不允許上傳的文件類型    $max_size = 1000000;  // 大小限制 為1M    $upload_path = 'D:/WAMP/upload/';    // 指定移至的目錄         // 1、判斷是否成功上傳到服務器     $error = $_FILES['uploadFile']['error'];    if($error > 0){         switch($error){             case 1: exit('超過php配置的最大文件上傳限制');             case 2: exit('超過HTML表單的最大文件上傳限制');             case 3: exit('文件只有部分被上傳');             case 4: exit('沒有上傳任何文件');             default: exit('未知類型錯誤');         }    }         // 2、判斷是否為允許上傳的類型    $extension = pathinfo($_FILES['uploadFile']['name'], PATHINFO_EXTENSION); // 獲取擴展名    if(!in_array($extension, $typeWhiteList)){        if($extension == '')           exit('不允許上傳空類型文件');         else            exit('不允許上傳'.$extension.'類型文件');    }          // 3、判斷是否為允許大小    if($_FILES['uploadFile']['size'] > $max_size){        exit('超過了允許上傳到的'.$max_size.'字節');    }         // 4、已到指定位置    $filename = date('Ymd').rand(1000, 9999);   // 生成一個新文件名,防止覆蓋    if(is_uploaded_file($_FILES['uploadFile']['tmp_name'])){   // 判斷是否通過HTTP POST上傳        if(!move_uploaded_file($_FILES['uploadFile']['tmp_name'], $upload_path.$filename.'.'.$extension)){            exit('無法移動到指定位置');         }         else{            echo '文件上傳成功<br/>';            echo '文件名: '.$upload_path.$filename.'.'.$extension.'<br>';         }    }     else{         exit('文件未通過合法途徑上傳');     }

    本想迅速體驗一把,結果報了個Warning,說時間設置依賴系統...bug總是這么不期而遇,設置好時間后,再試,perfect!

    3.文件下載

    文件下載就比較簡單了,簡單的文件下載只需要用一個HTML鏈接就夠了,使用<a>標簽,href屬性指定資源位置,一點就可。但這種方式只能處理瀏覽器默認無法識別的MIME類型,比如rar、7z等壓縮的數據。

    <html>    <head>             <title>donwload file</title>             <meta http-equiv="Content-Type" content="text/html"; charset="utf-8" />    </head>    <body>             <a href="resource/header.txt">header.txt</a><br/>             <a href="resource/php.zip">php.zip</a><br/>             <a href="resource/pic.ico">pic.ico</a>               </body></html>

    對于這些瀏覽器不認識的類型文件,點鏈接,它直接彈框讓你下載,有的瀏覽器甚至直接就下了,那么對于文本txt、jpg等瀏覽器默認識別的類型的文件,一點擊則會直接展現在頁面上,比如上面header.txt、pic.ico。如何不展示在頁面上而去下載它們呢,使用header函數。

    header函數會通過發送頭信息告知,請把該文件當成一個附件,這樣點擊的時候,就也會下載了。

    <?php    $filename = 'header.txt';    header('Content-Type: text/plain');   // 類型為普通文本    header('Content-Disposition:attachment; filename="$filename"');  // Content-Disposition:attachment,告訴它這是附件    header('Content-Length:'.filesize($filename));   // 告知文件大小    readfile($filename);  // 讀取文件直接輸出,便于下載

    實際上不要最后一行也可。這樣即便是文本文件,它也會彈出保存框讓你保存,連下載框都沒有!

    涉及到頭信息的東西,要補補HTTP協議的知識,最近事多人累,咽喉腫痛,就醬紫。

    PHP編程

    鄭重聲明:本文版權歸原作者所有,轉載文章僅為傳播更多信息之目的,如作者信息標記有誤,請第一時間聯系我們修改或刪除,多謝。

  • 發表評論 共有條評論
    用戶名: 密碼:
    驗證碼: 匿名發表
    亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
    欧美日韩激情美女| 欧美视频裸体精品| 在线成人免费网站| 国产小视频国产精品| 日韩h在线观看| 国产91精品久久久久| 久久精品国产亚洲一区二区| 97视频免费在线看| 九九九热精品免费视频观看网站| 成人激情视频小说免费下载| 国产成人欧美在线观看| 国产一区二区三区在线看| 亚洲午夜未删减在线观看| 亚洲第一色中文字幕| 精品亚洲一区二区三区在线观看| 91在线高清免费观看| 欧美成年人在线观看| 国产精品黄页免费高清在线观看| 亚洲成年人在线播放| 91av视频在线免费观看| 久久久久久久久久久成人| 中文字幕在线亚洲| 国产欧美精品日韩精品| 日产精品久久久一区二区福利| 国产中文字幕91| 亚洲一区二区三区香蕉| 欧美日韩亚洲网| 91免费精品国偷自产在线| 亚洲国产高清高潮精品美女| 欧美电影第一页| 欧美人与性动交a欧美精品| 亚洲精品之草原avav久久| 91在线视频九色| 亚洲女人被黑人巨大进入| 一区二区在线视频播放| 国产精品欧美日韩久久| 国产高清视频一区三区| 成人xxxxx| 日韩色av导航| 奇门遁甲1982国语版免费观看高清| 欧美日韩中文在线观看| 国产精品亚洲片夜色在线| 久久成人精品视频| 久久久久久91| 国产精品尤物福利片在线观看| 久久精品国产成人精品| 精品国模在线视频| 欧美日韩国产中文精品字幕自在自线| 国产精品久久久久久久久久三级| 成人久久久久爱| 国产精品激情自拍| 热门国产精品亚洲第一区在线| 国产精品一区二区久久国产| 高清欧美性猛交xxxx黑人猛交| 成人免费在线视频网址| 亚洲a一级视频| 国产精品第1页| 久热精品视频在线| 久久人人爽人人爽人人片av高清| 国产精品亚洲自拍| 久久精品久久精品亚洲人| 97视频免费观看| 久久久亚洲欧洲日产国码aⅴ| 亚洲欧美精品伊人久久| 国产精品免费一区豆花| 国产91色在线免费| 亚洲第一福利视频| 久久久久久国产精品久久| 亚洲美女精品成人在线视频| 国产欧美精品在线播放| 免费成人高清视频| 一区二区欧美在线| 久久免费少妇高潮久久精品99| 国产美女精彩久久| 亚洲精品99久久久久中文字幕| 欧美高清videos高潮hd| 国产精品免费一区| 精品国产依人香蕉在线精品| 欧美一级高清免费播放| 在线视频日韩精品| 一区三区二区视频| 国产精品美女网站| 国产精品无av码在线观看| 国产精品三级在线| 国产日韩换脸av一区在线观看| 久久精品福利视频| 亚洲精品一区二区三区婷婷月| 亚洲有声小说3d| 国产99久久精品一区二区永久免费| 亚洲高清在线观看| 亚洲视频电影图片偷拍一区| 国产精品久久久久久亚洲调教| 日韩在线中文字幕| 国产99久久精品一区二区永久免费| 国产成人久久久精品一区| 久久乐国产精品| 久久激情视频免费观看| 成人黄色网免费| 在线播放精品一区二区三区| 日韩精品高清在线| 亚洲午夜久久久久久久| 欧美亚洲视频在线观看| 日韩在线播放av| 国产成人综合久久| yellow中文字幕久久| 欧美成人中文字幕| 国产日韩欧美在线视频观看| 欧美成人在线免费| 国产精品一区久久久| 久久久精品网站| 亚洲国产精品va在线| 美乳少妇欧美精品| 国产成人涩涩涩视频在线观看| 国产成人jvid在线播放| 97视频网站入口| 日韩久久精品成人| 国产一区二区色| 欧美日韩中文字幕在线视频| 国产成人久久久精品一区| 97成人精品区在线播放| 成人免费观看49www在线观看| 久久99久久99精品中文字幕| 精品人伦一区二区三区蜜桃免费| 伊是香蕉大人久久| 91天堂在线视频| 日韩在线观看av| 国产精品偷伦免费视频观看的| 国产精品狠色婷| 亚洲国产精品一区二区三区| 久久久国产精品亚洲一区| 久久久久久久久网站| 日韩av在线免费| 久久夜色精品亚洲噜噜国产mv| 51色欧美片视频在线观看| 91美女片黄在线观看游戏| 久久久免费电影| 日韩av在线影院| 亚洲人成在线观看| 欧美成人精品在线| 97香蕉超级碰碰久久免费软件| 日韩美女av在线| 久久中文字幕视频| 欧美日韩国产限制| 国产成人午夜视频网址| 亚洲天堂av在线播放| 日韩高清av一区二区三区| 欧美激情精品久久久| 欧美精品生活片| 日韩欧美国产成人| 国产精品自拍小视频| 色悠久久久久综合先锋影音下载| 国产亚洲精品久久久久久牛牛| 成人黄色在线观看| 国产视频福利一区| 欧美大片免费观看在线观看网站推荐| 亚洲精品欧美一区二区三区| 日韩欧美黄色动漫| 亲爱的老师9免费观看全集电视剧| 国产视频久久久久久久| 欧美理论电影在线播放| 亚洲字幕在线观看| 日韩高清电影免费观看完整| 亚洲变态欧美另类捆绑| 亚洲欧洲一区二区三区在线观看|