在所有事情发生之前,我知道我的问题已经发布了数千次,但由于我无法确定我的问题,因此没有人关注我。
所以,我正在构建一个PHP rest api来从客户端获取put请求(angular),这最后可以更新表单内的文件以及一些文本输入,所有这些都是作为{{3发送的在这段代码中:
var fileFormData = new FormData();
$http({
method: 'PUT',
url: host + '/produit/' + $scope.product.id,
data: fileFormData,
transformRequest: angular.identity,
headers: {
'Content-Type': undefined
}
}).then(function successCallback(response) {}, function errorCallback(response) {});
在服务器端,我必须得到响应类型,然后在form-data
的帮助下解析数据,这是完整的代码$method = $_SERVER['REQUEST_METHOD'];
if ($method=="PUT"){
global $_PUT;
/* PUT data comes in on the stdin stream */
$putdata = fopen("php://input", "r");
/* Open a file for writing */
// $fp = fopen("myputfile.ext", "w");
$raw_data = '';
/* Read the data 1 KB at a time
and write to the file */
while ($chunk = fread($putdata, 1024))
$raw_data .= $chunk;
/* Close the streams */
fclose($putdata);
// Fetch content and determine boundary
$boundary = substr($raw_data, 0, strpos($raw_data, "\r\n"));
if(empty($boundary)){
parse_str($raw_data,$data);
$GLOBALS[ '_PUT' ] = $data;
return;
}
// Fetch each part
$parts = array_slice(explode($boundary, $raw_data), 1);
$data = array();
foreach ($parts as $part) {
// If this is the last part, break
if ($part == "--\r\n") break;
// Separate content from headers
$part = ltrim($part, "\r\n");
list($raw_headers, $body) = explode("\r\n\r\n", $part, 2);
// Parse the headers list
$raw_headers = explode("\r\n", $raw_headers);
$headers = array();
foreach ($raw_headers as $header) {
list($name, $value) = explode(':', $header);
$headers[strtolower($name)] = ltrim($value, ' ');
}
// Parse the Content-Disposition to get the field name, etc.
if (isset($headers['content-disposition'])) {
$filename = null;
$tmp_name = null;
preg_match(
'/^(.+); *name="([^"]+)"(; *filename="([^"]+)")?/',
$headers['content-disposition'],
$matches
);
list(, $type, $name) = $matches;
//Parse File
if( isset($matches[4]) )
{
//if labeled the same as previous, skip
if( isset( $_FILES[ $matches[ 2 ] ] ) )
{
continue;
}
//get filename
$filename = $matches[4];
//get tmp name
$filename_parts = pathinfo( $filename );
$tmp_name = tempnam( ini_get('upload_tmp_dir'), $filename_parts['filename']);
//populate $_FILES with information, size may be off in multibyte situation
$_FILES[ $matches[ 2 ] ] = array(
'error'=>0,
'name'=>$filename,
'tmp_name'=>$tmp_name,
'size'=>strlen( $body ),
'type'=>$value
);
//place in temporary directory
file_put_contents($tmp_name, $body);
}
//Parse Field
else
{
$data[$name] = substr($body, 0, strlen($body) - 2);
}
}
}
$GLOBALS[ '_PUT' ] = $data;
$input= array_merge($_PUT, $_FILES);
}
然后我必须执行查询并从temp文件夹
移动文件$sql = "update `$table` set $set where id=$key"; //works
if(isset($name)){ //to check if file exist
chmod($tmpname,0666); //since that's the answer for most of question that are similar to mine
echo substr(sprintf('%o', fileperms($tmpname)), -4); //returns 0666
echo $tmpname." ".$name; //works too
if(move_uploaded_file($tmpname, "/home/****/****/uploads/produits/".$name))
echo "moved";
else
echo "not moved"; // and I always get this
你能解释一下我的错吗?
PS:
我检查了/tmp
文件夹,我上传的文件仍然存在。
日志很干净,我在代码顶部使用了这个
ini_set('display_errors', true);
error_reporting(E_ALL);
更新:
我用它来从$input
var
$values = array_map(function ($value) use ($link) {
global $method;
if ($value === null)
return null;
if (gettype($value) === "array"){
if ($method=="PUT" || $method=="POST"){
global $tmpname,$name;
$tmpname=$value['tmp_name'];
$name=uniqid().$value['name'];
$value=$name;
}
}
return mysqli_real_escape_string($link, (string) $value);
}, array_values($input));