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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > php >内容正文

php

php input file ajax,jquery ajax put file, php save file

發(fā)布時(shí)間:2025/3/12 php 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 php input file ajax,jquery ajax put file, php save file 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

在項(xiàng)目中第一次遇到這個(gè)問題,當(dāng)我在更新用戶頭像的時(shí)候,選擇使用put上傳頭像,然而服務(wù)端并不能通過$_FILES像我們以前一樣得到想要的結(jié)果。這是一個(gè)相當(dāng)復(fù)雜的問題,我們這篇文章就來試圖解決這個(gè)問題。

restful post vs. put

如果我們希望嚴(yán)格保持restful風(fēng)格,那么一定要遵循post=add, put=update的風(fēng)格,在stackoverfollow上已經(jīng)有很多這樣的討論,所以,就不這里再討論。但是restful不是規(guī)范,我們并不一定非得嚴(yán)格按照這個(gè)規(guī)定去做,在適當(dāng)?shù)臅r(shí)候,其實(shí)我們確實(shí)可以選擇使用post代替put.

為什么仍然堅(jiān)持put

在PHP接受數(shù)據(jù)傳遞時(shí),只有$_GET, $_POST,而$_PUT和$_DELETE是沒有的,當(dāng)然,由于delete操作往往把要?jiǎng)h除的資源直接在url中加以確定。所以,現(xiàn)在其實(shí)最麻煩的,是put操作。

我們有足夠的理由使用put,因?yàn)槲覀冊(cè)诮邮躳ut信息時(shí),采用的是php://input的形式,這也就是說,通過

file_get_contents('php://input')

可以獲取傳遞內(nèi)容的原始信息,以及二進(jìn)制流,這使得傳輸和接受都是非常高效率的。我們甚至可以直接通過put傳遞文件的二進(jìn)制流,在服務(wù)端保存這個(gè)二進(jìn)制信息,就得到了原始的文件。這個(gè)過程不會(huì)在服務(wù)器上產(chǎn)生臨時(shí)文件,不會(huì)消耗更多的內(nèi)存。

如何獲取put信息

但是,隨之而來的是,解析put信息成為讓人非常煩惱的事,我們通過網(wǎng)上(官網(wǎng))的一些示例代碼,發(fā)現(xiàn)也只能解決部分問題,比如當(dāng)我們通過發(fā)送put信息到服務(wù)端更新文章信息時(shí),由于文章信息不包含復(fù)雜信息,服務(wù)端通過官方示例就可以得到對(duì)應(yīng)的信息,而這樣的到的信息,和$_POST沒有什么不同。

然而,如果發(fā)送的信息中如果含有文件,則情況將會(huì)大不一樣。

在$_POST文件時(shí),要求表單含有enctype='multipart/form-data'屬性,而以往我們長(zhǎng)長(zhǎng)不去思考它的作用,現(xiàn)在我們才知道,這其實(shí)時(shí)一中表單請(qǐng)求的加密形式,當(dāng)表單含有該屬性,提交的內(nèi)容中含有文件時(shí),服務(wù)器將會(huì)按照該規(guī)則進(jìn)行解碼,而解碼的到的文件信息,將會(huì)以$_FILES返回。所以,當(dāng)我們?cè)谑褂胮ost進(jìn)行文件上傳的時(shí)候,實(shí)際上,文件不能到$_POST中去取,而是到$_FILES中。

put傳輸?shù)氖嵌M(jìn)制信息流,因此不需要服務(wù)端解碼,自然也就不存在$_FILES的具體信息(為空)。這下我們就懵了,那上傳的文件到哪里去了(我們知道$_FILES中的文件保存在服務(wù)器臨時(shí)目錄中,需要我們通過move_uploaded_file函數(shù)進(jìn)行轉(zhuǎn)移)?

實(shí)際上,put的文件哪里都沒有去,還在php://input原始信息流中,我們要做的,是對(duì)php://input進(jìn)行解碼,得到我們想要的文件信息。

我們來看put得到的結(jié)果:

echo file_get_contents('php://input');

exit;

一般而言,我們可以得到兩種結(jié)果,

一種:不包含文件的

這時(shí)我們長(zhǎng)長(zhǎng)得到的,是一串字符串,例如name=Jerry&age=18,我們?cè)诖蟛糠諴HP中如此去解析:

parse_str(file_get_contents('php://input'), $_PUT);

另一種:包含文件的

這種情況是比較復(fù)雜的,我們會(huì)發(fā)現(xiàn),php://input是一個(gè)復(fù)雜的體系。

------------------------------b2449e94a11cContent-Disposition:form-data;name="user_id"3------------------------------b2449e94a11cContent-Disposition:form-data;name="post_id"

5------------------------------b2449e94a11cContent-Disposition:form-data;name="image";filename="/tmp/current_file"Content-Type:application/octet-stream�����JFIF���������...a bunch of binary data

可以看到上面的結(jié)果中,用------------------------------b2449e94a11c把整個(gè)內(nèi)容分為了幾個(gè)部分,其中第三個(gè)部分是一個(gè)文件。

經(jīng)過觀察,我們最終決定,用正則分析它,并得到我們想要的結(jié)果,最后我參考一些網(wǎng)上的朋友給出的代碼,總結(jié)了下面這個(gè)函數(shù):

/** * Parse raw HTTP request data

*

* Pass in $a_data as an array. This is done by reference to avoid copying

* the data around too much.

*

* Any files found in the request will be added by their field name to the

* $data['files'] array. * * https://www.tangshuang.net/?p=2294

*

* @param array Empty array to fill with data

* @return array Associative array of request data

*/

function parse_http_input_raw() {

$a_data = array();

// read incoming data

$input = file_get_contents('php://input');

// grab multipart boundary from content type header

preg_match('/boundary=(.*)$/', $_SERVER['CONTENT_TYPE'], $matches);

// content type is probably regular form-encoded

if (!count($matches)) {

// we expect regular puts to containt a query string containing data

parse_str(urldecode($input), $a_data);

return $a_data;

}

$boundary = $matches[1];

// split content by boundary and get rid of last -- element

$a_blocks = preg_split("/-+$boundary/", $input);

array_pop($a_blocks);

// loop data blocks

foreach ($a_blocks as $id => $block) {

if (empty($block)) continue;

// you'll have to var_dump $block to understand this and maybe replace or \r with a visibile char

// parse uploaded files

if (strpos($block, 'filename=') !== FALSE) {

// match "name", then everything after "stream" (optional) except for prepending newlines

preg_match("/name=\"([^\"]*)\".*filename=\"([^\"].*?)\".*Content-Type:\s+(.*?)[|\r|\r]+([^\r].*)?$/s", $block, $matches);

$a_data['files'][$matches[1]] = array('name' => $matches[1],'filename' => $matches[2],'type' => $matches[3],'blob' => $matches[4]);

}

// parse all other fields

else {

// match "name" and optional value in between newline sequences

preg_match('/name=\"([^\"]*)\"[|\r]+([^\r].*)?\r$/s', $block, $matches);

print_r($matches);

$a_data[$matches[1]] = $matches[2];

}

}

return $a_data;

}

所有的文件,被放在一個(gè)字段中提供使用:

$_PUT = parse_http_input_raw();

注意,文件的二進(jìn)制流還在$_PUT中呢。我們需要通過遍歷$_PUT['files']保存文件。

jquery ajax如何去發(fā)起put請(qǐng)求和上傳

這個(gè)是最簡(jiǎn)單的了,可以看我之前寫過的一些文章,非常詳細(xì),這里僅給出核心代碼:

$.ajax({

url: url,

type: 'PUT',

data: data,

success: function(result) {}

});

僅此而已。但是,當(dāng)我們需要上傳文件或圖片的時(shí)候,就相對(duì)復(fù)雜一些,因?yàn)闊o(wú)論是POST或PUT,ajax都不會(huì)主動(dòng)把表單中的文件流上傳,而是只提交其他類型的數(shù)據(jù)。

我們需要借助FormData()來實(shí)現(xiàn)文件的ajax上傳:

$('#form').on('submit',function(e) {

e.preventDefault();

var $form = $(this), $files = $form.find('input[type=file][name]'), data = new FormData();

$files.each(function() {if ('files' in this && this.files.length > 0) {data.append(this.name, this.files[0]);}});

// 省略了把非文件數(shù)據(jù)加入到data中

$.ajax({

url: 'your url',

type: 'PUT',

data: data,

contentType: false,

processData: false,

success: function(result) {}

});

});

可以看到,這個(gè)過程也很簡(jiǎn)單,并沒有想象到那么復(fù)雜。通過new FormData()產(chǎn)生的對(duì)象,通過遍歷form中的input或其他數(shù)據(jù)對(duì)象,將結(jié)果逐個(gè)加入到data中。new FormData()有一個(gè)append方法,可以實(shí)現(xiàn)append(key,value),從而將你需要的數(shù)據(jù)加入到data中,ajax提交到時(shí)候,data則是全部的有效數(shù)據(jù)(包括文件的二進(jìn)制流)。

(完)

2016-03-26

7204

總結(jié)

以上是生活随笔為你收集整理的php input file ajax,jquery ajax put file, php save file的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

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