move_uploaded_file()
does not work if I create a file using
tempnam
.
I am using Yii2's UploadedFile::getInstance()
method to create a file instance. Now, the difference here is the fact that I am populating $_FILES
like the following, before making the instance:
function addToFiles($key, $model, $url) {
$tempName = tempnam(ini_get('upload_tmp_dir'), 'php_files');
$originalName = basename(parse_url($url, PHP_URL_PATH));
$curl = new \common\components\Curl();
$imgRawData = $curl->get($url);
$fp = fopen($tempName, 'w');
fwrite($fp, $imgRawData);
fclose($fp);
$_FILES[$model] = array(
'name' => [$key => $originalName],
'type' => [$key => 'image/jpeg'],
'tmp_name' => [$key => $tempName],
'error' => [$key => 0],
'size' => [$key => strlen($imgRawData)],
);
}
Then, I create an instance like following:
$file = UploadedFile::getInstance($instance, $attr);
Dump of the $file
:
yii\web\UploadedFile#1
(
[name] => '20421_33_t.jpg'
[tempName] => 'D:\\xampp\\tmp\\php8005.tmp'
[type] => 'image/jpeg'
[size] => 2527
[error] => 0
)
Now, if I call:
$file->saveAs($folder . '/' . $filename);
It just returns false
, without any warning or exception.
Now, I did some digging around and found out that Yii uses move_uploaded_file()
(without any error suppression operator) in saveAs()
method. The following is the core saveAs()
method.
public function saveAs($file, $deleteTempFile = true)
{
if ($this->error == UPLOAD_ERR_OK) {
if ($deleteTempFile) {
return move_uploaded_file($this->tempName, $file);
} elseif (is_uploaded_file($this->tempName)) {
return copy($this->tempName, $file);
}
}
return false;
}
As per move_uploaded_file()
documentation a warning should have been issued when return is false, but I get nothing! Error reporting + Yii2's debugger is enabled in my setup and it should break out on slightest of the error!
Question is- Is this by design? Or is this a bug? Or perhaps I am doing something horribly wrong?
By the way, I am not really looking for an alternative solution because I have it already. I am curious to find out why this does not work, more than anything.
Things to note:
$folder
is writable.is_dir($folder) && is_writable($folder)
returns true.$file->tempName
exists and not readonly!readfile($file->tempName)
reads the file without a problem.I even tried
chmod($file->tempName , 0777);
but it doesn't work.The same method works perfectly if I do not use
addToFiles
method, and upload the same image file from the form. In such cases, the dump of the instance is exactly the same ( only the tempName is different obviously, e.g.D:\\xampp\\tmp\\phpDBCC.tmp
), but the file uploads.