yii2规则不适用于非db属性?

时间:2016-01-25 18:49:35

标签: forms validation yii2 rules modelattribute

我想一次上传多个文件。我有

模特:

class KakiKingModel extends ActiveRecord {

    public $uploadedFiles;

    public function rules() {
        return [
            [['uploadedFiles'], 'file', 'extensions' => 'txt', 'checkExtensionByMimeType' => false, 'skipOnEmpty' => true, 'maxFiles' => 2]];
    }
    ...

控制器:

use yii\web\UploadedFile;
...
public function actionUpload() {
    $model = new KakiKingModel;
    $t = new KakiKingModel;

    if (Yii::$app->request->isPost) {
        $files = UploadedFile::getInstances($model, 'uploadedFiles');

        $t = [];
        $i = 0;
        foreach ($files as $i => $file) {
            $t[$i] = new KakiKingModel;
            $t[$i]->contentUploadedFile = file($file->tempName);
            $t[$i]->assign(); // assign file content to model attributes
            $i++;
        }

        if (Model::validateMultiple($t)) {
            foreach ($t as $item) {
                $item->save(false);
            }
            return $this->redirect(['index']);
        } else {
            return $this->render('upload', [
                        'model' => $model,
                        't' => $t,
            ]);
        }
    }

    return $this->render('upload', [
                'model' => $model,
                't' => $t,
    ]);
}

视图:

$form = ActiveForm::begin([
    ....
    'options' => ['enctype' => 'multipart/form-data'],
    ...
        <?= $form->field($model, 'uploadedFiles[]')->fileInput(['multiple' => true]) ?>

问题是,它也接受任何其他类型的文件!这是为什么?我究竟做错了什么?谢谢! 更新:我已经改变了我的内容,以便您可以更好地理解为什么我发现它令人不安它不起作用。它应该工作恕我直言。你能帮我么?谢谢!

2 个答案:

答案 0 :(得分:4)

Yii2验证规则也适用于非数据库模型属性。

我认为这个问题有两个常见原因:

1)确保添加正确的enctype以便将文件发送到服务器:

use yii\widgets\ActiveForm;

...

<?php $form = ActiveForm::begin(['options' => ['enctype' => 'multipart/form-data']]); ?>

2) yii\validators\FileValidatoraliasedfile)仅适用于yii\web\UploadedFile类实例(它是PHP原生超全局的抽象{{3数组),确保在验证之前为属性分配正确的值。

单个文件使用$_FILES

use yii\web\UploadedFile;

...

$this->file = UploadedFile::getInstance($this, 'file');

对于多个文件,请使用\yii\web\UploadedFile::getInstance()

use yii\web\UploadedFile;

...

$this->files = UploadedFile::getInstances($this, 'files');

这可以在调用$model->save()$model->validate()之前或beforeValidate()事件处理程序内部之前完成:

/**
 * @inheritdoc
 */
public function beforeValidate()
{
    $this->files = UploadedFile::getInstances($this, 'files');

    return parent::beforeValidate();
}

答案 1 :(得分:1)

在您的模型中尝试这种方式:

ReadWriteLock

观点:

public class ConnectionPool {
    private HikariDataSource hds;
    private ReentrantReadWriteLock dsLock = ....;
    //....

    public void reloadFile() {
        dsLock.writeLock().lock();
        try {
            if (hds != null) {
                hds.close();
            }

            hds = new HikariDataSource(new HikariConfig(propertyFileName));
        } finally {
            dsLock.writeLock().unlock();
        }
    }

    public void executeQuery(final String sql, final CallBack<ResultSet, SQLException> callBack) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                Connection connection = null;
                PreparedStatement preparedStatement = null;
                ResultSet resultSet = null;

                dsLock.readLock().lock();
                try {
                    connection = hds.getConnection();
                    // ....
                } catch (SQLException e) {
                    callBack.call(null, e);
                } finally {
                    // your other cleanups
                    dsLock.readLock().unlock();
                }
            }
        }).start();
    }
    //....
}