上传后移动临时文件无法正常工作

时间:2017-08-18 14:58:23

标签: php angularjs

在所有事情发生之前,我知道我的问题已经发布了数千次,但由于我无法确定我的问题,因此没有人关注我。

所以,我正在构建一个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));

0 个答案:

没有答案