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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

利用PUT方式上传文件的方法研究

發布時間:2023/12/19 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 利用PUT方式上传文件的方法研究 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

雖然沒有POST方法使用廣泛,但是PUT方法卻是向服務器上傳文件最有效率的方法。POST上傳文件時,我們通常需要將所有的信息組合成 multipart 傳送過去,然后服務器再解碼這些信息,解碼過程則必不可少的會消耗內存和CPU資源,這種現象在上傳大文件時尤其明顯。而PUT方法則允許你通過與服務器建立的socket鏈接傳遞文件的內容,而不附帶其他的信息。

最近一個項目上需要利用這種方式來進行文件的上傳,下面介紹一下在 Apache + PHP 的環境下如何進行PUT方式的文件上傳。

Apache 有一個模塊 mod_actions,先看看官方的說明:

This module has two directives. The?Action?directive lets you run CGI scripts whenever a file of a certain?MIME content type?is requested. The?Script?directive lets you run CGI scripts whenever a particular method is used in a request. This makes it much easier to execute scripts that process files.

也就是說,這個模塊可以指定對于特定 MIME 類型的文件處理,或者對于特定腳本的請求進行指定的處理。我用到的就是 Script 這個選項。

在Apache 配置文件的 Directory 中指定

Script PUT /receive.php

這個含義就是,對于所有對服務器的PUT請求,都交給根目錄下的 receive.php 去處理,當然我們也可以選擇 perl 或者其他的CGI腳本來進行處理。

接下來就是這個 receive.php 腳本的編寫了,他的主要任務就是將請求的文件寫到指定的位置

<?php
/**
* Process The PUT File, receive and move a file to corresponsed location
* Created by shiqiang<cocowool@gmail.com> at 2010-05-24
*
**/

class Receive {
??? var $default_log_file = "logs/error.log";
??? var $default_server_info = "logs/server.log";
??? var $default_header_info = "logs/header.log";
??? var $default_prefix = "/data1/vhosts";??? //Default project location prefix;
??? var $default_module = "test.cn";
??? var $max_filesize = 2048000;
??? var $request_uri;

??? function Receive(){
??????? $this->request_uri = $_SERVER['REQUEST_URI'];
??? }
??? function saveFile(){
??????? //receive data and save
??????? $putdata = fopen("php://input", "r");

??????? $path = $this->getPath($this->request_uri);
??????? $fp = fopen($path, 'w');
??????? while($data = fread($putdata, 1024) ){
??????????? fwrite($fp, $data);
??????? }

??????? fclose($fp);
??????? fclose($putdata);

??????? //Log The filesize check and limit check
??????? if( filesize($path) != $_SERVER['CONTENT_LENGTH'] ){
??????????? $this->errorLog( "[warn] " . date("Y-m-d H:i:s")? . " The file's ($path) size dosen't match Server Filesize = " . filesize($path) . "; Put Filesize = " . $_SERVER['CONTENT_LENGTH']. "\r\n" );
??????????? header('HTTP/1.1 526 Receive Data Error');
??????? }

??????? if( filesize($path) > $this->max_filesize ){
??????????? $this->errorLog( "[warn] " . date("Y-m-d H:i:s")? . " The file's ($path) size exceed the system limit");
??????? }
??? }

??? //Log Error Info
??? function errorLog( $info ){
??????? $f = fopen($this->default_log_file, 'a+');
??????? fwrite($f, $info);
??????? flcose($f);
??? }

??? function serverLog(){
??????? $f = fopen($this->default_server_info, 'w');
??????? $info = $_SERVER;
??????? $str = "The Last Request Server Info:\r\n";
??????? foreach ($info as $key => $value){
??????????? $str .= "$key = $value\r\n";
??????? }
??????? $str .= $this->getPath($this->request_uri) . "\r\n";
??????? $str .= "PHP_UPLOADED_FILE_NAME=" . $PHP_UPLOADED_FILE_NAME . "\r\n";
??????? fwrite($f , $str);
??????? fclose($f);
??? }

??? //Log the Request Header info
??? function headerLog(){
??????? $f = fopen($this->default_header_info, 'w');
??????? $info = get_headers();
??????? $str = "The Last Request header Info:\r\n";
??????? foreach ($info as $key => $value){
??????????? $str .= "$key = $value\r\n";
??????? }
??????? fwrite($f , $str);
??????? fclose($f);
??? }

??? //get the path where the file should be
??? function getPath($uri){
??????? $module = $this->defalt_module;??? //Default storage module

??????? $referer = $this->request_uri;
??????? preg_match('/(?<=\/)(.*?)(?=\/)/s', $referer, $match);

??????? if( !empty($match) && !empty($match[0]) ){
??????????? $module = $match[0];
??????? }

??????? $path = $this->default_prefix;
??????? $path .= '/' . $module . '/htdocs';
??????? $fullpath = substr($uri, strlen($match[0]) + 1, strlen($uri) );

??????? $arr = explode('/', ltrim($fullpath, '/'));
??????? foreach($arr as $v){
??????????? if( !strstr($v, '.') ){
??????????????? $path .= '/' . $v;
??????????????? //exec("echo $path >> dir.txt");
??????????????? if( !is_dir($path) ){
??????????????????? //For php > 5.0
??????????????????? //mkdir($path, "0766", true);
??????????????????? mkdir($path, 0766);
??????????????? }
??????????? }else{
??????????????? $path .= '/' . $v;
??????????? }
??????? }

??????? return $path;
??? }

}

$instance = new Receive();
$instance->serverLog();
//$instance->headerLog();
$instance->saveFile();

?>

這個腳本,使用PHP手冊中的接收PUT方式的方法,詳細的使用,GOOGLE的時候,并沒有找到很多,所以可能對于錯誤情況,考慮的也不是很全面,如果有使用過這個方法的歡迎和我討論。

Technorati 標簽: PHP,PUT,Script

參考資料:
1、PUT Upload
2、RFC 2616

總結

以上是生活随笔為你收集整理的利用PUT方式上传文件的方法研究的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。