Before everything , I know that my question is already posted thousand times but none of them concern me since i cant identify my problem.
So ,I am building a PHP rest api to get a put request from the client (angular), this last can update a file inside the form as well as some text inputs , all of this is sent as a form-data in this code :
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) {});
On the server-side I have to get the response type and then parse the data here's the full code with help from here
$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);
}
and then I have to execute the query and move the file form the temp folder
$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
Can you explain to me please whats wrong ?
PS:
I checked the /tmp
folder the files I uploaded are still there.
The log is clean and I used this in the top of my code
ini_set('display_errors', true);
error_reporting(E_ALL);
Update :
I use this to get file params from the $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));