可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
Following Yii Framework 2.0 documentation http://www.yiiframework.com/doc-2.0/guide-input-file-upload.html I tried to upload image. The image could be uploaded successfully, but after uploading the image, I tried to insert the model into the database with the following code.
$model->file->saveAs('uploads/' . $model->file->baseName . '.' . $model->file->extension);
$model->save();
I got the following error:
PHP Warning – yii\base\ErrorException
finfo_file(/tmp/phpIGuwiT): failed to open stream: No such file or directory
1. in /var/www/html/website/advanced/vendor/yiisoft/yii2/helpers/BaseFileHelper.php
if ($info) {
$result = finfo_file($info, $file);
finfo_close($info);
if ($result !== false) {
return $result;
}
}
2. in /var/www/html/my-project/advanced/vendor/yiisoft/yii2/validators/FileValidator.php – yii\helpers\BaseFileHelper::getMimeType()
$mimeType = FileHelper::getMimeType($file->tempName, null, false);
3.
4.
and so on ....
The result is that image has been uploaded but the model has not been inserted into the database. Does anyone know how to solve this?
回答1:
I was having the exact same problem, and I solved it by calling
$model->save();
before
$model->file->saveAs()
I don't know how your model looks like, but if you are just saving the actual file on the server, and only the path to the image in the DB, it should work.
I think what happens is that when you call file->saveAs() before model->save, the model validation fails because 'file' no longer contains the uploaded data (it is already saved as...). Hope it makes sense.
回答2:
$model->file->saveAs();
//try delete imageFile file variable before save model
$model->imageFile = null;
$model->save();
回答3:
I was having same same problem, I solve with this.
$model->file->saveAs($filepath , false)
then
$model->save(false)
Important : in saveAs
function pass False
parameter.
回答4:
This issue can be caused by two issues, not just what is stated in other answers:
- PHP file size limits - you need to make sure your PHP settings allow you to upload files that are big enough. By default, PHP only allows 2mb files, so if you try to upload more, you may encounter this error and have no idea why.
You can change it by editing your php.ini file settings:
memory_limit = 32M
upload_max_filesize = 24M
post_max_size = 32M
Make sure post_max_size
is bigger than or equal to upload_max_file_size
and memory_limit
is bigger than or equal to post_max_size
.
- Model validation fails - the model no longer contains the uploaded temp post data. Therefore, you need to validate the model before saving it (note this won't consistently happen across environments / server set ups so best to be safe).
Here is a practical and real life example of how you would use it in your controller:
$model->upload_file = UploadedFile::getInstance($model, 'upload_file');
if ($model->validate()) {
if ($model->upload_file->saveAs('my/path/filename.txt')) {
$model->upload_file = null;
$model->save(false);
return ['status' => 'success']; // return your custom success
} else return ['status'=>'error']; // return your validation errors
}
} else return ['status'=>'error']; // return your validation errors
回答5:
You need to call $model->save() first then $model->file->saveAs(). Below is the code for reference.
if($model->file) {
$imagename = 'Profile_'.$model->created_at.rand(100000, 999999);
$model->profilepic = $imagename.'.'.$model->file->extension;
$path = 'uploads/';
}
if($model->save()) {
$model->file ? $model->file->saveAs($path.$imagename.'.'.$model->file->extension): null;
//the render or redirect code goes here on success
} else {
//if the validation fails then it will be executed
}
回答6:
Do as follows
$model->file->saveAs('uploads/' . $model->file->baseName . '.' . $model->file->extension);
// rewrite the file attribute to saved url of the file.
$model->file = 'uploads/' . $model->file->baseName . '.' . $model->file->extension;
$model->save();
Hope this helps!
回答7:
My solution looks like this:
$model = new Film();
$uploads = Yii::getAlias('@uploads'); // Alias root_dir/uploads
if ($model->load(Yii::$app->request->post())) {
$file = UploadedFile::getInstance($model, 'poster');
$imageName = rand(9999, 999999);
$file->name = $imageName . '.' . $file->extension; // override the file name
$model->poster = $file;
if($model->validate() && $model->save()) {
$file->saveAs($uploads . '/posters/' . $model->poster);
return $this->redirect(['view', 'id' => $model->film_id]);
}
}
return $this->render('create', [
'model' => $model
]);
回答8:
Replace
$model->save()
by
$model->save(false)
This is because when you perform $model->save() with no argument, it will by default consider true
ie the input must be validated
(reference).
And all inputs must be validated before uploading or saving in database ie above
$model->file->saveAs('uploads/' . $model->file->baseName . '.' .
$model->file->extension);
line and
$model->save()
line
So finally my suggestion is
In your XyzController.php (in "create" (actionCreate possibly) scenario)
...
...
if($model->validate()) // in "create" (actionCreate possibly) scenario
{
$model->file->saveAs('uploads/' . $model->file->baseName . '.' . $model->file->extension);
$model->save(false);
}
else
{
$msg = 'Error in saving data! Invalid data';
return $this->render('back', ['err_msg'=>$msg]);
}
...
...
This would work fine in create scenario,
but what about "update" (actionUpdate possibly) scenario?
In that case I have tested Aleksandr Ivin's (above) answer and it's working fine.
Here is the description
If image uploading is not mandatory than
...
...
if($model->image_file = UploadedFile::getInstance($model, 'image_file'))
{
// do all uploading stuffs here like below line
$model->file->saveAs('uploads/' . $model->file->baseName . '.' . $model->file->extension);
}
$model->image_file = null;
if($model->save(true))
{
$msg = 'Success!'; // set this as flash message if you need
return $this->redirect(['index']);
}
...
...
回答9:
try $model->file->saveAs($filepath, false)
instead of $model->file->saveAs($filepath)
or set $model->file = null
before calling $model->file->saveAs()
will solve the problem
回答10:
when we save to image field in db, just use
$model->file->name;
when you try to print $model->file you will get an array
print_r($model->file); die();