2010-01-20 2 views
4

В настоящее время я использую symfony 1.4 и хочу разрешить пользователям загружать файлы Microsoft Word docx. Использование виджета sfWidgetFormInputFile и sfValidatorFile ниже пользователи могут выбирать и успешно загружать свои файлы docx с помощью простой веб-формы.Загруженные файлы docx превращаются в zip

$this->widgetSchema['file_name'] = new sfWidgetFormInputFile(array('label' => 'File')); 

$this->validatorSchema['file_name'] = new sfValidatorFile(array(
    'required' => true, 
    'path'  => sfConfig::get('sf_upload_dir').DIRECTORY_SEPARATOR.sfConfig::get('app_dir_file_sharing').DIRECTORY_SEPARATOR, 
    'mime_types' => array('application/msword', 
         'application/vnd.ms-word', 
         'application/msword', 
         'application/msword; charset=binary') 
), array(
    'invalid' => 'Invalid file.', 
    'required' => 'Select a file to upload.', 
    'mime_types' => 'The file must be a supported type.' 
)); 

Проблема заключается в том, что после того, как файл будет загружен, то расширение меняется на .zip и файл содержит файл дерево XML-файлов. Я понимаю, что это потому, что Office 2007 теперь использует Open xml-файлы. Есть ли способ предотвратить это, используя symfony или PHP?

+0

Это также относится и к XLSX файлы – markb

ответ

5

У Symfony 1.3+ есть опция mime_type_guessers для sfValidatorFile, которая позволяет вам определить свой собственный угадатель типа mime PHP, который можно вызывать или использовать построение в угадывании. Вызов любого из 3 встроенных гаджетов типа mime находит правильный тип файла для docx и поддерживает расширение файла docx.

Вот обновленный код с помощью guessFromFileinfo:

$this->validatorSchema['file_name'] = new sfValidatorFile(array(
'required' => true, 
'path'  => sfConfig::get('sf_upload_dir').DIRECTORY_SEPARATOR.sfConfig::get('app_dir_file_sharing').DIRECTORY_SEPARATOR, 
'mime_type_guessers' => array('guessFromFileinfo'), 
'mime_types' => array('application/msword', 
        'application/vnd.ms-word', 
        'application/msword', 
        'application/msword; charset=binary') 
), array(
    'invalid' => 'Invalid file.', 
    'required' => 'Select a file to upload.', 
    'mime_types' => 'The file must be a supported type.' 
)); 
4

Это, по-видимому, bug в обнаружении типа файла Symfony. Описывается обходной путь.

5

Проблема заключается в том, что контент-обнюхивание. Новые форматы Office ARE .zip-файлы, и если при загрузке контент обнюхивается, браузер идентифицирует это как ZIP-файл и устанавливает заголовок Content-Type как таковой. Аналогично, при загрузке, если ваш сервер не устанавливает правильный заголовок ответа HTTP Content-Type, браузер предположит, что это ZIP-файл.

+0

Да, новые форматы Office 2007 - это файлы XML, которые были заархивированы. – TravisO

1

Предлагаемое использование mime_type_guessers использует несуществующее функцию. Если вы хотите использовать метод sfValidatorFile, напишите array(array('sfValidatorFile', 'guessFromFileinfo')). Предлагаемое решение вообще не использует обнаружение типа mime и приводит к проблемам с классическим форматом excel в моей системе.

Я исправил проблему, расширив класс sfValidatorFile и изменив метод getMimeType.

Создать новый файл msValidatorFile.class.php в вашей папке Lib:

<?php 

class msValidatorFile extends sfValidatorFile 
{ 
    protected function getMimeType($file, $fallback) 
    { 
    $arrayZips = array("application/zip", 
         "application/x-zip", 
         "application/x-zip-compressed"); 
    $officeTypes = array(
     "application/vnd.ms-word.document.macroEnabled.12", 
     "application/vnd.openxmlformats-officedocument.wordprocessingml.document", 
     "application/vnd.openxmlformats-officedocument.wordprocessingml.template", 
     "application/vnd.ms-powerpoint.template.macroEnabled.12", 
     "application/vnd.openxmlformats-officedocument.presentationml.template", 
     "application/vnd.ms-powerpoint.addin.macroEnabled.12", 
     "application/vnd.ms-powerpoint.slideshow.macroEnabled.12", 
     "application/vnd.openxmlformats-officedocument.presentationml.slideshow", 
     "application/vnd.ms-powerpoint.presentation.macroEnabled.12", 
     "application/vnd.openxmlformats-officedocument.presentationml.presentation", 
     "application/vnd.ms-excel.addin.macroEnabled.12", 
     "application/vnd.ms-excel.sheet.binary.macroEnabled.12", 
     "application/vnd.ms-excel.sheet.macroEnabled.12", 
     "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", 
     "application/vnd.ms-excel.template.macroEnabled.12", 
     "application/vnd.openxmlformats-officedocument.spreadsheetml.template"); 

    foreach ($this->getOption('mime_type_guessers') as $method) 
    { 
     $type = call_user_func($method, $file); 

     if (null !== $type && $type !== false) 
     { 
     if (in_array($type, $arrayZips) && in_array($fallback, $officeTypes)) 
     { 
      return $fallback; 
     } 
     return strtolower($type); 
     } 
    } 

    return strtolower($fallback); 
    } 
} 

Используйте этот новый валидатор в вашем коде формы:

$this->validatorSchema['file'] = 
    new msValidatorFile(array('required' => false, 
           'path' => sfConfig::get('sf_upload_dir') 
         )); 
Смежные вопросы