我想通过Kartik
小部件上传图片。提交表单后,$_FILE['Product']
包含有关图片的数据,但getInstance($model, 'images')
会返回null
。试过images[]
,也是null。
这就是我在控制器中尝试var_dump
的原因:
public function actionCreate()
{
$model = new Product();
if ($model->load(Yii::$app->request->post())) {
var_dump(UploadedFile::getInstance($model, 'images[]'));die;
这是我的模型Product
:
<?php
namespace app\models;
use backend\models\CActiveRecord;
use Yii;
use omgdef\multilingual\MultilingualQuery;
use omgdef\multilingual\MultilingualBehavior;
use yii\web\UploadedFile;
/**
* This is the model class for table "product".
*
* @property int $id
* @property int $category_id
* @property int $quantity
* @property double $price
* @property int $sort
*
* @property Productlang[] $productlangs
*/
class Product extends CActiveRecord
{
public $images;
public static function find()
{
return new MultilingualQuery(get_called_class());
}
public function behaviors()
{
$allLanguages = [];
foreach (Yii::$app->params['languages'] as $title => $language) {
$allLanguages[$title] = $language;
}
return [
'ml' => [
'class' => MultilingualBehavior::className(),
'languages' => $allLanguages,
//'languageField' => 'language',
//'localizedPrefix' => '',
//'requireTranslations' => false',
//'dynamicLangClass' => true',
//'langClassName' => PostLang::className(), // or namespace/for/a/class/PostLang
'defaultLanguage' => Yii::$app->params['languageDefault'],
'langForeignKey' => 'product_id',
'tableName' => "{{%productLang}}",
'attributes' => [
'title',
'description',
'meta_title',
'meta_desc',
'url'
]
],
];
}
/**
* @inheritdoc
*/
public static function tableName()
{
return 'product';
}
/**
* @inheritdoc
*/
public function rules()
{
$string = $this->multilingualFields(['description', 'url']);
$string_59 = $this->multilingualFields(['meta_title']);
$string_255 = $this->multilingualFields(['meta_desc', 'title']);
$string[] = 'description';
$string[] = 'url';
$string_59[] = 'meta_title';
$string_255[] = 'meta_desc';
$string_255[] = 'title';
return [
[['quantity', 'price', 'title', 'meta_title', 'meta_desc'], 'required'],
[['category_id', 'quantity', 'sort'], 'integer'],
[$string, 'string'],
[$string_59, 'string', 'max' => 59],
[$string_255, 'string', 'max' => 255],
[['price'], 'number'],
['images', 'file']
];
}
/**
* @inheritdoc
*/
public function attributeLabels()
{
return [
'id' => 'ID',
'category_id' => 'Category ID',
'quantity' => 'Quantity',
'price' => 'Price',
'sort' => 'Sort',
];
}
public function upload()
{
if ($this->validate()) {
foreach ($this->image as $file) {
$file->saveAs(\Yii::getAlias("@images") . "/products/" . $this->id . "_" . $this->image->baseName . '.' . $this->image->extension);
}
return true;
} else {
return false;
}
}
}
尝试使用规则['images', 'safe']
也['images', 'file']
(认为第二个不正确,因为该属性是一个数组,对吧?)。表格为<?php $form = ActiveForm::begin(['options' => ['multipart/form-data']]); ?>
。
最后我的意见是:
<?= $form->field($model, 'images[]')->widget(FileInput::class, [
'showMessage' => true,
]) ?>
完全控制器操作:
public function actionCreate()
{
$model = new Product();
if ($model->load(Yii::$app->request->post())) {
foreach (Yii::$app->params['languages'] as $language){
if(Yii::$app->params['languageDefault'] != $language){
$title_lang = "title_$language";
$model->$title_lang = Yii::$app->request->post('Product')["title_$language"];
$description_lang = "description_$language";
$model->$description_lang = Yii::$app->request->post('Product')["description_$language"];
$meta_title_lang = "meta_title_$language";
$model->$meta_title_lang = Yii::$app->request->post('Product')["meta_title_$language"];
$meta_desc_lang = "meta_desc_$language";
$model->$meta_desc_lang = Yii::$app->request->post('Product')["meta_desc_$language"];
}
}
if($model->save()){
$model = $this->findModel($model->id, true);
//Make urls
foreach (Yii::$app->params['languages'] as $language) {
if (Yii::$app->params['languageDefault'] != $language) {
$url_lang = "url_$language";
$title_lang = "title_$language";
$model->$url_lang = $model->constructURL(
$model->$title_lang,
$model->id
);
}else{
$model->url = $model->constructURL(
$model->title,
$model->id
);
}
}
//Upload Images
$model->images = UploadedFile::getInstance($model, 'images');
if (!($model->upload())) {
Yii::$app->session->setFlash('error', Yii::t('app', 'Some problem with the image uploading occure!'));
return $this->redirect(['create']);
}
if($model->update() !== false){
return $this->redirect(['view', 'id' => $model->id]);
}else{
Yii::$app->session->setFlash('error', Yii::t('app', 'Something went wrong. Please, try again later!'));
return $this->redirect(['create']);
}
}
}
return $this->render('create', [
'model' => $model,
]);
}
答案 0 :(得分:0)
您尝试上传单个图片时应该从ActiveForm字段声明和模型规则中删除输入字段名称中的[]
。
Single File
<?= $form->field($model, 'images')->widget(FileInput::class, [
'showMessage' => true,
'pluginOptions' => [
'showCaption' => false ,
'showRemove' => false ,
'showUpload' => false ,
'showPreview' => false ,
'browseClass' => 'btn btn-success btn-block' ,
'browseIcon' => '<i class="glyphicon glyphicon-camera"></i> ' ,
'browseLabel' => 'Select Profile Image'
] ,
'options' => ['accept' => 'image/*' ] ,
]) ?>
并从以下一行
UploadedFile::getInstance($model, 'images');
Multiple Files
对于多个文件,您需要为该字段添加'options' => ['multiple' => true]
,并将属性名称更改为images[]
<?= $form->field($model, 'images[]')->widget(FileInput::class, [
'showMessage' => true,
'pluginOptions' => [
'showCaption' => false ,
'showRemove' => false ,
'showUpload' => false ,
'showPreview' => false ,
'browseClass' => 'btn btn-success btn-block' ,
'browseIcon' => '<i class="glyphicon glyphicon-camera"></i> ' ,
'browseLabel' => 'Select Profile Image'
] ,
'options' => ['accept' => 'image/*' ,'multiple'=>true] ,
]) ?>
并且为了接收上传的文件,您不应该将属性指定为数组只需将getInstance
更改为getInstances
,然后尝试打印,它会显示使用foreach()
的所有图片保存所有这些。
UploadedFile::getInstances($model, 'images');
我个人更喜欢使用单独的模型进行文件上传,而不是使用ActiveRecord模型。
注意:使用多个文件上传时,您还可以在模型规则中指定'maxFiles'=>1000
以限制要上传的文件数
修改强>
要对代码进行问题排查,您应该从控制器中注释掉actionCreate
并替换为我在下面添加的代码
public function actionCreate() {
$model = new Product();
if ( $model->load ( Yii::$app->request->post () ) ) {
foreach ( Yii::$app->params['languages'] as $language ) {
if ( Yii::$app->params['languageDefault'] != $language ) {
$title_lang = "title_$language";
$model->$title_lang = Yii::$app->request->post ( 'Product' )["title_$language"];
$description_lang = "description_$language";
$model->$description_lang = Yii::$app->request->post ( 'Product' )["description_$language"];
$meta_title_lang = "meta_title_$language";
$model->$meta_title_lang = Yii::$app->request->post ( 'Product' )["meta_title_$language"];
$meta_desc_lang = "meta_desc_$language";
$model->$meta_desc_lang = Yii::$app->request->post ( 'Product' )["meta_desc_$language"];
}
}
$transaction = Yii::$app->db->beginTransaction ();
try {
if ( !$model->save () ) {
throw new \Exception ( implode ( "<br />" , \yii\helpers\ArrayHelper::getColumn ( $model->errors , 0 , false ) ) );
}
//Make urls
foreach ( Yii::$app->params['languages'] as $language ) {
if ( Yii::$app->params['languageDefault'] != $language ) {
$url_lang = "url_$language";
$title_lang = "title_$language";
$model->$url_lang = $model->constructURL (
$model->$title_lang , $model->id
);
} else {
$model->url = $model->constructURL (
$model->title , $model->id
);
}
}
//save the new urls
if ( !$model->save () ) {
throw new \Exception ( implode ( "<br />" , \yii\helpers\ArrayHelper::getColumn ( $model->errors , 0 , false ) ) );
}
//Upload Images
$model->images = UploadedFile::getInstances ( $model , 'images' );
$model->upload ();
//commit the transatction to save the record in the table
$transaction->commit ();
Yii::$app->session->setFlash ( 'success' , 'The model saved successfully.' );
return $this->redirect ( [ 'view' , 'id' => $model->id ] );
} catch ( \Exception $ex ) {
$transaction->rollBack ();
Yii::$app->session->setFlash ( 'error' , Yii::t ( 'app' , $ex->getMessage () ) );
}
}
return $this->render ( 'create' , [
'model' => $model ,
] );
}
并注释掉模型的upload()
函数并添加以下函数
public function upload() {
$skipped = [];
foreach ( $this->images as $file ) {
if ( !$file->saveAs ( \Yii::getAlias ( "@images" ) . "/products/" . $this->id . "_" . $this->image->baseName . '.' . $this->image->extension ) ) {
$skipped[] = "File " . $file->baseName . " was not saved.";
}
}
if ( !empty ( $skipped ) ) {
Yii::$app->session->setFlash ( 'error' , implode ( "<br>" , $skipped ) );
}
}
对于ActiveForm,请确保您的输入符合以下
$form->field($model, 'images[]')->widget(FileInput::class, [
'showMessage' => true,
'pluginOptions' => [
'showCaption' => false ,
'showRemove' => false ,
'showUpload' => false ,
'showPreview' => false ,
'browseClass' => 'btn btn-success btn-block' ,
'browseIcon' => '<i class="glyphicon glyphicon-camera"></i> ' ,
'browseLabel' => 'Select Profile Image'
] ,
'options' => ['accept' => 'image/*','multiple'=>true ] ,
]) ;