php put怎么接收文件,php,restful_PHP PUT方式传文件的话,如何获取文件内容呢 ?,php,restful,http - phpStudy...

PHP PUT方式传文件的话,如何获取文件内容呢 ?

最近因为在做前后端分离,后端PHP所有Api都使用RESTFul风格。

但是在使用PUT上传文件的时候,发现$_FILES没有文件信息(可能没有上传临时文件,待验证),使用POST是可以的,并且PUT从标准输入流获取过来的数据,读取出来是下面这种格式(上面我猜测没有上传临时文件,是因为看标准输入流里面存着文件信息),需要另外解析。

#获取到的输入流内容

------WebKitFormBoundarybzEhWNCqbo9qKZBX

Content-Disposition: form-data; name="upload"; filename="一些不错的职位.md"

Content-Type: text/markdown

xxxx

xxxx

xxxx

------WebKitFormBoundarybzEhWNCqbo9qKZBX--

目前我的思路是两个:

如果上传临时文件(这个正在测试...): 如果上传了,可以读临时文件。

如果不上传临时文件:尝试解析这串form-data传过来的参数,但我不知道这种格式php有没有对应方法进行解析。

顺带吐槽下,RESTFul用起来经常会有问题:

在跨域的时候,普通的form表单(GET, POST)没问题,但是使用PUT,DELETE的话,需要设置跨域头。

PS:不明白,为什么需要?

MDN HTTP Method文档竟然没有PUT,DELETE的详细介绍...

PHP获取PUT,DELETE需要到file_get_contents('php://input');获取参数信息,没有类似$_PUT,$_DELETE的全局变量。

============= [ 22:01 ] ===================

到stackoverflow逛了下,发现不少碰到相同问题的,暂时没看到比较好的解决方案。

补充下,这篇文章jquery ajax put file, php save file,博主和我碰到了一样的问题,不过他是通过用正则来解析处理数据的。

我在想,有没有比较好的方案,能够模仿PHP处理POST请求一样,把form-data串,解析出来,普通参数,存到$_PUT($_POST), 文件传到临时目录,然后返回文件信息到$_FILES.

============ [ 10-10 10:16 ] ===================

这片博文如何使用multipart/form-data格式上传文件,有讲到form-data的格式。

目前先自己简单写一个解析form-data的composer组件。

============ [ 10-10 16:24 ] ====================

简单写了个解析form-data的类

默认直接获取文件内容(除文件外其他参数,默认使用json串传输)。

如果配置了$option['saveFile']=true,保存临时文件,返回临时文件路径。

class FormDataParser

{

private static $partSize = 4096; //每次最大获取字节

/**

* 负责解析FormData

*/

public static function parser($options = [])

{

//$options['saveFile'] = true; 测试能否正常保存临时文件

$formData = fopen("php://input", "r");

$retData = [];

$boundary = rtrim(fgets($formData), "\r\n"); //第一行是boundary

$info = []; //info段的信息

$data = ''; //拼接的数据

$infoPart = true; //是否是info段

while ($line = fgets($formData, self::$partSize)) {

if ($boundary . "\r\n" == $line || $boundary . "--\r\n" == $line) {

//如果是分割

$infoPart = true;

if ($info['type'] == 'json') {

$data = json_decode($data, true);

$retData[$info['name']] = $data;

} else if($info['type'] == 'file') {

if(isset($info['tmp_file'])) {

fclose($info['file_handle']);

$retData[$info['name']] = [

'org_name' => $info['org_name'],

'tmp_file' => $info['tmp_file']

];

} else {

$retData[$info['name']] = $data;

}

}

$data = '';

} else if ("\r\n" == $line) {

if ($infoPart) {

//解析info

$info = self::parserInfo($data, $options);

if (isset($info['tmp_file'])) {

$info['file_handle'] = fopen($info['tmp_file'], 'w');

}

$data = '';

$infoPart = false;

}

} else {

if($infoPart == false && isset($info['tmp_file'])) {

fwrite($info['file_handle'], $line);

} else {

$data .= $line;

}

}

}

fclose($formData);

print_r($retData);

}

private static function parserInfo($data, $options)

{

//获取参数名称, type

$infoPattern = '/name="(.+?)"(; )?(filename="(.+?)")?/'; //todo: 待优化

preg_match($infoPattern, $data, $matches);

$info['name'] = $matches[1];

$info['type'] = 'json';

//如果是文件

if (count($matches) > 4) {

$info['type'] = 'file';

$info['org_name'] = $matches[4];

//如果设置保存文件, 保存到临时文件

if (isset($options['saveFile']) && $options['saveFile']) {

$tmpFile = tempnam(sys_get_temp_dir(), 'FD');

$info['tmp_file'] = $tmpFile;

}

}

return $info;

}

}

相关阅读:

既然view的绘制是异步的,为什么总是比activity慢?

能否为go的基本类型如int实现某个接口?

__name__= __main__怎么解释 怎么用 另外两个py文件之间的互动关联

python嵌套SQL语句,字段 in () 格式错误?

url-loader如何将打包的图片资源 放入build/imgs下

关于判断手机QQ内置浏览器的问题!

关于手机竖拍照片旋转问题

ant design的time picker生成为何是独立于组件外?

vue父组件动画时子组件怎样处理的

如何避免 webstorm 中 Vue 项目通过 npm 面板运行开发服务器时的 DEBUG_FD 已废弃提示信息

遍历 body 的子元素

swiper插件

annimate只能执行一次

Tomcat:绿盟扫出来的“检测到目标URL存在http host头攻击漏洞”如何解决

外部函数接收三个参数,里面的函数只需要一个参数或者需要四个参数的时候,里面的函数的参数怎么被赋值的?

ORA-12547:TNS:丢失连接

Vagrant如何打包分布式环境

mybatis 子查询多个条件 ?

Rust: 测试时使用条件编译,如何在默认时开启某个测试而在传入 feature 后关闭?

vue-cli 如何结合ueditor,run dev的时候出现问题

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值