YII上传文件

处理文件上传是一个相当常见的任务对于一个web应用程序,Yii有一些有用的类内置。让我们创建一个简单的形式允许上传ZIP并存储在 protected/uploads。
我们将从模块开始,创建protected/models/Upload.php如下:

<?php
class Upload extends CFormModel
{
    public $file;
 
    public function rules()
    {
        return array(
            array('file', 'file', 'types'=>'zip'),
        );
    }
}

现在我们将开始说明控制器,创建 protected/controllers/UploadController.php

<?php
class UploadController extends Controller
{
    function actionIndex()
    {
           $dir = Yii::getPathOfAlias('application.uploads') . '/' . date('Y') . '/' . date('m');
        if (!is_dir($dir))
            mkdir($dir, 0777);
        $uploaded = false;
        $model = new Upload();
        if (isset($_POST['Upload'])) {
            $model->attributes = $_POST['Upload'];
            $file = CUploadedFile::getInstance($model, 'file');
            $newName = substr(md5($file->extensionName . round((microtime(true) * 1000))), 0, 17) . '.' . $file->extensionName;
            $file_name = $dir . '/' . $newName;
            if ($model->validate()) {
                $attach = new Attache();
                $uploaded = $file->saveAs($file_name, TRUE);
                $attach->name = 'test';
                $attach->path = $file_name;
                $attach->create_time = time();
                $attach->save();
            }
        }
 
        $this->render('index', array(
            'model' => $model,
            'uploaded' => $uploaded,
            'dir' => $dir,
        ));
    }
}

最后,视图 protected/views/upload/index.php:

<?php if($uploaded):?>
<p>File was uploaded. Check <?php echo $dir?>.</p>
<?php endif ?>
<?php echo CHtml::beginForm('','post',array
        ('enctype'=>'multipart/form-data'))?>
    <?php echo CHtml::error($model, 'file')?>
    <?php echo CHtml::activeFileField($model, 'file')?>
    <?php echo CHtml::submitButton('Upload')?>
<?php echo CHtml::endForm()?>

它是如何工作的…
我们使用的模型非常简单。我们只定义一个字段$file和一个验证规则使用文件验证器写着”只允许zip文件”。

控制器有点复杂。我们逐行回顾它:

$dir = Yii::getPathOfAlias('application.uploads');
$uploaded = false;
$model=new Upload();
if(isset($_POST['Upload']))
{
    $model->attributes=$_POST['Upload'];

$dir是一个目录实现ZIP的上传。我们将它设置为protected/uploads。$uploaded是一个标志决定是否我们需要显示成功信息。我们创建一个model的实例并且如果提交了表单$_POST的数据填补它。

$file=CUploadedFile::getInstance($model,'file');
if($model->validate()){
    $file->saveAs($dir.'/'.$file->getName());
    $uploaded = true;

然后,我们使用CUploadedFile::getInstance能让我们访问CUploadedFile实例。这是一封装类,当文件上传后,围绕php的$_FILE数组进行填充。

如果我们确定文件是一个ZIP文档通过调用模型的验证方法,然后我们用CUploadedFile::saveAs保存文件。

The rest is passing some values to the view:

<?php if($uploaded):?>
<p>File was uploaded. Check <?php echo $dir?>.</p>
<?php endif ?>

如果$uploaded标志设置为真,则显示信息。

为了上传文件,HTML一定要遵守以下两种重要的要求:

应该使用post方法
enctype属性应该设置为’multipart/form-data’。
我们使用CHtlm或是 CActiveForm的htmlOptions生成HTML,CHtml使用如下:

<?php echo CHtml::beginForm('','post',array('enctype'=>'multipart/form-data'))?>

The rest is the standard form: We display an error and a field for model’s file attribute and render a submit button.
如果上传很多个文件,你应该用下面的方法修改代码:

if(isset($_POST['Upload']))
{
    $model->attributes=$_POST['Upload'];
    $files=CUploadedFile::getInstance($model,'file');
    if($model->validate())
    {
        foreach($files as $file)
            $file->saveAs($dir.'/'.$file->getName());

视图文件,你应该用下面的方式输出文件字段:

<?php echo CHtml::activeFileField($model, "[0]file")?>
<?php echo CHtml::activeFileField($model, "[1]file")?>
<?php echo CHtml::activeFileField($model, "[2]file")?>

文件验证
文件验证器中使用一个模型不仅让我们可以限制某些类型文件,但也设置其他限制,例如文件大小或是文件数量。例如,下面的规则只允许上传图片,文件大小小于一兆字节:

array('file', 'file', 'types'=>'jpg, gif, png', 'maxSize' => 1048576),

发表评论

电子邮件地址不会被公开。 必填项已用*标注