Блог

Yii отдача файла через sendFile

Снова и снова натыкаюсь на одни и те же грабли при работе с Yii, опишу ка все это в виде вот таких вот мини-заметок может отложится в памяти получше.

Сегодня минут 30 искал ошибку в отдаче файлов через Yii::app()->request->sendFile().

Казалось бы, что может быть тут сложного? Вызвал данный метод как:


Yii::app()->request->sendFile(basename($file),file_get_contents($file));

И радуйся!

Но не все так просто. Все скачанные файлы оказывались «поврежденными» и после скачки не открывались соответствующим софтом в ОС. Ларчик открывался просто.

Решение номер 1: из конфигурации приложения убрать всё логироваие, которое пишется прямо на отдаваемую страницу (CFileLogRoute конечно же можно оставить). Убрать стоит CProfileLogRoute, CWebLogRoute, YiiDebugToolbarRoute, DbProfileLogRoute и другие логеры.

Решение номер 2: подсмотрено у ребят из monoray.ru/86-yii/76-yii-tips-chapter-14

В базовый контроллер (он ведь у вас есть да ?) добавляем вот такой код:

public function disableProfilers()
    {
        if (Yii::app()->getComponent('log')) {
            foreach (Yii::app()->getComponent('log')->routes as $route) {
                if (in_array(get_class($route), array('CProfileLogRoute', 'CWebLogRoute', 'YiiDebugToolbarRoute','DbProfileLogRoute'))) {
                    $route->enabled = false;
                }
            }
        }
    }

Данный метод просто отключает все перечисленные в пункте 1 логеры.

Использовать следует примерно вот так:

public function actionDownloadFile()
{
        //отключить профайлеры
        $this->disableProfilers();        
        $file = '/path/to/file/some_file.txt';
        // отдаем файл
        Yii::app()->request->sendFile(basename($file),file_get_contents($file));
}

На сегодня все! Удачной скачки!