利用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. TheScript
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`]. ”
” );
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:
“;
foreach ($info as $key => $value){
$str .= “$key = $value
“;
}
$str .= $this->getPath($this->request_uri) . ”
“;
$str .= “PHP_UPLOADED_FILE_NAME=” . $PHP_UPLOADED_FILE_NAME . ”
“;
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:
“;
foreach ($info as $key => $value){
$str .= “$key = $value
“;
}
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的時候,並沒有找到很多,所以可能對於錯誤情況,考慮的也不是很全面,如果有使用過這個方法的歡迎和我討論。
參考資料:
1、PUT Upload
2、RFC 2616
相關文章
- 檔案上傳的幾種方式
- vue前端上傳檔案到阿里雲oss的兩種方式,put檔案流上傳,multipartUpload直接上傳Vue前端阿里
- WebView上傳檔案的深坑與研究WebView
- 利用ftp自動上傳檔案FTP
- vue 檔案上傳方法formDataVueORM
- php檔案上傳之多檔案上傳PHP
- 檔案上傳速度查詢方法
- 幾種windows到linux上傳檔案的方式WindowsLinux
- 【liunx命令】上傳下載檔案的方法
- 修改PHP上傳檔案大小限制的方法PHP
- 檔案上傳之三基於flash的檔案上傳
- .NET Core Web APi大檔案分片上傳研究WebAPI
- Web檔案上傳方法總結大全Web
- 提升檔案上傳效能的 4 種方式,你會嗎?
- 單個檔案上傳和批量檔案上傳
- 阿里雲oss 上傳檔案的兩種方式(本地路徑上傳遠端連結上傳)阿里
- 檔案上傳
- 利用ssh傳輸檔案
- 上傳檔案的陷阱
- SpringMVC 單檔案上傳與多檔案上傳SpringMVC
- 【詳細】關於Android上傳檔案的幾種方式Android
- laravel 使用 axios 通過 put 上傳檔案獲取不到資料的解決辦法LaraveliOS
- 自定義檔案上傳功能實現方法
- 上傳大檔案-斷點續傳的一中方式的記錄斷點
- 大檔案如何傳輸,大檔案的傳輸方式有哪些?
- Java大檔案上傳、分片上傳、多檔案上傳、斷點續傳、上傳檔案minio、分片上傳minio等解決方案Java斷點
- [筆記]laravel的上傳檔案或者圖片的方法筆記Laravel
- 前端大檔案上傳/分片上傳前端
- Flask——檔案上傳Flask
- PHP上傳檔案PHP
- JavaScript 檔案上傳JavaScript
- Git上傳檔案Git
- YII檔案上傳
- 檔案上傳概述
- beego上傳檔案Go
- 上傳檔案流程
- 上傳EXCLE檔案
- PHP 檔案上傳PHP