Загрузка с использованием Yii::app()->request->SendFile возвращает поврежденный файл

Я пытался загрузить мой загруженный файл из определенного каталога, например так:

Yii::app()->request->SendFile($model->statement, 
                        file_get_contents($path.$model->statement)
                        ); 

Он распознает файл и загрузил его с правильным именем и форматом, но вместо файла размером 74 КБ я получаю только поврежденный файл размером 1 КБ. Пробовал другие документы, такие как.doc,.pdf, все так же.

Я не совсем уверен в том, что на самом деле делает file_get_contents, поскольку я взял это из примера, который нашел.

Файл для загрузки был ранее загружен с помощью

<div class="row">
    <?php echo $form->labelEx($model, 'statement'); ?>
    <?php echo $form->fileField($model, 'statement', array('size' => 36, 'maxlength' => 255)); ?>
    <?php echo $form->error($model, 'statement'); ?>
</div>

в _form.php и настроил actionCreate в контроллере:

public function actionCreate($id)
{
    $model=new Witness;
    $model->ip_id = $id;

    // Uncomment the following line if AJAX validation is needed
    // $this->performAjaxValidation($model);

    $path = Yii::app()->basePath . '/modules/iris/statements';
    if (!is_dir($path)) {
        mkdir($path);
    }   

    if(isset($_POST['Witness']))
    {
        $model->attributes=$_POST['Witness'];

        if (@!empty($_FILES['Witness']['name']['statement'])) {
            $model->statement = $_POST['Witness']['statement'];
            if ($model->validate(array('statement'))) {
                $model->statement = CUploadedFile::getInstance($model, 'statement');
            } else {
                $model->statement = '';
            }

            $model->statement->saveAs($path . '/' . time() . '_' . str_replace(' ', '_', strtolower($model->statement)));

            //$model->doc_type = $model->statement->getType();
            //$model->doc_size = $model->statement->getSize();
        }

        $model->statement = time() . '_' . str_replace(' ', '_', strtolower($model->statement));


        if($model->save())
            $this->redirect(array('ip/view','id'=>$model->ip_id));
    }

    $this->render('create',array(
        'model'=>$model,
    ));
}

Загруженные файлы могут быть открыты без проблем. Есть идеи, почему загрузка повреждена? Нужно ли указывать тип / размер файла перед загрузкой?

2 ответа

При использовании файла размером 1 Кбайт ваш сервер выдает ошибку php после установки заголовков.

Откройте загруженный файл в текстовом редакторе и проверьте его содержимое.

В Yii2 подпись sendFile()

public $this sendFile ( $filePath, $attachmentName = null, $options = [] )

Отправка файла:

Yii::$app->response->sendFile('test.zip');

Для тех, у кого есть полные файлы, но они остались поврежденными:

Вы должны проверить, печатают ли другие файлы php выходные данные, иногда пробелы после закрытия тегов PHP могут вызывать проблемы.

Отсюда

Если вы посмотрите на список аргументов sendFile, вы можете видеть, что третий параметр mimeType. Фактически, вы не представляете ответ HTTP-заголовков, поэтому я предлагаю вам попробовать явно указатьContent-Type заголовок ответа:

Yii::app()->request->sendFile(
   "Youfile.pdf",
   file_get_contents('path/to/file'), 
   'application/pdf'
);

Я нашел другое решение вместо использования функции SendFile. Поместите это в файл представления, чтобы сгенерировать ссылку для скачивания:

CHtml::link('Click to download file', array('ip/download&id='.$model->file_id));

где 'ip' - название модели. Это передаст file_id в функцию actionDownload, созданную в controller.php:

public function downloadFile($fullpath){
    if(!empty($fullpath)){
        header("Content-type:application/pdf"); //for pdf file
        //header('Content-Type:text/plain; charset=ISO-8859-15');
        //if you want to read text file using text/plain header
        header('Content-Disposition: attachment; filename="'.basename($fullpath).'"');
        header('Content-Length: ' . filesize($fullpath));
        readfile($fullpath);
        Yii::app()->end();
    }
}

public function actionDownload($id){
    $model=Ip::model()->findByPk($id);
    $path = Yii::app()->basePath . 'location of file to be downloaded'.$model->filename;
    $this->downloadFile($path);
}

Это должно загрузить файл полностью. Не беспокойтесь о типе контента, я перепробовал все распространенные типы файлов (.pdf, .doc, .ppt, .png, .jpg), все работает отлично.

Другие вопросы по тегам